@conterra/vuln-scan 1.0.13 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -425,17 +425,77 @@ These can also be set in a `.env` file in the working directory.
425
425
  | `addToBoard[].matchProjects` | no | Glob patterns to activate this entry. Defaults to `["*"]`. |
426
426
  | `autoCloseBelowSeverity` | no | Default auto-close threshold inherited by every `issues[]` entry that does not override it. One of `UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`. |
427
427
  | `issues[].autoCloseBelowSeverity` | no | Per-rule override of the top-level threshold. |
428
+ | `issues[].projectOverrides` | no | Per-project overrides of this rule's `autoCloseBelowSeverity`. See below. |
428
429
 
429
430
  `addToBoard` resolution: only entries whose `matchProjects` cover the vulnerability's affected scan projects are considered. The **first** matching scrum entry (with `sprintBoardId`) claims the sprint; further scrum entries are ignored. Kanban entries (no `sprintBoardId`) all contribute their labels.
430
431
 
431
432
  #### Auto-close low-severity issues
432
433
 
433
- When `autoCloseBelowSeverity` (top-level or per-issue rule) is set, newly-created issues whose vulnerability severity is **strictly below** the threshold are immediately transitioned to a status whose Jira status category is `done` (the first such transition exposed by the workflow is used, regardless of the status's display name and locale). The board/sprint assignment, labels and comment described above still happen *before* the transition, so the issue is reachable on the configured board even though it starts out closed. A short German-language comment is added explaining the auto-closure.
434
+ When `autoCloseBelowSeverity` (top-level or per-issue rule) is set, newly-created issues whose vulnerability severity is **strictly below** the threshold are immediately transitioned to a status whose Jira status category is `done` (the first such transition exposed by the workflow is used, regardless of the status's display name and locale). The board/sprint assignment, labels and comment described above still happen *before* the transition, so the issue is reachable on the configured board even though it starts out closed. A short German-language comment is added explaining the auto-closure (see below).
434
435
 
435
436
  For *existing* issues, the threshold only suppresses re-opening: when a closed sub-threshold issue gains a newly-affected project, the project label and "Zusätzlich gemeldet für" comment are added as usual, but the issue is **not** re-opened (and never re-closed). Issues at or above the threshold keep the existing re-open + re-add-to-active-sprint behavior.
436
437
 
437
438
  Threshold semantics mirror `ct-vuln-auto-vex`: with `"HIGH"`, severities `MEDIUM`, `LOW` and `UNKNOWN` are auto-closed, while `HIGH` and `CRITICAL` stay open.
438
439
 
440
+ ##### Auto-acknowledgement comments
441
+
442
+ The Jira reporter posts one of three German comment shapes depending on the per-project resolver outcome (see `projectOverrides` below for the bucket definitions):
443
+
444
+ - **Auto-close comment** — posted after a successful close transition. Lists every project that was auto-acknowledged together with its effective threshold:
445
+
446
+ ```
447
+ Automatisch geschlossen: Schwere MEDIUM liegt unterhalb der konfigurierten Auto-Close-Schwelle.
448
+ Auto-akzeptiert für:
449
+ - mapapps@4.20.0 (Schwelle HIGH)
450
+ - other-tool@1.0.0 (Schwelle CRITICAL)
451
+ ```
452
+
453
+ - **Partial-ack comment** (`Teilweise auto-akzeptiert`) — posted on a newly-created issue that stays open because the issue's matching projects split across both buckets. Names which projects are implicitly auto-acknowledged and which still require manual evaluation:
454
+
455
+ ```
456
+ Teilweise auto-akzeptiert. Schwere HIGH.
457
+ Auto-akzeptiert für:
458
+ - other-tool@1.0.0 (Schwelle CRITICAL)
459
+ Manuelle Bewertung erforderlich für:
460
+ - mapapps@4.20.0 (Schwelle HIGH)
461
+ ```
462
+
463
+ The comment is suppressed when all matching projects fall in a single bucket (the auto-close path covers all-auto-acknowledged; the all-manual case posts nothing).
464
+
465
+ - **Reopen-reason append** — when a closed sub-threshold issue is re-opened because newly-affected projects raise the bar, the consolidated reopen-reason comment is extended with the same `Auto-akzeptiert für` / `Manuelle Bewertung erforderlich für` sections (scoped to the newly added projects). The reporter does not post a second comment for the bucket split.
466
+
467
+ Projects that have no effective threshold configured (no `projectOverrides` match, no rule-level / top-level `autoCloseBelowSeverity`) are omitted from these listings — they neither block nor enable the auto-close decision in any new way.
468
+
469
+ ##### `issues[].projectOverrides` — per-project stricter thresholds
470
+
471
+ `projectOverrides` mirrors the [`projectOverrides`](#projectoverrides--per-project-stricter-thresholds) block of `auto-vex-conf.json`, so the same LTSS / regular-release-line policy can be expressed in both tools. Each entry binds one severity threshold to a list of glob patterns matched against the `name@version` project identifier (same shape used in `vuln-scan-conf.json#projects[]` and in Jira `reportProjects`). Only `*` wildcards are supported.
472
+
473
+ For every vulnerability covered by a rule:
474
+
475
+ 1. Each `matchingProject` (an affected project that matches the rule's `reportProjects`) resolves to an effective threshold — the strictest (lowest) matching `projectOverrides` entry, falling back to `issues[].autoCloseBelowSeverity` and finally the top-level `autoCloseBelowSeverity`.
476
+ 2. The issue's threshold is the **strictest across all matchingProjects**. A new issue is therefore only auto-closed when the vulnerability is strictly below the threshold for *every* matching project; any project that still requires deeper analysis keeps the issue open.
477
+ 3. Existing closed sub-threshold issues are never re-opened by `projectOverrides` — but raising the bar (e.g. via an LTSS override) above the live severity *does* re-open them, just as if `autoCloseBelowSeverity` itself had been raised.
478
+
479
+ Example mirroring the matching `auto-vex-conf.json`:
480
+
481
+ ```jsonc
482
+ {
483
+ "jiraProject": "PLATFORM",
484
+ "issueType": "CVE",
485
+ "reportProjects": ["*"],
486
+ "autoCloseBelowSeverity": "CRITICAL",
487
+ "projectOverrides": [
488
+ {
489
+ "projects": ["mapapps@4.20.*", "mapapps-sdi@5.8.*"],
490
+ "autoCloseBelowSeverity": "HIGH",
491
+ "comment": "LTSS means to analyze 'HIGH and CRITICAL'"
492
+ }
493
+ ]
494
+ }
495
+ ```
496
+
497
+ With this rule, a `MEDIUM` CVE that affects only `mapapps@4.20.0` is auto-closed (below `HIGH`); the same CVE bleeding into a non-LTSS project keeps the issue open if its effective threshold treats `MEDIUM` as actionable.
498
+
439
499
  ### CLI
440
500
 
441
501
  ```
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var A=Object.create;var x=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var T=Object.getPrototypeOf,L=Object.prototype.hasOwnProperty;var U=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of D(t))!L.call(e,i)&&i!==r&&x(e,i,{get:()=>t[i],enumerable:!(n=F(t,i))||n.enumerable});return e};var P=(e,t,r)=>(r=e!=null?A(T(e)):{},U(t||!e||!e.__esModule?x(r,"default",{value:e,enumerable:!0}):r,e));var u=P(require("path")),v=require("fs/promises");var a=require("fs/promises");async function m(e){try{return await R(e)?JSON.parse(await(0,a.readFile)(e,{encoding:"utf-8"})):void 0}catch(t){throw new Error(`Error reading JSON file ${e}: ${t}`,{cause:t})}}async function E(e,t){let r=JSON.stringify(t,null,4)+`
3
- `,n=await $(e,r);await(0,a.writeFile)(e,n,{encoding:"utf-8"})}async function R(e){try{return await(0,a.access)(e,a.constants.F_OK),!0}catch{return!1}}async function $(e,t){let r=await B();if(!r)return t;let n=await r.resolveConfig(e);return n?await r.format(t,{...n,filepath:e}):t}var M;function B(){return M??=import("prettier").catch(()=>{})}var c=["UNKNOWN","LOW","MEDIUM","HIGH","CRITICAL"];var S=class e{constructor(t){this.workingDir=t}workingDir;static DEFAULT_MAVEN_REPO="https://repository.conterra.de/repository/maven-mirror-ct";static DEFAULT_VEX_SUBDIR="input/vex";static DEFAULT_OUT_SUBDIR="output";static DEFAULT_CACHE_SUBDIR="cache";static DEFAULT_SCANNERS=["grype","trivy","ossindex"];normalize(t,r){let n=t.findNoLongerDetectedVulnerabilitiesOnlyForSnapshots??!1;return{projectConfigFileLocation:r,onNewVulnerabilities:t.onNewVulnerabilities??(t.failOnNewVulnerabilities?"fail":"warn"),onNoLongerDetectedVulnerabilities:t.onNoLongerDetectedVulnerabilities??"ignore",reportNoLongerDetectedVulnerabilities:t.reportNoLongerDetectedVulnerabilities??!0,consoleReport:t.consoleReport??"BY_PROJECT_DETAILED",createSubDirsForProject:t.createSubDirsForProject??!0,mavenRepo:t.mavenRepo??e.DEFAULT_MAVEN_REPO,vexUrls:t.vexUrls??[],vexDir:this.resolvePath(t.vexDir)??(0,u.resolve)(this.workingDir,e.DEFAULT_VEX_SUBDIR),outDir:this.resolvePath(t.outDir)??(0,u.resolve)(this.workingDir,e.DEFAULT_OUT_SUBDIR),cacheDir:this.resolvePath(t.cacheDir)??(0,u.resolve)(this.workingDir,e.DEFAULT_CACHE_SUBDIR),scanners:this.normalizeScanners(t.scanners,r),projects:this.normalizeProjects(t.projects??[],n)}}normalizeScanners(t,r){return(t??e.DEFAULT_SCANNERS).map(i=>{if(typeof i!="string")throw new Error(`Invalid scanner name '${String(i)}' in configuration file '${r}'`);let o=i.split("@");if(o.length>2)throw new Error(`Invalid scanner name '${i}' in configuration file '${r}'`);return{name:o[0],version:o[1]??""}})}normalizeProjects(t,r){return t.map(n=>{let i=n;if(!i.name)throw new Error("Project name is missing on entry: "+JSON.stringify(i));if(!i.version)throw new Error("Project version is missing on entry: "+JSON.stringify(i));if(!i.purl)throw new Error("Project purl is missing on entry: "+JSON.stringify(i));let o={...i,purlAliases:i.purlAliases??[],enabled:i.enabled??!0,silent:i.silent??!1,minimumSeverity:i.minimumSeverity??"UNKNOWN"};return o.sbomFile?{...o,sbomFile:this.resolvePath(o.sbomFile)??o.sbomFile}:{...o,detectNoLongerUsedVulnerabilities:r?o.purl.endsWith("-SNAPSHOT"):!0}})}resolvePath(t){if(t)return u.default.isAbsolute(t)?t:(0,u.resolve)(this.workingDir,t)}},l=class{constructor(t){this.workingDir=t;this.normalizer=new S(t)}workingDir;normalizer;projectConfigCache;async loadProjectConfig(){return this.projectConfigCache??=this.doLoadProjectConfig(),this.projectConfigCache}async doLoadProjectConfig(){let t=(0,u.resolve)(this.workingDir,"vuln-scan-conf.json"),r=await m(t);if(!r)throw new Error(`Missing project configuration file '${t}'`);return this.normalizer.normalize(r,t)}async loadJiraConfig(t){let r=await(0,v.readFile)(t,"utf8"),n=JSON.parse(r);if(!n.issues&&n.issue&&(n.issues=n.issue),!n.jiraUrl||typeof n.jiraUrl!="string")throw new Error("jira-conf.json: missing or invalid 'jiraUrl' field");if(!Array.isArray(n.issues))throw new Error("jira-conf.json: missing or invalid 'issues' array");this.validateAutoCloseSeverity(n.autoCloseBelowSeverity,"jira-conf.json: invalid 'autoCloseBelowSeverity'");for(let[i,o]of n.issues.entries())o&&typeof o=="object"&&this.validateAutoCloseSeverity(o.autoCloseBelowSeverity,`jira-conf.json: invalid 'issues[${i}].autoCloseBelowSeverity'`);return n}validateAutoCloseSeverity(t,r){if(t!==void 0&&!c.includes(t))throw new Error(`${r} value '${String(t)}'. Must be one of: ${c.join(", ")}`)}async loadAutoVexConfig(t){let r=await(0,v.readFile)(t,"utf8"),n=JSON.parse(r);if(!n.impactStatement||typeof n.impactStatement!="string")throw new Error("auto-vex-conf.json: missing or invalid 'impactStatement' field (must be a non-empty string)");if(n.maxSeverity!==void 0&&!c.includes(n.maxSeverity))throw new Error(`auto-vex-conf.json: invalid 'maxSeverity' value '${String(n.maxSeverity)}'. Must be one of: ${c.join(", ")}`);if(n.projectOverrides!==void 0){if(!Array.isArray(n.projectOverrides))throw new Error("auto-vex-conf.json: 'projectOverrides' must be an array");for(let[i,o]of n.projectOverrides.entries()){if(!o||typeof o!="object")throw new Error(`auto-vex-conf.json: 'projectOverrides[${i}]' must be an object`);let s=o;if(!Array.isArray(s.projects)||s.projects.length===0||!s.projects.every(d=>typeof d=="string"&&d.length>0))throw new Error(`auto-vex-conf.json: 'projectOverrides[${i}].projects' must be a non-empty array of non-empty strings`);if(!c.includes(s.maxSeverity))throw new Error(`auto-vex-conf.json: invalid 'projectOverrides[${i}].maxSeverity' value '${String(s.maxSeverity)}'. Must be one of: ${c.join(", ")}`)}}return n}};var N=require("fs/promises"),y=require("path");var V=require("crypto");var b="auto_vex_max_severity=";function f(e){let t=e.status_notes;if(!t||!t.startsWith(b))return;let r=t.slice(b.length).trim();return c.includes(r)?r:void 0}var k="https://openvex.dev/ns/v0.2.0";function C(e,t="conterra"){let n=`https://openvex.dev/docs/public/vex-${(0,V.randomUUID)()}`,i=e.timestamp??new Date().toISOString();return{"@context":k,"@id":n,author:t,timestamp:i,last_updated:i,version:1,statements:[e]}}function O(e,t){let r=t.timestamp??new Date().toISOString();return{...e,last_updated:r,version:e.version+1,statements:[...e.statements,t]}}var g=require("fs/promises"),h=require("path");var p=class{constructor(t){this.location=t}location;_content=void 0;_exists=!1;get exists(){return this._exists}get content(){return this._content}set content(t){this._content=t,this._exists=t!==void 0}async read(){let t=await m(this.location);this._content=t??void 0,this._exists=this._content!==void 0}async write(){if(this._content===void 0)throw new Error(`Cannot write VexFile: content is undefined (${this.location})`);await(0,g.mkdir)((0,h.dirname)((0,h.resolve)(this.location)),{recursive:!0}),await E(this.location,this._content)}async delete(){await(0,g.unlink)(this.location),this._exists=!1}upsert(t,r){if(this._content===void 0)return this._content=C(t,r),this._exists=!0,{created:!0,changed:!0};let n=f(t);if(n!==void 0){let i=this._content.statements.findIndex(o=>o.vulnerability.name===t.vulnerability.name&&o.status===t.status&&f(o)===n);if(i!==-1){let o=this._content.statements[i];return X(o,t)?{created:!1,changed:!1}:(o.products=t.products,o.impact_statement=t.impact_statement,o.action_statement=t.action_statement,o.justification=t.justification,o.status_notes=t.status_notes,o.timestamp=t.timestamp,this._content.version+=1,this._content.last_updated=t.timestamp??new Date().toISOString(),{created:!1,changed:!0})}}return this._content=O(this._content,t),{created:!1,changed:!0}}addProductId(t,r){this.assertContentLoaded("addProductId");let n=!1;for(let i of this._content.statements){if(!i.products||i.products.some(s=>s["@id"]===r))continue;let o=i.products.findIndex(s=>s["@id"]===t);o!==-1&&(i.products.splice(o+1,0,{"@id":r}),n=!0)}return n}removeProductId(t,r){this.assertContentLoaded("removeProductId");let n=this._content.statements,i=[],o=!1;for(let s of n){if(r&&!j(s).has(r)||!s.products)continue;let d=s.products.findIndex(I=>I["@id"]===t);d!==-1&&(s.products.splice(d,1),o=!0,s.products.length===0&&i.push(s))}if(!o)return"unchanged";for(let s of i)n.splice(n.indexOf(s),1);return n.length===0?"emptied":"changed"}hasStatementForProduct(t){return this.assertContentLoaded("hasStatementForProduct"),this._content.statements.some(r=>r.products?.some(n=>n["@id"]===t)??!1)}assertContentLoaded(t){if(this._content===void 0)throw new Error(`VexFile.${t}(): content is not loaded. Call read() first (${this.location})`)}};function X(e,t){return e.impact_statement!==t.impact_statement||e.action_statement!==t.action_statement||e.justification!==t.justification||e.status_notes!==t.status_notes?!1:W(e.products,t.products)}function W(e,t){let r=o=>Array.from(new Set((o??[]).map(s=>s["@id"]).filter(s=>typeof s=="string"))).sort(),n=r(e),i=r(t);return n.length!==i.length?!1:n.every((o,s)=>o===i[s])}async function w(e,t){for(let r of await(0,N.readdir)(e,{withFileTypes:!0}))r.name.endsWith(".json")?await t(new p((0,y.resolve)(r.parentPath,r.name))):r.isDirectory()&&await w((0,y.resolve)(r.parentPath,r.name),t)}function j(e){let t=e.vulnerability.name;return new Set([t,...e.vulnerability.aliases??[]])}async function _({workingDir:e,existingPurl:t,newPurl:r}){let n=await new l(e).loadProjectConfig();await w(n.vexDir,async i=>{await i.read(),i.addProductId(t,r)&&(console.info(`Add ${r} to ${i.location}`),await i.write())})}var H=process.cwd();(async()=>{let{existingPurl:e,newPurl:t}=await J();await _({workingDir:H,existingPurl:e,newPurl:t})})();async function J(){let e=process.argv[2];if(!e)throw new Error("Existing purl parameter missing.");let t=process.argv[3];if(!t)throw new Error("New purl parameter missing.");return{existingPurl:e,newPurl:t}}
2
+ "use strict";var F=Object.create;var E=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var $=Object.getPrototypeOf,L=Object.prototype.hasOwnProperty;var U=(r,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of T(t))!L.call(r,i)&&i!==e&&E(r,i,{get:()=>t[i],enumerable:!(n=D(t,i))||n.enumerable});return r};var b=(r,t,e)=>(e=r!=null?F($(r)):{},U(t||!r||!r.__esModule?E(e,"default",{value:r,enumerable:!0}):e,r));var d=b(require("path")),S=require("fs/promises");var a=require("fs/promises");async function l(r){try{return await R(r)?JSON.parse(await(0,a.readFile)(r,{encoding:"utf-8"})):void 0}catch(t){throw new Error(`Error reading JSON file ${r}: ${t}`,{cause:t})}}async function j(r,t){let e=JSON.stringify(t,null,4)+`
3
+ `,n=await M(r,e);await(0,a.writeFile)(r,n,{encoding:"utf-8"})}async function R(r){try{return await(0,a.access)(r,a.constants.F_OK),!0}catch{return!1}}async function M(r,t){let e=await k();if(!e)return t;let n=await e.resolveConfig(r);return n?await e.format(t,{...n,filepath:r}):t}var B;function k(){return B??=import("prettier").catch(()=>{})}var u=["UNKNOWN","LOW","MEDIUM","HIGH","CRITICAL"];var y=class r{constructor(t){this.workingDir=t}workingDir;static DEFAULT_MAVEN_REPO="https://repository.conterra.de/repository/maven-mirror-ct";static DEFAULT_VEX_SUBDIR="input/vex";static DEFAULT_OUT_SUBDIR="output";static DEFAULT_CACHE_SUBDIR="cache";static DEFAULT_SCANNERS=["grype","trivy","ossindex"];normalize(t,e){let n=t.findNoLongerDetectedVulnerabilitiesOnlyForSnapshots??!1;return{projectConfigFileLocation:e,onNewVulnerabilities:t.onNewVulnerabilities??(t.failOnNewVulnerabilities?"fail":"warn"),onNoLongerDetectedVulnerabilities:t.onNoLongerDetectedVulnerabilities??"ignore",reportNoLongerDetectedVulnerabilities:t.reportNoLongerDetectedVulnerabilities??!0,consoleReport:t.consoleReport??"BY_PROJECT_DETAILED",createSubDirsForProject:t.createSubDirsForProject??!0,mavenRepo:t.mavenRepo??r.DEFAULT_MAVEN_REPO,vexUrls:t.vexUrls??[],vexDir:this.resolvePath(t.vexDir)??(0,d.resolve)(this.workingDir,r.DEFAULT_VEX_SUBDIR),outDir:this.resolvePath(t.outDir)??(0,d.resolve)(this.workingDir,r.DEFAULT_OUT_SUBDIR),cacheDir:this.resolvePath(t.cacheDir)??(0,d.resolve)(this.workingDir,r.DEFAULT_CACHE_SUBDIR),scanners:this.normalizeScanners(t.scanners,e),projects:this.normalizeProjects(t.projects??[],n)}}normalizeScanners(t,e){return(t??r.DEFAULT_SCANNERS).map(i=>{if(typeof i!="string")throw new Error(`Invalid scanner name '${String(i)}' in configuration file '${e}'`);let o=i.split("@");if(o.length>2)throw new Error(`Invalid scanner name '${i}' in configuration file '${e}'`);return{name:o[0],version:o[1]??""}})}normalizeProjects(t,e){return t.map(n=>{let i=n;if(!i.name)throw new Error("Project name is missing on entry: "+JSON.stringify(i));if(!i.version)throw new Error("Project version is missing on entry: "+JSON.stringify(i));if(!i.purl)throw new Error("Project purl is missing on entry: "+JSON.stringify(i));let o={...i,purlAliases:i.purlAliases??[],enabled:i.enabled??!0,silent:i.silent??!1,minimumSeverity:i.minimumSeverity??"UNKNOWN"};return o.sbomFile?{...o,sbomFile:this.resolvePath(o.sbomFile)??o.sbomFile}:{...o,detectNoLongerUsedVulnerabilities:e?o.purl.endsWith("-SNAPSHOT"):!0}})}resolvePath(t){if(t)return d.default.isAbsolute(t)?t:(0,d.resolve)(this.workingDir,t)}},f=class{constructor(t){this.workingDir=t;this.normalizer=new y(t)}workingDir;normalizer;projectConfigCache;async loadProjectConfig(){return this.projectConfigCache??=this.doLoadProjectConfig(),this.projectConfigCache}async doLoadProjectConfig(){let t=(0,d.resolve)(this.workingDir,"vuln-scan-conf.json"),e=await l(t);if(!e)throw new Error(`Missing project configuration file '${t}'`);return this.normalizer.normalize(e,t)}async loadJiraConfig(t){let e=await(0,S.readFile)(t,"utf8"),n=JSON.parse(e);if(!n.issues&&n.issue&&(n.issues=n.issue),!n.jiraUrl||typeof n.jiraUrl!="string")throw new Error("jira-conf.json: missing or invalid 'jiraUrl' field");if(!Array.isArray(n.issues))throw new Error("jira-conf.json: missing or invalid 'issues' array");this.validateAutoCloseSeverity(n.autoCloseBelowSeverity,"jira-conf.json: invalid 'autoCloseBelowSeverity'");for(let[i,o]of n.issues.entries())if(o&&typeof o=="object"){let s=o;this.validateAutoCloseSeverity(s.autoCloseBelowSeverity,`jira-conf.json: invalid 'issues[${i}].autoCloseBelowSeverity'`),this.validateAutoCloseProjectOverrides(s.projectOverrides,`jira-conf.json: invalid 'issues[${i}].projectOverrides'`)}return n}validateAutoCloseSeverity(t,e){if(t!==void 0&&!u.includes(t))throw new Error(`${e} value '${String(t)}'. Must be one of: ${u.join(", ")}`)}validateAutoCloseProjectOverrides(t,e){if(t!==void 0){if(!Array.isArray(t))throw new Error(`${e}: must be an array`);for(let n=0;n<t.length;n++){let i=t[n],o=`${e}[${n}]`;if(i==null||typeof i!="object")throw new Error(`${o}: must be an object`);let s=i,c=s.projects;if(!Array.isArray(c)||c.length===0)throw new Error(`${o}.projects: must be a non-empty array of strings`);for(let m=0;m<c.length;m++){let P=c[m];if(typeof P!="string"||P.length===0)throw new Error(`${o}.projects[${m}]: must be a non-empty string`)}if(s.autoCloseBelowSeverity===void 0)throw new Error(`${o}.autoCloseBelowSeverity: is required`);if(this.validateAutoCloseSeverity(s.autoCloseBelowSeverity,`${o}.autoCloseBelowSeverity`),s.comment!==void 0&&typeof s.comment!="string")throw new Error(`${o}.comment: must be a string`)}}}async loadAutoVexConfig(t){let e=await(0,S.readFile)(t,"utf8"),n=JSON.parse(e);if(!n.impactStatement||typeof n.impactStatement!="string")throw new Error("auto-vex-conf.json: missing or invalid 'impactStatement' field (must be a non-empty string)");if(n.maxSeverity!==void 0&&!u.includes(n.maxSeverity))throw new Error(`auto-vex-conf.json: invalid 'maxSeverity' value '${String(n.maxSeverity)}'. Must be one of: ${u.join(", ")}`);if(n.projectOverrides!==void 0){if(!Array.isArray(n.projectOverrides))throw new Error("auto-vex-conf.json: 'projectOverrides' must be an array");for(let[i,o]of n.projectOverrides.entries()){if(!o||typeof o!="object")throw new Error(`auto-vex-conf.json: 'projectOverrides[${i}]' must be an object`);let s=o;if(!Array.isArray(s.projects)||s.projects.length===0||!s.projects.every(c=>typeof c=="string"&&c.length>0))throw new Error(`auto-vex-conf.json: 'projectOverrides[${i}].projects' must be a non-empty array of non-empty strings`);if(!u.includes(s.maxSeverity))throw new Error(`auto-vex-conf.json: invalid 'projectOverrides[${i}].maxSeverity' value '${String(s.maxSeverity)}'. Must be one of: ${u.join(", ")}`)}}return n}};var _=require("fs/promises"),w=require("path");var C=require("crypto");var V="auto_vex_max_severity=";function p(r){let t=r.status_notes;if(!t||!t.startsWith(V))return;let e=t.slice(V.length).trim();return u.includes(e)?e:void 0}var X="https://openvex.dev/ns/v0.2.0";function O(r,t="conterra"){let n=`https://openvex.dev/docs/public/vex-${(0,C.randomUUID)()}`,i=r.timestamp??new Date().toISOString();return{"@context":X,"@id":n,author:t,timestamp:i,last_updated:i,version:1,statements:[r]}}function A(r,t){let e=t.timestamp??new Date().toISOString();return{...r,last_updated:e,version:r.version+1,statements:[...r.statements,t]}}var h=require("fs/promises"),v=require("path");var g=class{constructor(t){this.location=t}location;_content=void 0;_exists=!1;get exists(){return this._exists}get content(){return this._content}set content(t){this._content=t,this._exists=t!==void 0}async read(){let t=await l(this.location);this._content=t??void 0,this._exists=this._content!==void 0}async write(){if(this._content===void 0)throw new Error(`Cannot write VexFile: content is undefined (${this.location})`);await(0,h.mkdir)((0,v.dirname)((0,v.resolve)(this.location)),{recursive:!0}),await j(this.location,this._content)}async delete(){await(0,h.unlink)(this.location),this._exists=!1}upsert(t,e){if(this._content===void 0)return this._content=O(t,e),this._exists=!0,{created:!0,changed:!0};let n=p(t);if(n!==void 0){let i=this._content.statements.findIndex(o=>o.vulnerability.name===t.vulnerability.name&&o.status===t.status&&p(o)===n);if(i!==-1){let o=this._content.statements[i];return W(o,t)?{created:!1,changed:!1}:(o.products=t.products,o.impact_statement=t.impact_statement,o.action_statement=t.action_statement,o.justification=t.justification,o.status_notes=t.status_notes,o.timestamp=t.timestamp,this._content.version+=1,this._content.last_updated=t.timestamp??new Date().toISOString(),{created:!1,changed:!0})}}return this._content=A(this._content,t),{created:!1,changed:!0}}addProductId(t,e){this.assertContentLoaded("addProductId");let n=!1;for(let i of this._content.statements){if(!i.products||i.products.some(s=>s["@id"]===e))continue;let o=i.products.findIndex(s=>s["@id"]===t);o!==-1&&(i.products.splice(o+1,0,{"@id":e}),n=!0)}return n}removeProductId(t,e){this.assertContentLoaded("removeProductId");let n=this._content.statements,i=[],o=!1;for(let s of n){if(e&&!N(s).has(e)||!s.products)continue;let c=s.products.findIndex(m=>m["@id"]===t);c!==-1&&(s.products.splice(c,1),o=!0,s.products.length===0&&i.push(s))}if(!o)return"unchanged";for(let s of i)n.splice(n.indexOf(s),1);return n.length===0?"emptied":"changed"}hasStatementForProduct(t){return this.assertContentLoaded("hasStatementForProduct"),this._content.statements.some(e=>e.products?.some(n=>n["@id"]===t)??!1)}assertContentLoaded(t){if(this._content===void 0)throw new Error(`VexFile.${t}(): content is not loaded. Call read() first (${this.location})`)}};function W(r,t){return r.impact_statement!==t.impact_statement||r.action_statement!==t.action_statement||r.justification!==t.justification||r.status_notes!==t.status_notes?!1:H(r.products,t.products)}function H(r,t){let e=o=>Array.from(new Set((o??[]).map(s=>s["@id"]).filter(s=>typeof s=="string"))).sort(),n=e(r),i=e(t);return n.length!==i.length?!1:n.every((o,s)=>o===i[s])}async function x(r,t){for(let e of await(0,_.readdir)(r,{withFileTypes:!0}))e.name.endsWith(".json")?await t(new g((0,w.resolve)(e.parentPath,e.name))):e.isDirectory()&&await x((0,w.resolve)(e.parentPath,e.name),t)}function N(r){let t=r.vulnerability.name;return new Set([t,...r.vulnerability.aliases??[]])}async function I({workingDir:r,existingPurl:t,newPurl:e}){let n=await new f(r).loadProjectConfig();await x(n.vexDir,async i=>{await i.read(),i.addProductId(t,e)&&(console.info(`Add ${e} to ${i.location}`),await i.write())})}var J=process.cwd();(async()=>{let{existingPurl:r,newPurl:t}=await z();await I({workingDir:J,existingPurl:r,newPurl:t})})();async function z(){let r=process.argv[2];if(!r)throw new Error("Existing purl parameter missing.");let t=process.argv[3];if(!t)throw new Error("New purl parameter missing.");return{existingPurl:r,newPurl:t}}
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var tr=Object.create;var Ze=Object.defineProperty;var rr=Object.getOwnPropertyDescriptor;var nr=Object.getOwnPropertyNames;var ir=Object.getPrototypeOf,or=Object.prototype.hasOwnProperty;var et=(t,e)=>()=>{try{return e||t((e={exports:{}}).exports,e),e.exports}catch(r){throw e=0,r}};var sr=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of nr(e))!or.call(t,i)&&i!==r&&Ze(t,i,{get:()=>e[i],enumerable:!(n=rr(e,i))||n.enumerable});return t};var M=(t,e,r)=>(r=t!=null?tr(ir(t)):{},sr(e||!t||!t.__esModule?Ze(r,"default",{value:t,enumerable:!0}):r,t));var yt=et((ni,xt)=>{"use strict";xt.exports=Ir;function Rr(t){let e={defaultWidth:0,output:process.stdout,tty:require("tty")};return t?(Object.keys(e).forEach(function(r){t[r]||(t[r]=e[r])}),t):e}function Ir(t){let e=Rr(t);if(e.output.getWindowSize)return e.output.getWindowSize()[0]||e.defaultWidth;if(e.tty.getWindowSize)return e.tty.getWindowSize()[1]||e.defaultWidth;if(e.output.columns)return e.output.columns;if(process.env.CLI_WIDTH){let r=parseInt(process.env.CLI_WIDTH,10);if(!isNaN(r)&&r!==0)return r}return e.defaultWidth}});var Ot=et((wi,Nt)=>{var Wr=require("stream"),Oe=class extends Wr{#r=null;constructor(e={}){super(e),this.writable=this.readable=!0,this.muted=!1,this.on("pipe",this._onpipe),this.replace=e.replace,this._prompt=e.prompt||null,this._hadControl=!1}#t(e,r){return this._dest?this._dest[e]:this._src?this._src[e]:r}#e(e,...r){typeof this._dest?.[e]=="function"&&this._dest[e](...r),typeof this._src?.[e]=="function"&&this._src[e](...r)}get isTTY(){return this.#r!==null?this.#r:this.#t("isTTY",!1)}set isTTY(e){this.#r=e}get rows(){return this.#t("rows")}get columns(){return this.#t("columns")}mute(){this.muted=!0}unmute(){this.muted=!1}_onpipe(e){this._src=e}pipe(e,r){return this._dest=e,super.pipe(e,r)}pause(){if(this._src)return this._src.pause()}resume(){if(this._src)return this._src.resume()}write(e){if(this.muted){if(!this.replace)return!0;if(e.match(/^\u001b/))return e.indexOf(this._prompt)===0&&(e=e.slice(this._prompt.length),e=e.replace(/./g,this.replace),e=this._prompt+e),this._hadControl=!0,this.emit("data",e);this._prompt&&this._hadControl&&e.indexOf(this._prompt)===0&&(this._hadControl=!1,this.emit("data",this._prompt),e=e.slice(this._prompt.length)),e=e.toString().replace(/./g,this.replace)}this.emit("data",e)}end(e){this.muted&&(e&&this.replace?e=e.toString().replace(/./g,this.replace):e=null),e&&this.emit("data",e),this.emit("end")}destroy(...e){return this.#e("destroy",...e)}destroySoon(...e){return this.#e("destroySoon",...e)}close(...e){return this.#e("close",...e)}};Nt.exports=Oe});var V=M(require("path")),Re=require("fs/promises");var T=require("fs/promises");async function z(t){try{return await ar(t)?JSON.parse(await(0,T.readFile)(t,{encoding:"utf-8"})):void 0}catch(e){throw new Error(`Error reading JSON file ${t}: ${e}`,{cause:e})}}async function re(t,e){let r=JSON.stringify(e,null,4)+`
3
- `,n=await lr(t,r);await(0,T.writeFile)(t,n,{encoding:"utf-8"})}async function ar(t){try{return await(0,T.access)(t,T.constants.F_OK),!0}catch{return!1}}async function lr(t,e){let r=await ur();if(!r)return e;let n=await r.resolveConfig(t);return n?await r.format(e,{...n,filepath:t}):e}var cr;function ur(){return cr??=import("prettier").catch(()=>{})}var U=["UNKNOWN","LOW","MEDIUM","HIGH","CRITICAL"];var Ie=class t{constructor(e){this.workingDir=e}workingDir;static DEFAULT_MAVEN_REPO="https://repository.conterra.de/repository/maven-mirror-ct";static DEFAULT_VEX_SUBDIR="input/vex";static DEFAULT_OUT_SUBDIR="output";static DEFAULT_CACHE_SUBDIR="cache";static DEFAULT_SCANNERS=["grype","trivy","ossindex"];normalize(e,r){let n=e.findNoLongerDetectedVulnerabilitiesOnlyForSnapshots??!1;return{projectConfigFileLocation:r,onNewVulnerabilities:e.onNewVulnerabilities??(e.failOnNewVulnerabilities?"fail":"warn"),onNoLongerDetectedVulnerabilities:e.onNoLongerDetectedVulnerabilities??"ignore",reportNoLongerDetectedVulnerabilities:e.reportNoLongerDetectedVulnerabilities??!0,consoleReport:e.consoleReport??"BY_PROJECT_DETAILED",createSubDirsForProject:e.createSubDirsForProject??!0,mavenRepo:e.mavenRepo??t.DEFAULT_MAVEN_REPO,vexUrls:e.vexUrls??[],vexDir:this.resolvePath(e.vexDir)??(0,V.resolve)(this.workingDir,t.DEFAULT_VEX_SUBDIR),outDir:this.resolvePath(e.outDir)??(0,V.resolve)(this.workingDir,t.DEFAULT_OUT_SUBDIR),cacheDir:this.resolvePath(e.cacheDir)??(0,V.resolve)(this.workingDir,t.DEFAULT_CACHE_SUBDIR),scanners:this.normalizeScanners(e.scanners,r),projects:this.normalizeProjects(e.projects??[],n)}}normalizeScanners(e,r){return(e??t.DEFAULT_SCANNERS).map(i=>{if(typeof i!="string")throw new Error(`Invalid scanner name '${String(i)}' in configuration file '${r}'`);let o=i.split("@");if(o.length>2)throw new Error(`Invalid scanner name '${i}' in configuration file '${r}'`);return{name:o[0],version:o[1]??""}})}normalizeProjects(e,r){return e.map(n=>{let i=n;if(!i.name)throw new Error("Project name is missing on entry: "+JSON.stringify(i));if(!i.version)throw new Error("Project version is missing on entry: "+JSON.stringify(i));if(!i.purl)throw new Error("Project purl is missing on entry: "+JSON.stringify(i));let o={...i,purlAliases:i.purlAliases??[],enabled:i.enabled??!0,silent:i.silent??!1,minimumSeverity:i.minimumSeverity??"UNKNOWN"};return o.sbomFile?{...o,sbomFile:this.resolvePath(o.sbomFile)??o.sbomFile}:{...o,detectNoLongerUsedVulnerabilities:r?o.purl.endsWith("-SNAPSHOT"):!0}})}resolvePath(e){if(e)return V.default.isAbsolute(e)?e:(0,V.resolve)(this.workingDir,e)}},k=class{constructor(e){this.workingDir=e;this.normalizer=new Ie(e)}workingDir;normalizer;projectConfigCache;async loadProjectConfig(){return this.projectConfigCache??=this.doLoadProjectConfig(),this.projectConfigCache}async doLoadProjectConfig(){let e=(0,V.resolve)(this.workingDir,"vuln-scan-conf.json"),r=await z(e);if(!r)throw new Error(`Missing project configuration file '${e}'`);return this.normalizer.normalize(r,e)}async loadJiraConfig(e){let r=await(0,Re.readFile)(e,"utf8"),n=JSON.parse(r);if(!n.issues&&n.issue&&(n.issues=n.issue),!n.jiraUrl||typeof n.jiraUrl!="string")throw new Error("jira-conf.json: missing or invalid 'jiraUrl' field");if(!Array.isArray(n.issues))throw new Error("jira-conf.json: missing or invalid 'issues' array");this.validateAutoCloseSeverity(n.autoCloseBelowSeverity,"jira-conf.json: invalid 'autoCloseBelowSeverity'");for(let[i,o]of n.issues.entries())o&&typeof o=="object"&&this.validateAutoCloseSeverity(o.autoCloseBelowSeverity,`jira-conf.json: invalid 'issues[${i}].autoCloseBelowSeverity'`);return n}validateAutoCloseSeverity(e,r){if(e!==void 0&&!U.includes(e))throw new Error(`${r} value '${String(e)}'. Must be one of: ${U.join(", ")}`)}async loadAutoVexConfig(e){let r=await(0,Re.readFile)(e,"utf8"),n=JSON.parse(r);if(!n.impactStatement||typeof n.impactStatement!="string")throw new Error("auto-vex-conf.json: missing or invalid 'impactStatement' field (must be a non-empty string)");if(n.maxSeverity!==void 0&&!U.includes(n.maxSeverity))throw new Error(`auto-vex-conf.json: invalid 'maxSeverity' value '${String(n.maxSeverity)}'. Must be one of: ${U.join(", ")}`);if(n.projectOverrides!==void 0){if(!Array.isArray(n.projectOverrides))throw new Error("auto-vex-conf.json: 'projectOverrides' must be an array");for(let[i,o]of n.projectOverrides.entries()){if(!o||typeof o!="object")throw new Error(`auto-vex-conf.json: 'projectOverrides[${i}]' must be an object`);let s=o;if(!Array.isArray(s.projects)||s.projects.length===0||!s.projects.every(a=>typeof a=="string"&&a.length>0))throw new Error(`auto-vex-conf.json: 'projectOverrides[${i}].projects' must be a non-empty array of non-empty strings`);if(!U.includes(s.maxSeverity))throw new Error(`auto-vex-conf.json: invalid 'projectOverrides[${i}].maxSeverity' value '${String(s.maxSeverity)}'. Must be one of: ${U.join(", ")}`)}}return n}};var ue=class{constructor(e){this.configFilePath=e}configFilePath;async readRawConfig(){let e=await z(this.configFilePath);if(!e)throw new Error(`Missing project configuration file '${this.configFilePath}'`);return e}async insertAfter(e,r){let n=await this.readRawConfig(),i=n.projects??[],o=i.findIndex(s=>s.name===e.name&&s.version===e.version);if(o===-1)throw new Error(`Reference project ${e.name}@${e.version} not found in config`);i.splice(o+1,0,r),n.projects=i,await re(this.configFilePath,n)}async remove(e,r){let n=await this.readRawConfig(),i=n.projects??[],o=i.findIndex(s=>s.name===e&&s.version===r);return o===-1?!1:(i.splice(o,1),n.projects=i,await re(this.configFilePath,n),!0)}};var st=require("fs/promises"),Fe=require("path");var rt=require("crypto");var tt="auto_vex_max_severity=";function fe(t){let e=t.status_notes;if(!e||!e.startsWith(tt))return;let r=e.slice(tt.length).trim();return U.includes(r)?r:void 0}var fr="https://openvex.dev/ns/v0.2.0";function nt(t,e="conterra"){let n=`https://openvex.dev/docs/public/vex-${(0,rt.randomUUID)()}`,i=t.timestamp??new Date().toISOString();return{"@context":fr,"@id":n,author:e,timestamp:i,last_updated:i,version:1,statements:[t]}}function it(t,e){let r=e.timestamp??new Date().toISOString();return{...t,last_updated:r,version:t.version+1,statements:[...t.statements,e]}}var pe=require("fs/promises"),me=require("path");var de=class{constructor(e){this.location=e}location;_content=void 0;_exists=!1;get exists(){return this._exists}get content(){return this._content}set content(e){this._content=e,this._exists=e!==void 0}async read(){let e=await z(this.location);this._content=e??void 0,this._exists=this._content!==void 0}async write(){if(this._content===void 0)throw new Error(`Cannot write VexFile: content is undefined (${this.location})`);await(0,pe.mkdir)((0,me.dirname)((0,me.resolve)(this.location)),{recursive:!0}),await re(this.location,this._content)}async delete(){await(0,pe.unlink)(this.location),this._exists=!1}upsert(e,r){if(this._content===void 0)return this._content=nt(e,r),this._exists=!0,{created:!0,changed:!0};let n=fe(e);if(n!==void 0){let i=this._content.statements.findIndex(o=>o.vulnerability.name===e.vulnerability.name&&o.status===e.status&&fe(o)===n);if(i!==-1){let o=this._content.statements[i];return dr(o,e)?{created:!1,changed:!1}:(o.products=e.products,o.impact_statement=e.impact_statement,o.action_statement=e.action_statement,o.justification=e.justification,o.status_notes=e.status_notes,o.timestamp=e.timestamp,this._content.version+=1,this._content.last_updated=e.timestamp??new Date().toISOString(),{created:!1,changed:!0})}}return this._content=it(this._content,e),{created:!1,changed:!0}}addProductId(e,r){this.assertContentLoaded("addProductId");let n=!1;for(let i of this._content.statements){if(!i.products||i.products.some(s=>s["@id"]===r))continue;let o=i.products.findIndex(s=>s["@id"]===e);o!==-1&&(i.products.splice(o+1,0,{"@id":r}),n=!0)}return n}removeProductId(e,r){this.assertContentLoaded("removeProductId");let n=this._content.statements,i=[],o=!1;for(let s of n){if(r&&!ot(s).has(r)||!s.products)continue;let a=s.products.findIndex(c=>c["@id"]===e);a!==-1&&(s.products.splice(a,1),o=!0,s.products.length===0&&i.push(s))}if(!o)return"unchanged";for(let s of i)n.splice(n.indexOf(s),1);return n.length===0?"emptied":"changed"}hasStatementForProduct(e){return this.assertContentLoaded("hasStatementForProduct"),this._content.statements.some(r=>r.products?.some(n=>n["@id"]===e)??!1)}assertContentLoaded(e){if(this._content===void 0)throw new Error(`VexFile.${e}(): content is not loaded. Call read() first (${this.location})`)}};function dr(t,e){return t.impact_statement!==e.impact_statement||t.action_statement!==e.action_statement||t.justification!==e.justification||t.status_notes!==e.status_notes?!1:pr(t.products,e.products)}function pr(t,e){let r=o=>Array.from(new Set((o??[]).map(s=>s["@id"]).filter(s=>typeof s=="string"))).sort(),n=r(t),i=r(e);return n.length!==i.length?!1:n.every((o,s)=>o===i[s])}async function je(t,e){for(let r of await(0,st.readdir)(t,{withFileTypes:!0}))r.name.endsWith(".json")?await e(new de((0,Fe.resolve)(r.parentPath,r.name))):r.isDirectory()&&await je((0,Fe.resolve)(r.parentPath,r.name),e)}function ot(t){let e=t.vulnerability.name;return new Set([e,...t.vulnerability.aliases??[]])}async function at({workingDir:t,existingPurl:e,newPurl:r}){let n=await new k(t).loadProjectConfig();await je(n.vexDir,async i=>{await i.read(),i.addProductId(e,r)&&(console.info(`Add ${r} to ${i.location}`),await i.write())})}async function lt({workingDir:t,projectName:e,referenceProjectVersion:r,targetProjectVersion:n}){let i=await new k(t).loadProjectConfig();if(!i.projectConfigFileLocation)throw new Error("Missing project configuration file.");let o=i.projects.find(a=>a.name===e&&a.version===r);if(!o)throw new Error(`Project ${e} with version ${r} not found.`);let s=i.projects.find(a=>a.name===e&&a.version===n);s||(s=await mr(e,i.projectConfigFileLocation,o,n)),await at({workingDir:t,existingPurl:o.purl,newPurl:s.purl})}async function mr(t,e,r,n){let i=new ue(e),s=(await i.readRawConfig()).projects.find(c=>c.name===r.name&&c.version===r.version),a={...s};return a.version=n,a.purl=s.purl.replace(s.version,n),"sbomMavenCoordinates"in a?a.sbomMavenCoordinates=s.sbomMavenCoordinates.replace(s.version,n):"sbomFile"in a&&(a.sbomFile=s.sbomFile.replace(s.version,n)),console.info(`Add project ${t} with version ${n} to ${e}`),await i.insertAfter(r,a),a}var hr=["emacs","vim"],gr=new Set(hr);function wr(t){return gr.has(t)}function ct(){let t=process.env.INQUIRER_KEYBINDINGS;return t?Array.from(new Set(t.toLowerCase().split(/[\s,]+/).filter(wr))):[]}var ne=(t,e=[])=>t.name==="up"||e.includes("vim")&&t.name==="k"||e.includes("emacs")&&t.ctrl&&t.name==="p",he=(t,e=[])=>t.name==="down"||e.includes("vim")&&t.name==="j"||e.includes("emacs")&&t.ctrl&&t.name==="n";var ie=t=>t.name==="backspace",oe=t=>t.name==="tab",Ce=t=>"1234567890".includes(t.name),$=t=>t.name==="enter"||t.name==="return";var ge=class extends Error{name="AbortPromptError";message="Prompt was aborted";constructor(e){super(),this.cause=e?.cause}},we=class extends Error{name="CancelPromptError";message="Prompt was canceled"},se=class extends Error{name="ExitPromptError"},Se=class extends Error{name="HookError"},Y=class extends Error{name="ValidationError"};var pt=require("node:async_hooks");var xe=require("node:async_hooks");var ut=new xe.AsyncLocalStorage;function Sr(t){return{rl:t,hooks:[],hooksCleanup:[],hooksEffect:[],index:0,handleChange(){}}}function ft(t,e){let r=Sr(t);return ut.run(r,()=>{function n(i){r.handleChange=()=>{r.index=0,i()},r.handleChange()}return e(n)})}function W(){let t=ut.getStore();if(!t)throw new Se("[Inquirer] Hook functions can only be called from within a prompt");return t}function Te(){return W().rl}function _e(t){let e=(...r)=>{let n=W(),i=!1,o=n.handleChange;n.handleChange=()=>{i=!0};let s=t(...r);return i&&o(),n.handleChange=o,s};return xe.AsyncResource.bind(e)}function Q(t){let e=W(),{index:r}=e,n={get(){return e.hooks[r]},set(o){e.hooks[r]=o},initialized:r in e.hooks},i=t(n);return e.index++,i}function dt(){W().handleChange()}var K={queue(t){let e=W(),{index:r}=e;e.hooksEffect.push(()=>{e.hooksCleanup[r]?.();let n=t(Te());if(n!=null&&typeof n!="function")throw new Y("useEffect return value must be a cleanup function or nothing.");e.hooksCleanup[r]=n})},run(){let t=W();_e(()=>{t.hooksEffect.forEach(e=>{e()}),t.hooksEffect.length=0})()},clearAll(){let t=W();t.hooksCleanup.forEach(e=>{e?.()}),t.hooksEffect.length=0,t.hooksCleanup.length=0}};function xr(t){return typeof t=="function"}function D(t){return Q(e=>{let r=pt.AsyncResource.bind(function(o){e.get()!==o&&(e.set(o),dt())});if(e.initialized)return[e.get(),r];let n=xr(t)?t():t;return e.set(n),[n,r]})}function A(t,e){Q(r=>{let n=r.get();(!Array.isArray(n)||e.some((o,s)=>!Object.is(o,n[s])))&&K.queue(t),r.set(e)})}var C=require("node:util");var j=M(require("node:process"),1);function yr(){return j.default.platform.startsWith("win")?!!j.default.env.CI||!!j.default.env.WT_SESSION||!!j.default.env.TERMINUS_SUBLIME||j.default.env.ConEmuTask==="{cmd::Cmder}"||j.default.env.TERM_PROGRAM==="Terminus-Sublime"||j.default.env.TERM_PROGRAM==="vscode"||j.default.env.TERM==="xterm-256color"||j.default.env.TERM==="alacritty"||j.default.env.TERMINAL_EMULATOR==="JetBrains-JediTerm":j.default.env.TERM!=="linux"}var mt={circleQuestionMark:"(?)",questionMarkPrefix:"(?)",square:"\u2588",squareDarkShade:"\u2593",squareMediumShade:"\u2592",squareLightShade:"\u2591",squareTop:"\u2580",squareBottom:"\u2584",squareLeft:"\u258C",squareRight:"\u2590",squareCenter:"\u25A0",bullet:"\u25CF",dot:"\u2024",ellipsis:"\u2026",pointerSmall:"\u203A",triangleUp:"\u25B2",triangleUpSmall:"\u25B4",triangleDown:"\u25BC",triangleDownSmall:"\u25BE",triangleLeftSmall:"\u25C2",triangleRightSmall:"\u25B8",home:"\u2302",heart:"\u2665",musicNote:"\u266A",musicNoteBeamed:"\u266B",arrowUp:"\u2191",arrowDown:"\u2193",arrowLeft:"\u2190",arrowRight:"\u2192",arrowLeftRight:"\u2194",arrowUpDown:"\u2195",almostEqual:"\u2248",notEqual:"\u2260",lessOrEqual:"\u2264",greaterOrEqual:"\u2265",identical:"\u2261",infinity:"\u221E",subscriptZero:"\u2080",subscriptOne:"\u2081",subscriptTwo:"\u2082",subscriptThree:"\u2083",subscriptFour:"\u2084",subscriptFive:"\u2085",subscriptSix:"\u2086",subscriptSeven:"\u2087",subscriptEight:"\u2088",subscriptNine:"\u2089",oneHalf:"\xBD",oneThird:"\u2153",oneQuarter:"\xBC",oneFifth:"\u2155",oneSixth:"\u2159",oneEighth:"\u215B",twoThirds:"\u2154",twoFifths:"\u2156",threeQuarters:"\xBE",threeFifths:"\u2157",threeEighths:"\u215C",fourFifths:"\u2158",fiveSixths:"\u215A",fiveEighths:"\u215D",sevenEighths:"\u215E",line:"\u2500",lineBold:"\u2501",lineDouble:"\u2550",lineDashed0:"\u2504",lineDashed1:"\u2505",lineDashed2:"\u2508",lineDashed3:"\u2509",lineDashed4:"\u254C",lineDashed5:"\u254D",lineDashed6:"\u2574",lineDashed7:"\u2576",lineDashed8:"\u2578",lineDashed9:"\u257A",lineDashed10:"\u257C",lineDashed11:"\u257E",lineDashed12:"\u2212",lineDashed13:"\u2013",lineDashed14:"\u2010",lineDashed15:"\u2043",lineVertical:"\u2502",lineVerticalBold:"\u2503",lineVerticalDouble:"\u2551",lineVerticalDashed0:"\u2506",lineVerticalDashed1:"\u2507",lineVerticalDashed2:"\u250A",lineVerticalDashed3:"\u250B",lineVerticalDashed4:"\u254E",lineVerticalDashed5:"\u254F",lineVerticalDashed6:"\u2575",lineVerticalDashed7:"\u2577",lineVerticalDashed8:"\u2579",lineVerticalDashed9:"\u257B",lineVerticalDashed10:"\u257D",lineVerticalDashed11:"\u257F",lineDownLeft:"\u2510",lineDownLeftArc:"\u256E",lineDownBoldLeftBold:"\u2513",lineDownBoldLeft:"\u2512",lineDownLeftBold:"\u2511",lineDownDoubleLeftDouble:"\u2557",lineDownDoubleLeft:"\u2556",lineDownLeftDouble:"\u2555",lineDownRight:"\u250C",lineDownRightArc:"\u256D",lineDownBoldRightBold:"\u250F",lineDownBoldRight:"\u250E",lineDownRightBold:"\u250D",lineDownDoubleRightDouble:"\u2554",lineDownDoubleRight:"\u2553",lineDownRightDouble:"\u2552",lineUpLeft:"\u2518",lineUpLeftArc:"\u256F",lineUpBoldLeftBold:"\u251B",lineUpBoldLeft:"\u251A",lineUpLeftBold:"\u2519",lineUpDoubleLeftDouble:"\u255D",lineUpDoubleLeft:"\u255C",lineUpLeftDouble:"\u255B",lineUpRight:"\u2514",lineUpRightArc:"\u2570",lineUpBoldRightBold:"\u2517",lineUpBoldRight:"\u2516",lineUpRightBold:"\u2515",lineUpDoubleRightDouble:"\u255A",lineUpDoubleRight:"\u2559",lineUpRightDouble:"\u2558",lineUpDownLeft:"\u2524",lineUpBoldDownBoldLeftBold:"\u252B",lineUpBoldDownBoldLeft:"\u2528",lineUpDownLeftBold:"\u2525",lineUpBoldDownLeftBold:"\u2529",lineUpDownBoldLeftBold:"\u252A",lineUpDownBoldLeft:"\u2527",lineUpBoldDownLeft:"\u2526",lineUpDoubleDownDoubleLeftDouble:"\u2563",lineUpDoubleDownDoubleLeft:"\u2562",lineUpDownLeftDouble:"\u2561",lineUpDownRight:"\u251C",lineUpBoldDownBoldRightBold:"\u2523",lineUpBoldDownBoldRight:"\u2520",lineUpDownRightBold:"\u251D",lineUpBoldDownRightBold:"\u2521",lineUpDownBoldRightBold:"\u2522",lineUpDownBoldRight:"\u251F",lineUpBoldDownRight:"\u251E",lineUpDoubleDownDoubleRightDouble:"\u2560",lineUpDoubleDownDoubleRight:"\u255F",lineUpDownRightDouble:"\u255E",lineDownLeftRight:"\u252C",lineDownBoldLeftBoldRightBold:"\u2533",lineDownLeftBoldRightBold:"\u252F",lineDownBoldLeftRight:"\u2530",lineDownBoldLeftBoldRight:"\u2531",lineDownBoldLeftRightBold:"\u2532",lineDownLeftRightBold:"\u252E",lineDownLeftBoldRight:"\u252D",lineDownDoubleLeftDoubleRightDouble:"\u2566",lineDownDoubleLeftRight:"\u2565",lineDownLeftDoubleRightDouble:"\u2564",lineUpLeftRight:"\u2534",lineUpBoldLeftBoldRightBold:"\u253B",lineUpLeftBoldRightBold:"\u2537",lineUpBoldLeftRight:"\u2538",lineUpBoldLeftBoldRight:"\u2539",lineUpBoldLeftRightBold:"\u253A",lineUpLeftRightBold:"\u2536",lineUpLeftBoldRight:"\u2535",lineUpDoubleLeftDoubleRightDouble:"\u2569",lineUpDoubleLeftRight:"\u2568",lineUpLeftDoubleRightDouble:"\u2567",lineUpDownLeftRight:"\u253C",lineUpBoldDownBoldLeftBoldRightBold:"\u254B",lineUpDownBoldLeftBoldRightBold:"\u2548",lineUpBoldDownLeftBoldRightBold:"\u2547",lineUpBoldDownBoldLeftRightBold:"\u254A",lineUpBoldDownBoldLeftBoldRight:"\u2549",lineUpBoldDownLeftRight:"\u2540",lineUpDownBoldLeftRight:"\u2541",lineUpDownLeftBoldRight:"\u253D",lineUpDownLeftRightBold:"\u253E",lineUpBoldDownBoldLeftRight:"\u2542",lineUpDownLeftBoldRightBold:"\u253F",lineUpBoldDownLeftBoldRight:"\u2543",lineUpBoldDownLeftRightBold:"\u2544",lineUpDownBoldLeftBoldRight:"\u2545",lineUpDownBoldLeftRightBold:"\u2546",lineUpDoubleDownDoubleLeftDoubleRightDouble:"\u256C",lineUpDoubleDownDoubleLeftRight:"\u256B",lineUpDownLeftDoubleRightDouble:"\u256A",lineCross:"\u2573",lineBackslash:"\u2572",lineSlash:"\u2571"},ht={tick:"\u2714",info:"\u2139",warning:"\u26A0",cross:"\u2718",squareSmall:"\u25FB",squareSmallFilled:"\u25FC",circle:"\u25EF",circleFilled:"\u25C9",circleDotted:"\u25CC",circleDouble:"\u25CE",circleCircle:"\u24DE",circleCross:"\u24E7",circlePipe:"\u24BE",radioOn:"\u25C9",radioOff:"\u25EF",checkboxOn:"\u2612",checkboxOff:"\u2610",checkboxCircleOn:"\u24E7",checkboxCircleOff:"\u24BE",pointer:"\u276F",triangleUpOutline:"\u25B3",triangleLeft:"\u25C0",triangleRight:"\u25B6",lozenge:"\u25C6",lozengeOutline:"\u25C7",hamburger:"\u2630",smiley:"\u32E1",mustache:"\u0DF4",star:"\u2605",play:"\u25B6",nodejs:"\u2B22",oneSeventh:"\u2150",oneNinth:"\u2151",oneTenth:"\u2152"},br={tick:"\u221A",info:"i",warning:"\u203C",cross:"\xD7",squareSmall:"\u25A1",squareSmallFilled:"\u25A0",circle:"( )",circleFilled:"(*)",circleDotted:"( )",circleDouble:"( )",circleCircle:"(\u25CB)",circleCross:"(\xD7)",circlePipe:"(\u2502)",radioOn:"(*)",radioOff:"( )",checkboxOn:"[\xD7]",checkboxOff:"[ ]",checkboxCircleOn:"(\xD7)",checkboxCircleOff:"( )",pointer:">",triangleUpOutline:"\u2206",triangleLeft:"\u25C4",triangleRight:"\u25BA",lozenge:"\u2666",lozengeOutline:"\u25CA",hamburger:"\u2261",smiley:"\u263A",mustache:"\u250C\u2500\u2510",star:"\u2736",play:"\u25BA",nodejs:"\u2666",oneSeventh:"1/7",oneNinth:"1/9",oneTenth:"1/10"},vr={...mt,...ht},Er={...mt,...br},Dr=yr(),Pr=Dr?vr:Er,Z=Pr,On=Object.entries(ht);var Lr={prefix:{idle:(0,C.styleText)("blue","?"),done:(0,C.styleText)("green",Z.tick)},spinner:{interval:80,frames:["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"].map(t=>(0,C.styleText)("yellow",t))},keybindings:[],style:{answer:t=>(0,C.styleText)("cyan",t),message:t=>(0,C.styleText)("bold",t),error:t=>(0,C.styleText)("red",`> ${t}`),defaultAnswer:t=>(0,C.styleText)("dim",`(${t})`),help:t=>(0,C.styleText)("dim",t),highlight:t=>(0,C.styleText)("cyan",t),key:t=>(0,C.styleText)("cyan",(0,C.styleText)("bold",`<${t}>`))}};function gt(){return{...Lr,keybindings:ct()}}function wt(t){if(typeof t!="object"||t===null)return!1;let e=t;for(;Object.getPrototypeOf(e)!==null;)e=Object.getPrototypeOf(e);return Object.getPrototypeOf(t)===e}function St(...t){let e={};for(let r of t)for(let[n,i]of Object.entries(r)){let o=e[n];e[n]=wt(o)&&wt(i)?St(o,i):i}return e}function N(...t){let e=[gt(),...t.filter(r=>r!=null)];return St(...e)}function H({status:t="idle",theme:e}){let[r,n]=D(!1),[i,o]=D(0),{prefix:s,spinner:a}=N(e);return A(()=>{if(t==="loading"){let u,f=-1,l=setTimeout(()=>{n(!0),u=setInterval(()=>{f=f+1,o(f%a.frames.length)},a.interval)},300);return()=>{clearTimeout(l),clearInterval(u)}}else n(!1)},[t]),r?a.frames[i]:typeof s=="string"?s:s[t==="loading"?"idle":t]??s.idle}function ae(t,e){return Q(r=>{let n=r.get();if(!n||n.dependencies.length!==e.length||n.dependencies.some((i,o)=>i!==e[o])){let i=t();return r.set({value:i,dependencies:e}),i}return n.value})}function G(t){return D({current:t})[0]}function J(t){let e=G(t);e.current=t,A(r=>{let n=!1,i=_e((o,s)=>{n||e.current(s,r)});return r.input.on("keypress",i),()=>{n=!0,r.input.removeListener("keypress",i)}},[])}var At=M(yt(),1);var bt=(()=>{let t=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;return e=>{let r=0;for(t.lastIndex=0;t.test(e);)r+=1;return e.length-r}})(),vt=t=>t===12288||t>=65281&&t<=65376||t>=65504&&t<=65510,Et=t=>t===8987||t===9001||t>=12272&&t<=12287||t>=12289&&t<=12350||t>=12441&&t<=12543||t>=12549&&t<=12591||t>=12593&&t<=12686||t>=12688&&t<=12771||t>=12783&&t<=12830||t>=12832&&t<=12871||t>=12880&&t<=19903||t>=65040&&t<=65049||t>=65072&&t<=65106||t>=65108&&t<=65126||t>=65128&&t<=65131||t>=127488&&t<=127490||t>=127504&&t<=127547||t>=127552&&t<=127560||t>=131072&&t<=196605||t>=196608&&t<=262141;var Fr=/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y,jr=/[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y,Dt=/(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu,Cr=/\t{1,1000}/y,Pt=new RegExp("[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F\\u20E3?))*","yu"),Tr=/(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y,_r=new RegExp("\\p{M}+","gu"),Br={limit:1/0,ellipsis:""},Lt=(t,e={},r={})=>{let n=e.limit??1/0,i=e.ellipsis??"",o=e?.ellipsisWidth??(i?Lt(i,Br,r).width:0),s=0,a=r.controlWidth??0,c=r.tabWidth??8,u=r.emojiWidth??2,f=2,l=r.regularWidth??1,p=r.wideWidth??f,S=[[Tr,l],[Fr,s],[jr,a],[Cr,c],[Pt,u],[Dt,p]],h=0,d=0,m=t.length,x=0,g=!1,y=m,b=Math.max(0,n-o),P=0,L=0,I=0,F=0;e:for(;;){if(L>P||d>=m&&d>h){let w=t.slice(P,L)||t.slice(h,d);x=0;for(let v of w.replaceAll(_r,"")){let E=v.codePointAt(0)||0;if(vt(E)?F=f:Et(E)?F=p:F=l,I+F>b&&(y=Math.min(y,Math.max(P,h)+x)),I+F>n){g=!0;break e}x+=v.length,I+=F}P=L=0}if(d>=m)break e;for(let w=0,v=S.length;w<v;w++){let[E,R]=S[w];if(E.lastIndex=d,E.test(t)){if(x=E===Dt?bt(t.slice(d,E.lastIndex)):E===Pt?1:E.lastIndex-d,F=x*R,I+F>b&&(y=Math.min(y,d+Math.floor((b-I)/R))),I+F>n){g=!0;break e}I+=F,P=h,L=d,d=h=E.lastIndex;continue e}}d+=1}return{width:g?b:I,index:g?y:m,truncated:g,ellipsed:g&&n>=o}},Rt=Lt;var Ur={limit:1/0,ellipsis:"",ellipsisWidth:0},Ar=(t,e={})=>Rt(t,Ur,e).width,O=Ar;var ye="\x1B",Tt="\x9B",Nr=39,Ue="\x07",_t="[",Or="]",Bt="m",Ae=`${Or}8;;`,It=new RegExp(`(?:\\${_t}(?<code>\\d+)m|\\${Ae}(?<uri>.*)${Ue})`,"y"),Ft=t=>{if(t>=30&&t<=37||t>=90&&t<=97)return 39;if(t>=40&&t<=47||t>=100&&t<=107)return 49;if(t===1||t===2)return 22;if(t===3)return 23;if(t===4)return 24;if(t===7)return 27;if(t===8)return 28;if(t===9)return 29;if(t===0)return 0},jt=t=>`${ye}${_t}${t}${Bt}`,Ct=t=>`${ye}${Ae}${t}${Ue}`,Be=(t,e,r)=>{let n=e[Symbol.iterator](),i=!1,o=!1,s=t.at(-1),a=s===void 0?0:O(s),c=n.next(),u=n.next(),f=0;for(;!c.done;){let l=c.value,p=O(l);a+p<=r?t[t.length-1]+=l:(t.push(l),a=0),(l===ye||l===Tt)&&(i=!0,o=e.startsWith(Ae,f+1)),i?o?l===Ue&&(i=!1,o=!1):l===Bt&&(i=!1):(a+=p,a===r&&!u.done&&(t.push(""),a=0)),c=u,u=n.next(),f+=l.length}s=t.at(-1),!a&&s!==void 0&&s.length&&t.length>1&&(t[t.length-2]+=t.pop())},Vr=t=>{let e=t.split(" "),r=e.length;for(;r&&!O(e[r-1]);)r--;return r===e.length?t:e.slice(0,r).join(" ")+e.slice(r).join("")},kr=(t,e,r={})=>{if(r.trim!==!1&&t.trim()==="")return"";let n="",i,o,s=t.split(" "),a=[""],c=0;for(let l=0;l<s.length;l++){let p=s[l];if(r.trim!==!1){let h=a.at(-1)??"",d=h.trimStart();h.length!==d.length&&(a[a.length-1]=d,c=O(d))}l!==0&&(c>=e&&(r.wordWrap===!1||r.trim===!1)&&(a.push(""),c=0),(c||r.trim===!1)&&(a[a.length-1]+=" ",c++));let S=O(p);if(r.hard&&S>e){let h=e-c,d=1+Math.floor((S-h-1)/e);Math.floor((S-1)/e)<d&&a.push(""),Be(a,p,e),c=O(a.at(-1)??"");continue}if(c+S>e&&c&&S){if(r.wordWrap===!1&&c<e){Be(a,p,e),c=O(a.at(-1)??"");continue}a.push(""),c=0}if(c+S>e&&r.wordWrap===!1){Be(a,p,e),c=O(a.at(-1)??"");continue}a[a.length-1]+=p,c+=S}r.trim!==!1&&(a=a.map(l=>Vr(l)));let u=a.join(`
4
- `),f=!1;for(let l=0;l<u.length;l++){let p=u[l];if(n+=p,f)f=!1;else if(f=p>="\uD800"&&p<="\uDBFF",f)continue;if(p===ye||p===Tt){It.lastIndex=l+1;let h=It.exec(u)?.groups;if(h?.code!==void 0){let d=Number.parseFloat(h.code);i=d===Nr?void 0:d}else h?.uri!==void 0&&(o=h.uri.length===0?void 0:h.uri)}if(u[l+1]===`
5
- `){o&&(n+=Ct(""));let S=i?Ft(i):void 0;i&&S&&(n+=jt(S))}else p===`
6
- `&&(i&&Ft(i)&&(n+=jt(i)),o&&(n+=Ct(o)))}return n},Mr=/\r?\n/;function Ut(t,e,r){return String(t).normalize().split(Mr).map(n=>kr(n,e,r)).join(`
2
+ "use strict";var tr=Object.create;var Ze=Object.defineProperty;var rr=Object.getOwnPropertyDescriptor;var nr=Object.getOwnPropertyNames;var ir=Object.getPrototypeOf,or=Object.prototype.hasOwnProperty;var et=(t,e)=>()=>{try{return e||t((e={exports:{}}).exports,e),e.exports}catch(r){throw e=0,r}};var sr=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of nr(e))!or.call(t,i)&&i!==r&&Ze(t,i,{get:()=>e[i],enumerable:!(n=rr(e,i))||n.enumerable});return t};var $=(t,e,r)=>(r=t!=null?tr(ir(t)):{},sr(e||!t||!t.__esModule?Ze(r,"default",{value:t,enumerable:!0}):r,t));var yt=et((ni,xt)=>{"use strict";xt.exports=Rr;function jr(t){let e={defaultWidth:0,output:process.stdout,tty:require("tty")};return t?(Object.keys(e).forEach(function(r){t[r]||(t[r]=e[r])}),t):e}function Rr(t){let e=jr(t);if(e.output.getWindowSize)return e.output.getWindowSize()[0]||e.defaultWidth;if(e.tty.getWindowSize)return e.tty.getWindowSize()[1]||e.defaultWidth;if(e.output.columns)return e.output.columns;if(process.env.CLI_WIDTH){let r=parseInt(process.env.CLI_WIDTH,10);if(!isNaN(r)&&r!==0)return r}return e.defaultWidth}});var Nt=et((wi,Ot)=>{var Wr=require("stream"),Ne=class extends Wr{#r=null;constructor(e={}){super(e),this.writable=this.readable=!0,this.muted=!1,this.on("pipe",this._onpipe),this.replace=e.replace,this._prompt=e.prompt||null,this._hadControl=!1}#t(e,r){return this._dest?this._dest[e]:this._src?this._src[e]:r}#e(e,...r){typeof this._dest?.[e]=="function"&&this._dest[e](...r),typeof this._src?.[e]=="function"&&this._src[e](...r)}get isTTY(){return this.#r!==null?this.#r:this.#t("isTTY",!1)}set isTTY(e){this.#r=e}get rows(){return this.#t("rows")}get columns(){return this.#t("columns")}mute(){this.muted=!0}unmute(){this.muted=!1}_onpipe(e){this._src=e}pipe(e,r){return this._dest=e,super.pipe(e,r)}pause(){if(this._src)return this._src.pause()}resume(){if(this._src)return this._src.resume()}write(e){if(this.muted){if(!this.replace)return!0;if(e.match(/^\u001b/))return e.indexOf(this._prompt)===0&&(e=e.slice(this._prompt.length),e=e.replace(/./g,this.replace),e=this._prompt+e),this._hadControl=!0,this.emit("data",e);this._prompt&&this._hadControl&&e.indexOf(this._prompt)===0&&(this._hadControl=!1,this.emit("data",this._prompt),e=e.slice(this._prompt.length)),e=e.toString().replace(/./g,this.replace)}this.emit("data",e)}end(e){this.muted&&(e&&this.replace?e=e.toString().replace(/./g,this.replace):e=null),e&&this.emit("data",e),this.emit("end")}destroy(...e){return this.#e("destroy",...e)}destroySoon(...e){return this.#e("destroySoon",...e)}close(...e){return this.#e("close",...e)}};Ot.exports=Ne});var V=$(require("path")),je=require("fs/promises");var T=require("fs/promises");async function z(t){try{return await ar(t)?JSON.parse(await(0,T.readFile)(t,{encoding:"utf-8"})):void 0}catch(e){throw new Error(`Error reading JSON file ${t}: ${e}`,{cause:e})}}async function re(t,e){let r=JSON.stringify(e,null,4)+`
3
+ `,n=await lr(t,r);await(0,T.writeFile)(t,n,{encoding:"utf-8"})}async function ar(t){try{return await(0,T.access)(t,T.constants.F_OK),!0}catch{return!1}}async function lr(t,e){let r=await ur();if(!r)return e;let n=await r.resolveConfig(t);return n?await r.format(e,{...n,filepath:t}):e}var cr;function ur(){return cr??=import("prettier").catch(()=>{})}var U=["UNKNOWN","LOW","MEDIUM","HIGH","CRITICAL"];var Re=class t{constructor(e){this.workingDir=e}workingDir;static DEFAULT_MAVEN_REPO="https://repository.conterra.de/repository/maven-mirror-ct";static DEFAULT_VEX_SUBDIR="input/vex";static DEFAULT_OUT_SUBDIR="output";static DEFAULT_CACHE_SUBDIR="cache";static DEFAULT_SCANNERS=["grype","trivy","ossindex"];normalize(e,r){let n=e.findNoLongerDetectedVulnerabilitiesOnlyForSnapshots??!1;return{projectConfigFileLocation:r,onNewVulnerabilities:e.onNewVulnerabilities??(e.failOnNewVulnerabilities?"fail":"warn"),onNoLongerDetectedVulnerabilities:e.onNoLongerDetectedVulnerabilities??"ignore",reportNoLongerDetectedVulnerabilities:e.reportNoLongerDetectedVulnerabilities??!0,consoleReport:e.consoleReport??"BY_PROJECT_DETAILED",createSubDirsForProject:e.createSubDirsForProject??!0,mavenRepo:e.mavenRepo??t.DEFAULT_MAVEN_REPO,vexUrls:e.vexUrls??[],vexDir:this.resolvePath(e.vexDir)??(0,V.resolve)(this.workingDir,t.DEFAULT_VEX_SUBDIR),outDir:this.resolvePath(e.outDir)??(0,V.resolve)(this.workingDir,t.DEFAULT_OUT_SUBDIR),cacheDir:this.resolvePath(e.cacheDir)??(0,V.resolve)(this.workingDir,t.DEFAULT_CACHE_SUBDIR),scanners:this.normalizeScanners(e.scanners,r),projects:this.normalizeProjects(e.projects??[],n)}}normalizeScanners(e,r){return(e??t.DEFAULT_SCANNERS).map(i=>{if(typeof i!="string")throw new Error(`Invalid scanner name '${String(i)}' in configuration file '${r}'`);let o=i.split("@");if(o.length>2)throw new Error(`Invalid scanner name '${i}' in configuration file '${r}'`);return{name:o[0],version:o[1]??""}})}normalizeProjects(e,r){return e.map(n=>{let i=n;if(!i.name)throw new Error("Project name is missing on entry: "+JSON.stringify(i));if(!i.version)throw new Error("Project version is missing on entry: "+JSON.stringify(i));if(!i.purl)throw new Error("Project purl is missing on entry: "+JSON.stringify(i));let o={...i,purlAliases:i.purlAliases??[],enabled:i.enabled??!0,silent:i.silent??!1,minimumSeverity:i.minimumSeverity??"UNKNOWN"};return o.sbomFile?{...o,sbomFile:this.resolvePath(o.sbomFile)??o.sbomFile}:{...o,detectNoLongerUsedVulnerabilities:r?o.purl.endsWith("-SNAPSHOT"):!0}})}resolvePath(e){if(e)return V.default.isAbsolute(e)?e:(0,V.resolve)(this.workingDir,e)}},k=class{constructor(e){this.workingDir=e;this.normalizer=new Re(e)}workingDir;normalizer;projectConfigCache;async loadProjectConfig(){return this.projectConfigCache??=this.doLoadProjectConfig(),this.projectConfigCache}async doLoadProjectConfig(){let e=(0,V.resolve)(this.workingDir,"vuln-scan-conf.json"),r=await z(e);if(!r)throw new Error(`Missing project configuration file '${e}'`);return this.normalizer.normalize(r,e)}async loadJiraConfig(e){let r=await(0,je.readFile)(e,"utf8"),n=JSON.parse(r);if(!n.issues&&n.issue&&(n.issues=n.issue),!n.jiraUrl||typeof n.jiraUrl!="string")throw new Error("jira-conf.json: missing or invalid 'jiraUrl' field");if(!Array.isArray(n.issues))throw new Error("jira-conf.json: missing or invalid 'issues' array");this.validateAutoCloseSeverity(n.autoCloseBelowSeverity,"jira-conf.json: invalid 'autoCloseBelowSeverity'");for(let[i,o]of n.issues.entries())if(o&&typeof o=="object"){let s=o;this.validateAutoCloseSeverity(s.autoCloseBelowSeverity,`jira-conf.json: invalid 'issues[${i}].autoCloseBelowSeverity'`),this.validateAutoCloseProjectOverrides(s.projectOverrides,`jira-conf.json: invalid 'issues[${i}].projectOverrides'`)}return n}validateAutoCloseSeverity(e,r){if(e!==void 0&&!U.includes(e))throw new Error(`${r} value '${String(e)}'. Must be one of: ${U.join(", ")}`)}validateAutoCloseProjectOverrides(e,r){if(e!==void 0){if(!Array.isArray(e))throw new Error(`${r}: must be an array`);for(let n=0;n<e.length;n++){let i=e[n],o=`${r}[${n}]`;if(i==null||typeof i!="object")throw new Error(`${o}: must be an object`);let s=i,a=s.projects;if(!Array.isArray(a)||a.length===0)throw new Error(`${o}.projects: must be a non-empty array of strings`);for(let c=0;c<a.length;c++){let u=a[c];if(typeof u!="string"||u.length===0)throw new Error(`${o}.projects[${c}]: must be a non-empty string`)}if(s.autoCloseBelowSeverity===void 0)throw new Error(`${o}.autoCloseBelowSeverity: is required`);if(this.validateAutoCloseSeverity(s.autoCloseBelowSeverity,`${o}.autoCloseBelowSeverity`),s.comment!==void 0&&typeof s.comment!="string")throw new Error(`${o}.comment: must be a string`)}}}async loadAutoVexConfig(e){let r=await(0,je.readFile)(e,"utf8"),n=JSON.parse(r);if(!n.impactStatement||typeof n.impactStatement!="string")throw new Error("auto-vex-conf.json: missing or invalid 'impactStatement' field (must be a non-empty string)");if(n.maxSeverity!==void 0&&!U.includes(n.maxSeverity))throw new Error(`auto-vex-conf.json: invalid 'maxSeverity' value '${String(n.maxSeverity)}'. Must be one of: ${U.join(", ")}`);if(n.projectOverrides!==void 0){if(!Array.isArray(n.projectOverrides))throw new Error("auto-vex-conf.json: 'projectOverrides' must be an array");for(let[i,o]of n.projectOverrides.entries()){if(!o||typeof o!="object")throw new Error(`auto-vex-conf.json: 'projectOverrides[${i}]' must be an object`);let s=o;if(!Array.isArray(s.projects)||s.projects.length===0||!s.projects.every(a=>typeof a=="string"&&a.length>0))throw new Error(`auto-vex-conf.json: 'projectOverrides[${i}].projects' must be a non-empty array of non-empty strings`);if(!U.includes(s.maxSeverity))throw new Error(`auto-vex-conf.json: invalid 'projectOverrides[${i}].maxSeverity' value '${String(s.maxSeverity)}'. Must be one of: ${U.join(", ")}`)}}return n}};var ue=class{constructor(e){this.configFilePath=e}configFilePath;async readRawConfig(){let e=await z(this.configFilePath);if(!e)throw new Error(`Missing project configuration file '${this.configFilePath}'`);return e}async insertAfter(e,r){let n=await this.readRawConfig(),i=n.projects??[],o=i.findIndex(s=>s.name===e.name&&s.version===e.version);if(o===-1)throw new Error(`Reference project ${e.name}@${e.version} not found in config`);i.splice(o+1,0,r),n.projects=i,await re(this.configFilePath,n)}async remove(e,r){let n=await this.readRawConfig(),i=n.projects??[],o=i.findIndex(s=>s.name===e&&s.version===r);return o===-1?!1:(i.splice(o,1),n.projects=i,await re(this.configFilePath,n),!0)}};var st=require("fs/promises"),Ie=require("path");var rt=require("crypto");var tt="auto_vex_max_severity=";function fe(t){let e=t.status_notes;if(!e||!e.startsWith(tt))return;let r=e.slice(tt.length).trim();return U.includes(r)?r:void 0}var fr="https://openvex.dev/ns/v0.2.0";function nt(t,e="conterra"){let n=`https://openvex.dev/docs/public/vex-${(0,rt.randomUUID)()}`,i=t.timestamp??new Date().toISOString();return{"@context":fr,"@id":n,author:e,timestamp:i,last_updated:i,version:1,statements:[t]}}function it(t,e){let r=e.timestamp??new Date().toISOString();return{...t,last_updated:r,version:t.version+1,statements:[...t.statements,e]}}var pe=require("fs/promises"),me=require("path");var de=class{constructor(e){this.location=e}location;_content=void 0;_exists=!1;get exists(){return this._exists}get content(){return this._content}set content(e){this._content=e,this._exists=e!==void 0}async read(){let e=await z(this.location);this._content=e??void 0,this._exists=this._content!==void 0}async write(){if(this._content===void 0)throw new Error(`Cannot write VexFile: content is undefined (${this.location})`);await(0,pe.mkdir)((0,me.dirname)((0,me.resolve)(this.location)),{recursive:!0}),await re(this.location,this._content)}async delete(){await(0,pe.unlink)(this.location),this._exists=!1}upsert(e,r){if(this._content===void 0)return this._content=nt(e,r),this._exists=!0,{created:!0,changed:!0};let n=fe(e);if(n!==void 0){let i=this._content.statements.findIndex(o=>o.vulnerability.name===e.vulnerability.name&&o.status===e.status&&fe(o)===n);if(i!==-1){let o=this._content.statements[i];return dr(o,e)?{created:!1,changed:!1}:(o.products=e.products,o.impact_statement=e.impact_statement,o.action_statement=e.action_statement,o.justification=e.justification,o.status_notes=e.status_notes,o.timestamp=e.timestamp,this._content.version+=1,this._content.last_updated=e.timestamp??new Date().toISOString(),{created:!1,changed:!0})}}return this._content=it(this._content,e),{created:!1,changed:!0}}addProductId(e,r){this.assertContentLoaded("addProductId");let n=!1;for(let i of this._content.statements){if(!i.products||i.products.some(s=>s["@id"]===r))continue;let o=i.products.findIndex(s=>s["@id"]===e);o!==-1&&(i.products.splice(o+1,0,{"@id":r}),n=!0)}return n}removeProductId(e,r){this.assertContentLoaded("removeProductId");let n=this._content.statements,i=[],o=!1;for(let s of n){if(r&&!ot(s).has(r)||!s.products)continue;let a=s.products.findIndex(c=>c["@id"]===e);a!==-1&&(s.products.splice(a,1),o=!0,s.products.length===0&&i.push(s))}if(!o)return"unchanged";for(let s of i)n.splice(n.indexOf(s),1);return n.length===0?"emptied":"changed"}hasStatementForProduct(e){return this.assertContentLoaded("hasStatementForProduct"),this._content.statements.some(r=>r.products?.some(n=>n["@id"]===e)??!1)}assertContentLoaded(e){if(this._content===void 0)throw new Error(`VexFile.${e}(): content is not loaded. Call read() first (${this.location})`)}};function dr(t,e){return t.impact_statement!==e.impact_statement||t.action_statement!==e.action_statement||t.justification!==e.justification||t.status_notes!==e.status_notes?!1:pr(t.products,e.products)}function pr(t,e){let r=o=>Array.from(new Set((o??[]).map(s=>s["@id"]).filter(s=>typeof s=="string"))).sort(),n=r(t),i=r(e);return n.length!==i.length?!1:n.every((o,s)=>o===i[s])}async function Ce(t,e){for(let r of await(0,st.readdir)(t,{withFileTypes:!0}))r.name.endsWith(".json")?await e(new de((0,Ie.resolve)(r.parentPath,r.name))):r.isDirectory()&&await Ce((0,Ie.resolve)(r.parentPath,r.name),e)}function ot(t){let e=t.vulnerability.name;return new Set([e,...t.vulnerability.aliases??[]])}async function at({workingDir:t,existingPurl:e,newPurl:r}){let n=await new k(t).loadProjectConfig();await Ce(n.vexDir,async i=>{await i.read(),i.addProductId(e,r)&&(console.info(`Add ${r} to ${i.location}`),await i.write())})}async function lt({workingDir:t,projectName:e,referenceProjectVersion:r,targetProjectVersion:n}){let i=await new k(t).loadProjectConfig();if(!i.projectConfigFileLocation)throw new Error("Missing project configuration file.");let o=i.projects.find(a=>a.name===e&&a.version===r);if(!o)throw new Error(`Project ${e} with version ${r} not found.`);let s=i.projects.find(a=>a.name===e&&a.version===n);s||(s=await mr(e,i.projectConfigFileLocation,o,n)),await at({workingDir:t,existingPurl:o.purl,newPurl:s.purl})}async function mr(t,e,r,n){let i=new ue(e),s=(await i.readRawConfig()).projects.find(c=>c.name===r.name&&c.version===r.version),a={...s};return a.version=n,a.purl=s.purl.replace(s.version,n),"sbomMavenCoordinates"in a?a.sbomMavenCoordinates=s.sbomMavenCoordinates.replace(s.version,n):"sbomFile"in a&&(a.sbomFile=s.sbomFile.replace(s.version,n)),console.info(`Add project ${t} with version ${n} to ${e}`),await i.insertAfter(r,a),a}var hr=["emacs","vim"],gr=new Set(hr);function wr(t){return gr.has(t)}function ct(){let t=process.env.INQUIRER_KEYBINDINGS;return t?Array.from(new Set(t.toLowerCase().split(/[\s,]+/).filter(wr))):[]}var ne=(t,e=[])=>t.name==="up"||e.includes("vim")&&t.name==="k"||e.includes("emacs")&&t.ctrl&&t.name==="p",he=(t,e=[])=>t.name==="down"||e.includes("vim")&&t.name==="j"||e.includes("emacs")&&t.ctrl&&t.name==="n";var ie=t=>t.name==="backspace",oe=t=>t.name==="tab",Fe=t=>"1234567890".includes(t.name),M=t=>t.name==="enter"||t.name==="return";var ge=class extends Error{name="AbortPromptError";message="Prompt was aborted";constructor(e){super(),this.cause=e?.cause}},we=class extends Error{name="CancelPromptError";message="Prompt was canceled"},se=class extends Error{name="ExitPromptError"},Se=class extends Error{name="HookError"},Y=class extends Error{name="ValidationError"};var pt=require("node:async_hooks");var xe=require("node:async_hooks");var ut=new xe.AsyncLocalStorage;function Sr(t){return{rl:t,hooks:[],hooksCleanup:[],hooksEffect:[],index:0,handleChange(){}}}function ft(t,e){let r=Sr(t);return ut.run(r,()=>{function n(i){r.handleChange=()=>{r.index=0,i()},r.handleChange()}return e(n)})}function W(){let t=ut.getStore();if(!t)throw new Se("[Inquirer] Hook functions can only be called from within a prompt");return t}function Te(){return W().rl}function _e(t){let e=(...r)=>{let n=W(),i=!1,o=n.handleChange;n.handleChange=()=>{i=!0};let s=t(...r);return i&&o(),n.handleChange=o,s};return xe.AsyncResource.bind(e)}function Q(t){let e=W(),{index:r}=e,n={get(){return e.hooks[r]},set(o){e.hooks[r]=o},initialized:r in e.hooks},i=t(n);return e.index++,i}function dt(){W().handleChange()}var K={queue(t){let e=W(),{index:r}=e;e.hooksEffect.push(()=>{e.hooksCleanup[r]?.();let n=t(Te());if(n!=null&&typeof n!="function")throw new Y("useEffect return value must be a cleanup function or nothing.");e.hooksCleanup[r]=n})},run(){let t=W();_e(()=>{t.hooksEffect.forEach(e=>{e()}),t.hooksEffect.length=0})()},clearAll(){let t=W();t.hooksCleanup.forEach(e=>{e?.()}),t.hooksEffect.length=0,t.hooksCleanup.length=0}};function xr(t){return typeof t=="function"}function D(t){return Q(e=>{let r=pt.AsyncResource.bind(function(o){e.get()!==o&&(e.set(o),dt())});if(e.initialized)return[e.get(),r];let n=xr(t)?t():t;return e.set(n),[n,r]})}function A(t,e){Q(r=>{let n=r.get();(!Array.isArray(n)||e.some((o,s)=>!Object.is(o,n[s])))&&K.queue(t),r.set(e)})}var F=require("node:util");var C=$(require("node:process"),1);function yr(){return C.default.platform.startsWith("win")?!!C.default.env.CI||!!C.default.env.WT_SESSION||!!C.default.env.TERMINUS_SUBLIME||C.default.env.ConEmuTask==="{cmd::Cmder}"||C.default.env.TERM_PROGRAM==="Terminus-Sublime"||C.default.env.TERM_PROGRAM==="vscode"||C.default.env.TERM==="xterm-256color"||C.default.env.TERM==="alacritty"||C.default.env.TERMINAL_EMULATOR==="JetBrains-JediTerm":C.default.env.TERM!=="linux"}var mt={circleQuestionMark:"(?)",questionMarkPrefix:"(?)",square:"\u2588",squareDarkShade:"\u2593",squareMediumShade:"\u2592",squareLightShade:"\u2591",squareTop:"\u2580",squareBottom:"\u2584",squareLeft:"\u258C",squareRight:"\u2590",squareCenter:"\u25A0",bullet:"\u25CF",dot:"\u2024",ellipsis:"\u2026",pointerSmall:"\u203A",triangleUp:"\u25B2",triangleUpSmall:"\u25B4",triangleDown:"\u25BC",triangleDownSmall:"\u25BE",triangleLeftSmall:"\u25C2",triangleRightSmall:"\u25B8",home:"\u2302",heart:"\u2665",musicNote:"\u266A",musicNoteBeamed:"\u266B",arrowUp:"\u2191",arrowDown:"\u2193",arrowLeft:"\u2190",arrowRight:"\u2192",arrowLeftRight:"\u2194",arrowUpDown:"\u2195",almostEqual:"\u2248",notEqual:"\u2260",lessOrEqual:"\u2264",greaterOrEqual:"\u2265",identical:"\u2261",infinity:"\u221E",subscriptZero:"\u2080",subscriptOne:"\u2081",subscriptTwo:"\u2082",subscriptThree:"\u2083",subscriptFour:"\u2084",subscriptFive:"\u2085",subscriptSix:"\u2086",subscriptSeven:"\u2087",subscriptEight:"\u2088",subscriptNine:"\u2089",oneHalf:"\xBD",oneThird:"\u2153",oneQuarter:"\xBC",oneFifth:"\u2155",oneSixth:"\u2159",oneEighth:"\u215B",twoThirds:"\u2154",twoFifths:"\u2156",threeQuarters:"\xBE",threeFifths:"\u2157",threeEighths:"\u215C",fourFifths:"\u2158",fiveSixths:"\u215A",fiveEighths:"\u215D",sevenEighths:"\u215E",line:"\u2500",lineBold:"\u2501",lineDouble:"\u2550",lineDashed0:"\u2504",lineDashed1:"\u2505",lineDashed2:"\u2508",lineDashed3:"\u2509",lineDashed4:"\u254C",lineDashed5:"\u254D",lineDashed6:"\u2574",lineDashed7:"\u2576",lineDashed8:"\u2578",lineDashed9:"\u257A",lineDashed10:"\u257C",lineDashed11:"\u257E",lineDashed12:"\u2212",lineDashed13:"\u2013",lineDashed14:"\u2010",lineDashed15:"\u2043",lineVertical:"\u2502",lineVerticalBold:"\u2503",lineVerticalDouble:"\u2551",lineVerticalDashed0:"\u2506",lineVerticalDashed1:"\u2507",lineVerticalDashed2:"\u250A",lineVerticalDashed3:"\u250B",lineVerticalDashed4:"\u254E",lineVerticalDashed5:"\u254F",lineVerticalDashed6:"\u2575",lineVerticalDashed7:"\u2577",lineVerticalDashed8:"\u2579",lineVerticalDashed9:"\u257B",lineVerticalDashed10:"\u257D",lineVerticalDashed11:"\u257F",lineDownLeft:"\u2510",lineDownLeftArc:"\u256E",lineDownBoldLeftBold:"\u2513",lineDownBoldLeft:"\u2512",lineDownLeftBold:"\u2511",lineDownDoubleLeftDouble:"\u2557",lineDownDoubleLeft:"\u2556",lineDownLeftDouble:"\u2555",lineDownRight:"\u250C",lineDownRightArc:"\u256D",lineDownBoldRightBold:"\u250F",lineDownBoldRight:"\u250E",lineDownRightBold:"\u250D",lineDownDoubleRightDouble:"\u2554",lineDownDoubleRight:"\u2553",lineDownRightDouble:"\u2552",lineUpLeft:"\u2518",lineUpLeftArc:"\u256F",lineUpBoldLeftBold:"\u251B",lineUpBoldLeft:"\u251A",lineUpLeftBold:"\u2519",lineUpDoubleLeftDouble:"\u255D",lineUpDoubleLeft:"\u255C",lineUpLeftDouble:"\u255B",lineUpRight:"\u2514",lineUpRightArc:"\u2570",lineUpBoldRightBold:"\u2517",lineUpBoldRight:"\u2516",lineUpRightBold:"\u2515",lineUpDoubleRightDouble:"\u255A",lineUpDoubleRight:"\u2559",lineUpRightDouble:"\u2558",lineUpDownLeft:"\u2524",lineUpBoldDownBoldLeftBold:"\u252B",lineUpBoldDownBoldLeft:"\u2528",lineUpDownLeftBold:"\u2525",lineUpBoldDownLeftBold:"\u2529",lineUpDownBoldLeftBold:"\u252A",lineUpDownBoldLeft:"\u2527",lineUpBoldDownLeft:"\u2526",lineUpDoubleDownDoubleLeftDouble:"\u2563",lineUpDoubleDownDoubleLeft:"\u2562",lineUpDownLeftDouble:"\u2561",lineUpDownRight:"\u251C",lineUpBoldDownBoldRightBold:"\u2523",lineUpBoldDownBoldRight:"\u2520",lineUpDownRightBold:"\u251D",lineUpBoldDownRightBold:"\u2521",lineUpDownBoldRightBold:"\u2522",lineUpDownBoldRight:"\u251F",lineUpBoldDownRight:"\u251E",lineUpDoubleDownDoubleRightDouble:"\u2560",lineUpDoubleDownDoubleRight:"\u255F",lineUpDownRightDouble:"\u255E",lineDownLeftRight:"\u252C",lineDownBoldLeftBoldRightBold:"\u2533",lineDownLeftBoldRightBold:"\u252F",lineDownBoldLeftRight:"\u2530",lineDownBoldLeftBoldRight:"\u2531",lineDownBoldLeftRightBold:"\u2532",lineDownLeftRightBold:"\u252E",lineDownLeftBoldRight:"\u252D",lineDownDoubleLeftDoubleRightDouble:"\u2566",lineDownDoubleLeftRight:"\u2565",lineDownLeftDoubleRightDouble:"\u2564",lineUpLeftRight:"\u2534",lineUpBoldLeftBoldRightBold:"\u253B",lineUpLeftBoldRightBold:"\u2537",lineUpBoldLeftRight:"\u2538",lineUpBoldLeftBoldRight:"\u2539",lineUpBoldLeftRightBold:"\u253A",lineUpLeftRightBold:"\u2536",lineUpLeftBoldRight:"\u2535",lineUpDoubleLeftDoubleRightDouble:"\u2569",lineUpDoubleLeftRight:"\u2568",lineUpLeftDoubleRightDouble:"\u2567",lineUpDownLeftRight:"\u253C",lineUpBoldDownBoldLeftBoldRightBold:"\u254B",lineUpDownBoldLeftBoldRightBold:"\u2548",lineUpBoldDownLeftBoldRightBold:"\u2547",lineUpBoldDownBoldLeftRightBold:"\u254A",lineUpBoldDownBoldLeftBoldRight:"\u2549",lineUpBoldDownLeftRight:"\u2540",lineUpDownBoldLeftRight:"\u2541",lineUpDownLeftBoldRight:"\u253D",lineUpDownLeftRightBold:"\u253E",lineUpBoldDownBoldLeftRight:"\u2542",lineUpDownLeftBoldRightBold:"\u253F",lineUpBoldDownLeftBoldRight:"\u2543",lineUpBoldDownLeftRightBold:"\u2544",lineUpDownBoldLeftBoldRight:"\u2545",lineUpDownBoldLeftRightBold:"\u2546",lineUpDoubleDownDoubleLeftDoubleRightDouble:"\u256C",lineUpDoubleDownDoubleLeftRight:"\u256B",lineUpDownLeftDoubleRightDouble:"\u256A",lineCross:"\u2573",lineBackslash:"\u2572",lineSlash:"\u2571"},ht={tick:"\u2714",info:"\u2139",warning:"\u26A0",cross:"\u2718",squareSmall:"\u25FB",squareSmallFilled:"\u25FC",circle:"\u25EF",circleFilled:"\u25C9",circleDotted:"\u25CC",circleDouble:"\u25CE",circleCircle:"\u24DE",circleCross:"\u24E7",circlePipe:"\u24BE",radioOn:"\u25C9",radioOff:"\u25EF",checkboxOn:"\u2612",checkboxOff:"\u2610",checkboxCircleOn:"\u24E7",checkboxCircleOff:"\u24BE",pointer:"\u276F",triangleUpOutline:"\u25B3",triangleLeft:"\u25C0",triangleRight:"\u25B6",lozenge:"\u25C6",lozengeOutline:"\u25C7",hamburger:"\u2630",smiley:"\u32E1",mustache:"\u0DF4",star:"\u2605",play:"\u25B6",nodejs:"\u2B22",oneSeventh:"\u2150",oneNinth:"\u2151",oneTenth:"\u2152"},br={tick:"\u221A",info:"i",warning:"\u203C",cross:"\xD7",squareSmall:"\u25A1",squareSmallFilled:"\u25A0",circle:"( )",circleFilled:"(*)",circleDotted:"( )",circleDouble:"( )",circleCircle:"(\u25CB)",circleCross:"(\xD7)",circlePipe:"(\u2502)",radioOn:"(*)",radioOff:"( )",checkboxOn:"[\xD7]",checkboxOff:"[ ]",checkboxCircleOn:"(\xD7)",checkboxCircleOff:"( )",pointer:">",triangleUpOutline:"\u2206",triangleLeft:"\u25C4",triangleRight:"\u25BA",lozenge:"\u2666",lozengeOutline:"\u25CA",hamburger:"\u2261",smiley:"\u263A",mustache:"\u250C\u2500\u2510",star:"\u2736",play:"\u25BA",nodejs:"\u2666",oneSeventh:"1/7",oneNinth:"1/9",oneTenth:"1/10"},vr={...mt,...ht},Er={...mt,...br},Dr=yr(),Pr=Dr?vr:Er,Z=Pr,Nn=Object.entries(ht);var Lr={prefix:{idle:(0,F.styleText)("blue","?"),done:(0,F.styleText)("green",Z.tick)},spinner:{interval:80,frames:["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"].map(t=>(0,F.styleText)("yellow",t))},keybindings:[],style:{answer:t=>(0,F.styleText)("cyan",t),message:t=>(0,F.styleText)("bold",t),error:t=>(0,F.styleText)("red",`> ${t}`),defaultAnswer:t=>(0,F.styleText)("dim",`(${t})`),help:t=>(0,F.styleText)("dim",t),highlight:t=>(0,F.styleText)("cyan",t),key:t=>(0,F.styleText)("cyan",(0,F.styleText)("bold",`<${t}>`))}};function gt(){return{...Lr,keybindings:ct()}}function wt(t){if(typeof t!="object"||t===null)return!1;let e=t;for(;Object.getPrototypeOf(e)!==null;)e=Object.getPrototypeOf(e);return Object.getPrototypeOf(t)===e}function St(...t){let e={};for(let r of t)for(let[n,i]of Object.entries(r)){let o=e[n];e[n]=wt(o)&&wt(i)?St(o,i):i}return e}function O(...t){let e=[gt(),...t.filter(r=>r!=null)];return St(...e)}function H({status:t="idle",theme:e}){let[r,n]=D(!1),[i,o]=D(0),{prefix:s,spinner:a}=O(e);return A(()=>{if(t==="loading"){let u,f=-1,l=setTimeout(()=>{n(!0),u=setInterval(()=>{f=f+1,o(f%a.frames.length)},a.interval)},300);return()=>{clearTimeout(l),clearInterval(u)}}else n(!1)},[t]),r?a.frames[i]:typeof s=="string"?s:s[t==="loading"?"idle":t]??s.idle}function ae(t,e){return Q(r=>{let n=r.get();if(!n||n.dependencies.length!==e.length||n.dependencies.some((i,o)=>i!==e[o])){let i=t();return r.set({value:i,dependencies:e}),i}return n.value})}function G(t){return D({current:t})[0]}function J(t){let e=G(t);e.current=t,A(r=>{let n=!1,i=_e((o,s)=>{n||e.current(s,r)});return r.input.on("keypress",i),()=>{n=!0,r.input.removeListener("keypress",i)}},[])}var At=$(yt(),1);var bt=(()=>{let t=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;return e=>{let r=0;for(t.lastIndex=0;t.test(e);)r+=1;return e.length-r}})(),vt=t=>t===12288||t>=65281&&t<=65376||t>=65504&&t<=65510,Et=t=>t===8987||t===9001||t>=12272&&t<=12287||t>=12289&&t<=12350||t>=12441&&t<=12543||t>=12549&&t<=12591||t>=12593&&t<=12686||t>=12688&&t<=12771||t>=12783&&t<=12830||t>=12832&&t<=12871||t>=12880&&t<=19903||t>=65040&&t<=65049||t>=65072&&t<=65106||t>=65108&&t<=65126||t>=65128&&t<=65131||t>=127488&&t<=127490||t>=127504&&t<=127547||t>=127552&&t<=127560||t>=131072&&t<=196605||t>=196608&&t<=262141;var Ir=/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y,Cr=/[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y,Dt=/(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu,Fr=/\t{1,1000}/y,Pt=new RegExp("[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F\\u20E3?))*","yu"),Tr=/(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y,_r=new RegExp("\\p{M}+","gu"),Br={limit:1/0,ellipsis:""},Lt=(t,e={},r={})=>{let n=e.limit??1/0,i=e.ellipsis??"",o=e?.ellipsisWidth??(i?Lt(i,Br,r).width:0),s=0,a=r.controlWidth??0,c=r.tabWidth??8,u=r.emojiWidth??2,f=2,l=r.regularWidth??1,p=r.wideWidth??f,S=[[Tr,l],[Ir,s],[Cr,a],[Fr,c],[Pt,u],[Dt,p]],h=0,d=0,m=t.length,x=0,g=!1,y=m,b=Math.max(0,n-o),P=0,L=0,R=0,I=0;e:for(;;){if(L>P||d>=m&&d>h){let w=t.slice(P,L)||t.slice(h,d);x=0;for(let v of w.replaceAll(_r,"")){let E=v.codePointAt(0)||0;if(vt(E)?I=f:Et(E)?I=p:I=l,R+I>b&&(y=Math.min(y,Math.max(P,h)+x)),R+I>n){g=!0;break e}x+=v.length,R+=I}P=L=0}if(d>=m)break e;for(let w=0,v=S.length;w<v;w++){let[E,j]=S[w];if(E.lastIndex=d,E.test(t)){if(x=E===Dt?bt(t.slice(d,E.lastIndex)):E===Pt?1:E.lastIndex-d,I=x*j,R+I>b&&(y=Math.min(y,d+Math.floor((b-R)/j))),R+I>n){g=!0;break e}R+=I,P=h,L=d,d=h=E.lastIndex;continue e}}d+=1}return{width:g?b:R,index:g?y:m,truncated:g,ellipsed:g&&n>=o}},jt=Lt;var Ur={limit:1/0,ellipsis:"",ellipsisWidth:0},Ar=(t,e={})=>jt(t,Ur,e).width,N=Ar;var ye="\x1B",Tt="\x9B",Or=39,Ue="\x07",_t="[",Nr="]",Bt="m",Ae=`${Nr}8;;`,Rt=new RegExp(`(?:\\${_t}(?<code>\\d+)m|\\${Ae}(?<uri>.*)${Ue})`,"y"),It=t=>{if(t>=30&&t<=37||t>=90&&t<=97)return 39;if(t>=40&&t<=47||t>=100&&t<=107)return 49;if(t===1||t===2)return 22;if(t===3)return 23;if(t===4)return 24;if(t===7)return 27;if(t===8)return 28;if(t===9)return 29;if(t===0)return 0},Ct=t=>`${ye}${_t}${t}${Bt}`,Ft=t=>`${ye}${Ae}${t}${Ue}`,Be=(t,e,r)=>{let n=e[Symbol.iterator](),i=!1,o=!1,s=t.at(-1),a=s===void 0?0:N(s),c=n.next(),u=n.next(),f=0;for(;!c.done;){let l=c.value,p=N(l);a+p<=r?t[t.length-1]+=l:(t.push(l),a=0),(l===ye||l===Tt)&&(i=!0,o=e.startsWith(Ae,f+1)),i?o?l===Ue&&(i=!1,o=!1):l===Bt&&(i=!1):(a+=p,a===r&&!u.done&&(t.push(""),a=0)),c=u,u=n.next(),f+=l.length}s=t.at(-1),!a&&s!==void 0&&s.length&&t.length>1&&(t[t.length-2]+=t.pop())},Vr=t=>{let e=t.split(" "),r=e.length;for(;r&&!N(e[r-1]);)r--;return r===e.length?t:e.slice(0,r).join(" ")+e.slice(r).join("")},kr=(t,e,r={})=>{if(r.trim!==!1&&t.trim()==="")return"";let n="",i,o,s=t.split(" "),a=[""],c=0;for(let l=0;l<s.length;l++){let p=s[l];if(r.trim!==!1){let h=a.at(-1)??"",d=h.trimStart();h.length!==d.length&&(a[a.length-1]=d,c=N(d))}l!==0&&(c>=e&&(r.wordWrap===!1||r.trim===!1)&&(a.push(""),c=0),(c||r.trim===!1)&&(a[a.length-1]+=" ",c++));let S=N(p);if(r.hard&&S>e){let h=e-c,d=1+Math.floor((S-h-1)/e);Math.floor((S-1)/e)<d&&a.push(""),Be(a,p,e),c=N(a.at(-1)??"");continue}if(c+S>e&&c&&S){if(r.wordWrap===!1&&c<e){Be(a,p,e),c=N(a.at(-1)??"");continue}a.push(""),c=0}if(c+S>e&&r.wordWrap===!1){Be(a,p,e),c=N(a.at(-1)??"");continue}a[a.length-1]+=p,c+=S}r.trim!==!1&&(a=a.map(l=>Vr(l)));let u=a.join(`
4
+ `),f=!1;for(let l=0;l<u.length;l++){let p=u[l];if(n+=p,f)f=!1;else if(f=p>="\uD800"&&p<="\uDBFF",f)continue;if(p===ye||p===Tt){Rt.lastIndex=l+1;let h=Rt.exec(u)?.groups;if(h?.code!==void 0){let d=Number.parseFloat(h.code);i=d===Or?void 0:d}else h?.uri!==void 0&&(o=h.uri.length===0?void 0:h.uri)}if(u[l+1]===`
5
+ `){o&&(n+=Ft(""));let S=i?It(i):void 0;i&&S&&(n+=Ct(S))}else p===`
6
+ `&&(i&&It(i)&&(n+=Ct(i)),o&&(n+=Ft(o)))}return n},$r=/\r?\n/;function Ut(t,e,r){return String(t).normalize().split($r).map(n=>kr(n,e,r)).join(`
7
7
  `)}function le(t,e){return t.split(`
8
8
  `).flatMap(r=>Ut(r,e,{trim:!1,wordWrap:!1}).split(`
9
9
  `).map(n=>n.trimEnd())).join(`
10
- `)}function be(){return(0,At.default)({defaultWidth:80,output:Te().output})}function $r({active:t,renderedItems:e,pageSize:r,loop:n}){let i=G({lastPointer:t,lastActive:void 0}),{lastPointer:o,lastActive:s}=i.current,a=Math.floor(r/2),c=e.reduce((l,p)=>l+p.length,0),u=e.slice(0,t).reduce((l,p)=>l+p.length,0),f=u;if(c>r)if(n)f=o,s!=null&&s<t&&t-s<r&&(f=Math.min(a,Math.abs(t-s)===1?Math.min(o+(e[s]?.length??0),Math.max(u,o)):o+t-s));else{let l=e.slice(t).reduce((p,S)=>p+S.length,0);f=l<r-a?r-l:Math.min(u,a)}return i.current.lastPointer=f,i.current.lastActive=t,f}function Ne({items:t,active:e,renderItem:r,pageSize:n,loop:i=!0}){let o=be(),s=x=>(x%t.length+t.length)%t.length,a=t.map((x,g)=>x==null?[]:le(r({item:x,index:g,isActive:g===e}),o).split(`
11
- `)),c=a.reduce((x,g)=>x+g.length,0),u=x=>a[x]??[],f=$r({active:e,renderedItems:a,pageSize:n,loop:i}),l=u(e).slice(0,n),p=f+l.length<=n?f:n-l.length,S=Array.from({length:n});S.splice(p,l.length,...l);let h=new Set([e]),d=p+l.length,m=s(e+1);for(;d<n&&!h.has(m)&&(i&&c>n?m!==e:m>e);){let g=u(m).slice(0,n-d);S.splice(d,g.length,...g),h.add(m),d+=g.length,m=s(m+1)}for(d=p-1,m=s(e-1);d>=0&&!h.has(m)&&(i&&c>n?m!==e:m<e);){let x=u(m),g=x.slice(Math.max(0,x.length-d-1));S.splice(d-g.length+1,g.length,...g),h.add(m),d-=g.length,m=s(m-1)}return S.filter(x=>typeof x=="string").join(`
12
- `)}var Ht=M(require("node:readline"),1),Gt=require("node:async_hooks"),Jt=M(Ot(),1);var q=[];q.push("SIGHUP","SIGINT","SIGTERM");process.platform!=="win32"&&q.push("SIGALRM","SIGABRT","SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT");process.platform==="linux"&&q.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT");var ve=t=>!!t&&typeof t=="object"&&typeof t.removeListener=="function"&&typeof t.emit=="function"&&typeof t.reallyExit=="function"&&typeof t.listeners=="function"&&typeof t.kill=="function"&&typeof t.pid=="number"&&typeof t.on=="function",Ve=Symbol.for("signal-exit emitter"),ke=globalThis,Kr=Object.defineProperty.bind(Object),Me=class{emitted={afterExit:!1,exit:!1};listeners={afterExit:[],exit:[]};count=0;id=Math.random();constructor(){if(ke[Ve])return ke[Ve];Kr(ke,Ve,{value:this,writable:!1,enumerable:!1,configurable:!1})}on(e,r){this.listeners[e].push(r)}removeListener(e,r){let n=this.listeners[e],i=n.indexOf(r);i!==-1&&(i===0&&n.length===1?n.length=0:n.splice(i,1))}emit(e,r,n){if(this.emitted[e])return!1;this.emitted[e]=!0;let i=!1;for(let o of this.listeners[e])i=o(r,n)===!0||i;return e==="exit"&&(i=this.emit("afterExit",r,n)||i),i}},Ee=class{},Hr=t=>({onExit(e,r){return t.onExit(e,r)},load(){return t.load()},unload(){return t.unload()}}),$e=class extends Ee{onExit(){return()=>{}}load(){}unload(){}},We=class extends Ee{#r=Ke.platform==="win32"?"SIGINT":"SIGHUP";#t=new Me;#e;#o;#s;#i={};#n=!1;constructor(e){super(),this.#e=e,this.#i={};for(let r of q)this.#i[r]=()=>{let n=this.#e.listeners(r),{count:i}=this.#t,o=e;if(typeof o.__signal_exit_emitter__=="object"&&typeof o.__signal_exit_emitter__.count=="number"&&(i+=o.__signal_exit_emitter__.count),n.length===i){this.unload();let s=this.#t.emit("exit",null,r),a=r==="SIGHUP"?this.#r:r;s||e.kill(e.pid,a)}};this.#s=e.reallyExit,this.#o=e.emit}onExit(e,r){if(!ve(this.#e))return()=>{};this.#n===!1&&this.load();let n=r?.alwaysLast?"afterExit":"exit";return this.#t.on(n,e),()=>{this.#t.removeListener(n,e),this.#t.listeners.exit.length===0&&this.#t.listeners.afterExit.length===0&&this.unload()}}load(){if(!this.#n){this.#n=!0,this.#t.count+=1;for(let e of q)try{let r=this.#i[e];r&&this.#e.on(e,r)}catch{}this.#e.emit=(e,...r)=>this.#l(e,...r),this.#e.reallyExit=e=>this.#a(e)}}unload(){this.#n&&(this.#n=!1,q.forEach(e=>{let r=this.#i[e];if(!r)throw new Error("Listener not defined for signal: "+e);try{this.#e.removeListener(e,r)}catch{}}),this.#e.emit=this.#o,this.#e.reallyExit=this.#s,this.#t.count-=1)}#a(e){return ve(this.#e)?(this.#e.exitCode=e||0,this.#t.emit("exit",this.#e.exitCode,null),this.#s.call(this.#e,this.#e.exitCode)):0}#l(e,...r){let n=this.#o;if(e==="exit"&&ve(this.#e)){typeof r[0]=="number"&&(this.#e.exitCode=r[0]);let i=n.call(this.#e,e,...r);return this.#t.emit("exit",this.#e.exitCode,null),i}else return n.call(this.#e,e,...r)}},Ke=globalThis.process,{onExit:Vt,load:yi,unload:bi}=Hr(ve(Ke)?new We(Ke):new $e);var Kt=require("node:util");var Mt="\x1B[?25l",$t="\x1B[?25h",He=(t=1)=>t>0?`\x1B[${t}A`:"",Ge=(t=1)=>t>0?`\x1B[${t}B`:"",Je=(t,e)=>typeof e=="number"&&!Number.isNaN(e)?`\x1B[${e+1};${t+1}H`:`\x1B[${t+1}G`,kt="\x1B[2K",qe=t=>t>0?(kt+He(1)).repeat(t-1)+kt+"\x1B[G":"";var Wt=t=>t.split(`
10
+ `)}function be(){return(0,At.default)({defaultWidth:80,output:Te().output})}function Mr({active:t,renderedItems:e,pageSize:r,loop:n}){let i=G({lastPointer:t,lastActive:void 0}),{lastPointer:o,lastActive:s}=i.current,a=Math.floor(r/2),c=e.reduce((l,p)=>l+p.length,0),u=e.slice(0,t).reduce((l,p)=>l+p.length,0),f=u;if(c>r)if(n)f=o,s!=null&&s<t&&t-s<r&&(f=Math.min(a,Math.abs(t-s)===1?Math.min(o+(e[s]?.length??0),Math.max(u,o)):o+t-s));else{let l=e.slice(t).reduce((p,S)=>p+S.length,0);f=l<r-a?r-l:Math.min(u,a)}return i.current.lastPointer=f,i.current.lastActive=t,f}function Oe({items:t,active:e,renderItem:r,pageSize:n,loop:i=!0}){let o=be(),s=x=>(x%t.length+t.length)%t.length,a=t.map((x,g)=>x==null?[]:le(r({item:x,index:g,isActive:g===e}),o).split(`
11
+ `)),c=a.reduce((x,g)=>x+g.length,0),u=x=>a[x]??[],f=Mr({active:e,renderedItems:a,pageSize:n,loop:i}),l=u(e).slice(0,n),p=f+l.length<=n?f:n-l.length,S=Array.from({length:n});S.splice(p,l.length,...l);let h=new Set([e]),d=p+l.length,m=s(e+1);for(;d<n&&!h.has(m)&&(i&&c>n?m!==e:m>e);){let g=u(m).slice(0,n-d);S.splice(d,g.length,...g),h.add(m),d+=g.length,m=s(m+1)}for(d=p-1,m=s(e-1);d>=0&&!h.has(m)&&(i&&c>n?m!==e:m<e);){let x=u(m),g=x.slice(Math.max(0,x.length-d-1));S.splice(d-g.length+1,g.length,...g),h.add(m),d-=g.length,m=s(m-1)}return S.filter(x=>typeof x=="string").join(`
12
+ `)}var Ht=$(require("node:readline"),1),Gt=require("node:async_hooks"),Jt=$(Nt(),1);var q=[];q.push("SIGHUP","SIGINT","SIGTERM");process.platform!=="win32"&&q.push("SIGALRM","SIGABRT","SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT");process.platform==="linux"&&q.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT");var ve=t=>!!t&&typeof t=="object"&&typeof t.removeListener=="function"&&typeof t.emit=="function"&&typeof t.reallyExit=="function"&&typeof t.listeners=="function"&&typeof t.kill=="function"&&typeof t.pid=="number"&&typeof t.on=="function",Ve=Symbol.for("signal-exit emitter"),ke=globalThis,Kr=Object.defineProperty.bind(Object),$e=class{emitted={afterExit:!1,exit:!1};listeners={afterExit:[],exit:[]};count=0;id=Math.random();constructor(){if(ke[Ve])return ke[Ve];Kr(ke,Ve,{value:this,writable:!1,enumerable:!1,configurable:!1})}on(e,r){this.listeners[e].push(r)}removeListener(e,r){let n=this.listeners[e],i=n.indexOf(r);i!==-1&&(i===0&&n.length===1?n.length=0:n.splice(i,1))}emit(e,r,n){if(this.emitted[e])return!1;this.emitted[e]=!0;let i=!1;for(let o of this.listeners[e])i=o(r,n)===!0||i;return e==="exit"&&(i=this.emit("afterExit",r,n)||i),i}},Ee=class{},Hr=t=>({onExit(e,r){return t.onExit(e,r)},load(){return t.load()},unload(){return t.unload()}}),Me=class extends Ee{onExit(){return()=>{}}load(){}unload(){}},We=class extends Ee{#r=Ke.platform==="win32"?"SIGINT":"SIGHUP";#t=new $e;#e;#o;#s;#i={};#n=!1;constructor(e){super(),this.#e=e,this.#i={};for(let r of q)this.#i[r]=()=>{let n=this.#e.listeners(r),{count:i}=this.#t,o=e;if(typeof o.__signal_exit_emitter__=="object"&&typeof o.__signal_exit_emitter__.count=="number"&&(i+=o.__signal_exit_emitter__.count),n.length===i){this.unload();let s=this.#t.emit("exit",null,r),a=r==="SIGHUP"?this.#r:r;s||e.kill(e.pid,a)}};this.#s=e.reallyExit,this.#o=e.emit}onExit(e,r){if(!ve(this.#e))return()=>{};this.#n===!1&&this.load();let n=r?.alwaysLast?"afterExit":"exit";return this.#t.on(n,e),()=>{this.#t.removeListener(n,e),this.#t.listeners.exit.length===0&&this.#t.listeners.afterExit.length===0&&this.unload()}}load(){if(!this.#n){this.#n=!0,this.#t.count+=1;for(let e of q)try{let r=this.#i[e];r&&this.#e.on(e,r)}catch{}this.#e.emit=(e,...r)=>this.#l(e,...r),this.#e.reallyExit=e=>this.#a(e)}}unload(){this.#n&&(this.#n=!1,q.forEach(e=>{let r=this.#i[e];if(!r)throw new Error("Listener not defined for signal: "+e);try{this.#e.removeListener(e,r)}catch{}}),this.#e.emit=this.#o,this.#e.reallyExit=this.#s,this.#t.count-=1)}#a(e){return ve(this.#e)?(this.#e.exitCode=e||0,this.#t.emit("exit",this.#e.exitCode,null),this.#s.call(this.#e,this.#e.exitCode)):0}#l(e,...r){let n=this.#o;if(e==="exit"&&ve(this.#e)){typeof r[0]=="number"&&(this.#e.exitCode=r[0]);let i=n.call(this.#e,e,...r);return this.#t.emit("exit",this.#e.exitCode,null),i}else return n.call(this.#e,e,...r)}},Ke=globalThis.process,{onExit:Vt,load:yi,unload:bi}=Hr(ve(Ke)?new We(Ke):new Me);var Kt=require("node:util");var $t="\x1B[?25l",Mt="\x1B[?25h",He=(t=1)=>t>0?`\x1B[${t}A`:"",Ge=(t=1)=>t>0?`\x1B[${t}B`:"",Je=(t,e)=>typeof e=="number"&&!Number.isNaN(e)?`\x1B[${e+1};${t+1}H`:`\x1B[${t+1}G`,kt="\x1B[2K",qe=t=>t>0?(kt+He(1)).repeat(t-1)+kt+"\x1B[G":"";var Wt=t=>t.split(`
13
13
  `).length,Jr=t=>t.split(`
14
14
  `).pop()??"",ce=class{height=0;extraLinesUnderPrompt=0;cursorPos;rl;constructor(e){this.rl=e,this.cursorPos=e.getCursorPos()}write(e){this.rl.output.unmute(),this.rl.output.write(e),this.rl.output.mute()}render(e,r=""){let n=Jr(e),i=(0,Kt.stripVTControlCharacters)(n),o=i;this.rl.line.length>0&&(o=o.slice(0,-this.rl.line.length)),this.rl.setPrompt(o),this.cursorPos=this.rl.getCursorPos();let s=be();e=le(e,s),r=le(r,s),i.length%s===0&&(e+=`
15
15
  `);let a=e+(r?`
16
16
  `+r:""),u=Math.floor(i.length/s)-this.cursorPos.rows+(r?Wt(r):0);u>0&&(a+=He(u)),a+=Je(this.cursorPos.cols),this.write(Ge(this.extraLinesUnderPrompt)+qe(this.height)+a),this.extraLinesUnderPrompt=u,this.height=Wt(a)}checkCursorPos(){let e=this.rl.getCursorPos();e.cols!==this.cursorPos.cols&&(this.write(Je(e.cols)),this.cursorPos=e)}done({clearContent:e}){this.rl.setPrompt("");let r=Ge(this.extraLinesUnderPrompt);r+=e?qe(this.height):`
17
- `,r+="\x1B[G",r+=$t,this.write(r),this.rl.close()}};var De=class extends Promise{static withResolver(){let e,r;return{promise:new Promise((i,o)=>{e=i,r=o}),resolve:e,reject:r}}};var qt=M(require("node:path"),1),qr=globalThis.setImmediate;function Xr(){let t=Error.prepareStackTrace,e=[];try{Error.prepareStackTrace=(r,n)=>{let i=n.slice(1);return e=i,i},new Error().stack}catch{return e}return Error.prepareStackTrace=t,e}function X(t){let e=Xr();return(n,i={})=>{let{input:o=process.stdin,signal:s}=i,a=new Set,c=new Jt.default;c.pipe(i.output??process.stdout);let u=Ht.createInterface({terminal:!0,input:o,output:c});c.mute();let f=new ce(u),{promise:l,resolve:p,reject:S}=De.withResolver(),h=()=>S(new we);if(s){let m=()=>S(new ge({cause:s.reason}));if(s.aborted)return m(),Object.assign(l,{cancel:h});s.addEventListener("abort",m),a.add(()=>s.removeEventListener("abort",m))}a.add(Vt((m,x)=>{S(new se(`User force closed the prompt with ${m} ${x}`))}));let d=()=>S(new se("User force closed the prompt with SIGINT"));return u.on("SIGINT",d),a.add(()=>u.removeListener("SIGINT",d)),ft(u,m=>{let x=Gt.AsyncResource.bind(()=>K.clearAll());u.on("close",x),a.add(()=>u.removeListener("close",x));let g=()=>{let y=()=>f.checkCursorPos();u.input.on("keypress",y),a.add(()=>u.input.removeListener("keypress",y));let b=null;m(()=>{let P=!1;try{let L=t(n,w=>{P?p(w):b={value:w}});if(L===void 0){let w=e[1]?.getFileName();throw w&&!w.startsWith("file://")&&(w=qt.default.resolve(w)),new Error(`Prompt functions must return a string.
18
- at ${w}`)}let[I,F]=typeof L=="string"?[L]:L;f.render(I,F),K.run()}catch(L){S(L)}if(P=!0,b!==null){let{value:L}=b;b=null,p(L)}})};return"readableFlowing"in o?qr(g):g(),Object.assign(l.then(y=>(K.clearAll(),y),y=>{throw K.clearAll(),y}).finally(()=>{a.forEach(y=>y()),f.done({clearContent:!!i.clearPromptOnDone}),c.end()}).then(()=>l),{cancel:h})})}}var Xt=require("node:util");var _=class{separator=(0,Xt.styleText)("dim",Array.from({length:15}).join(Z.line));type="separator";constructor(e){e&&(this.separator=e)}static isSeparator(e){return!!(e&&typeof e=="object"&&"type"in e&&e.type==="separator")}};function zt(t,e){let r=e!==!1;return/^(y|yes)/i.test(t)?r=!0:/^(n|no)/i.test(t)&&(r=!1),r}function Yt(t){return t?"Yes":"No"}var Xe=X((t,e)=>{let{transformer:r=Yt}=t,[n,i]=D("idle"),[o,s]=D(""),a=N(t.theme),c=H({status:n,theme:a});J((p,S)=>{if(n==="idle")if($(p)){let h=zt(o,t.default);s(r(h)),i("done"),e(h)}else if(oe(p)){let h=Yt(!zt(o,t.default));S.clearLine(0),S.write(h),s(h)}else s(S.line)});let u=o,f="";n==="done"?u=a.style.answer(o):f=` ${a.style.defaultAnswer(t.default===!1?"y/N":"Y/n")}`;let l=a.style.message(t.message,n);return`${c} ${l}${f} ${u}`});var zr={validationFailureMode:"keep"},ze=X((t,e)=>{let{prefill:r="tab"}=t,n=N(zr,t.theme),[i,o]=D("idle"),[s,a]=D(String(t.default??"")),[c,u]=D(),[f,l]=D(""),p=H({status:i,theme:n});async function S(g){let{required:y,pattern:b,patternError:P="Invalid input"}=t;return y&&!g?"You must provide a value":b&&!b.test(g)?P:typeof t.validate=="function"?await t.validate(g)||"You must provide a valid value":!0}J(async(g,y)=>{if(i==="idle")if($(g)){let b=f||s;o("loading");let P=await S(b);P===!0?(l(b),o("done"),e(b)):(n.validationFailureMode==="clear"?l(""):y.write(f),u(P),o("idle"))}else ie(g)&&!f?a(""):oe(g)&&!f?(a(""),y.clearLine(0),y.write(s),l(s)):(l(y.line),u(void 0))}),A(g=>{r==="editable"&&s&&(g.write(s),l(s))},[]);let h=n.style.message(t.message,i),d=f;typeof t.transformer=="function"?d=t.transformer(f,{isFinal:i==="done"}):i==="done"&&(d=n.style.answer(f));let m;s&&i!=="done"&&!f&&(m=n.style.defaultAnswer(s));let x="";return c&&(x=n.style.error(c)),[[p,h,m,d].filter(g=>g!==void 0).join(" "),x]});var ee=require("node:util");var Yr={icon:{cursor:Z.pointer},style:{disabled:t=>(0,ee.styleText)("dim",t),description:t=>(0,ee.styleText)("cyan",t),keysHelpTip:t=>t.map(([e,r])=>`${(0,ee.styleText)("bold",e)} ${(0,ee.styleText)("dim",r)}`).join((0,ee.styleText)("dim"," \u2022 "))},i18n:{disabledError:"This option is disabled and cannot be selected."},indexMode:"hidden"};function Ye(t){return!_.isSeparator(t)&&!t.disabled}function Qe(t){return!_.isSeparator(t)}function Qr(t){return t.map(e=>{if(_.isSeparator(e))return e;if(typeof e!="object"||e===null||!("value"in e)){let i=String(e);return{value:e,name:i,short:i,disabled:!1}}let r=e.name??String(e.value),n={value:e.value,name:r,short:e.short??r,disabled:e.disabled??!1};return e.description&&(n.description=e.description),n})}var Pe=X((t,e)=>{let{loop:r=!0,pageSize:n=7}=t,i=N(Yr,t.theme),{keybindings:o}=i,[s,a]=D("idle"),c=H({status:s,theme:i}),u=G(),f=!o.includes("vim"),l=ae(()=>Qr(t.choices),[t.choices]),p=ae(()=>{let w=l.findIndex(Qe),v=l.findLastIndex(Qe);if(w===-1)throw new Y("[select prompt] No selectable choices. All choices are disabled.");return{first:w,last:v}},[l]),S=ae(()=>"default"in t?l.findIndex(w=>Ye(w)&&w.value===t.default):-1,[t.default,l]),[h,d]=D(S===-1?p.first:S),m=l[h];if(m==null||_.isSeparator(m))throw new Error("Active index does not point to a choice");let[x,g]=D();J((w,v)=>{if(clearTimeout(u.current),x&&g(void 0),$(w))m.disabled?g(i.i18n.disabledError):(a("done"),e(m.value));else if(ne(w,o)||he(w,o)){if(v.clearLine(0),r||ne(w,o)&&h!==p.first||he(w,o)&&h!==p.last){let E=ne(w,o)?-1:1,R=h;do R=(R+E+l.length)%l.length;while(!Qe(l[R]));d(R)}}else if(Ce(w)&&!Number.isNaN(Number(v.line))){let E=Number(v.line)-1,R=-1,B=l.findIndex(te=>_.isSeparator(te)?!1:(R++,R===E)),Le=l[B];Le!=null&&Ye(Le)&&d(B),u.current=setTimeout(()=>{v.clearLine(0)},700)}else if(ie(w))v.clearLine(0);else if(f){let E=v.line.toLowerCase(),R=l.findIndex(B=>_.isSeparator(B)||!Ye(B)?!1:B.name.toLowerCase().startsWith(E));R!==-1&&d(R),u.current=setTimeout(()=>{v.clearLine(0)},700)}}),A(()=>()=>{clearTimeout(u.current)},[]);let y=i.style.message(t.message,s),b=i.style.keysHelpTip([["\u2191\u2193","navigate"],["\u23CE","select"]]),P=0,L=Ne({items:l,active:h,renderItem({item:w,isActive:v,index:E}){if(_.isSeparator(w))return P++,` ${w.separator}`;let R=v?i.icon.cursor:" ",B=i.indexMode==="number"?`${E+1-P}. `:"";if(w.disabled){let te=typeof w.disabled=="string"?w.disabled:"(disabled)",er=v?i.icon.cursor:"-";return i.style.disabled(`${er} ${B}${w.name} ${te}`)}return(v?i.style.highlight:te=>te)(`${R} ${B}${w.name}`)},pageSize:n,loop:r});if(s==="done")return[c,y,i.style.answer(m.short)].filter(Boolean).join(" ");let{description:I}=m;return`${[[c,y].filter(Boolean).join(" "),L," ",I?i.style.description(I):"",x?i.style.error(x):"",b].filter(Boolean).join(`
19
- `).trimEnd()}${Mt}`});async function Qt(t){let e=new Map;for(let s of t.projects){let a=e.get(s.name);a?a.push(s.version):e.set(s.name,[s.version])}let r=Array.from(e.keys()).sort(),n=await Pe({message:"Choose project name:",choices:r.map(s=>({name:s,value:s})),pageSize:15}),i=(e.get(n)??[]).sort(),o=await Pe({message:"Choose project version:",choices:i.map(s=>({name:s,value:s})),pageSize:15});return{projectName:n,projectVersion:o}}var Zt=process.cwd();(async()=>{let{projectName:t,referenceProjectVersion:e,targetProjectVersion:r}=await Zr();await lt({workingDir:Zt,projectName:t,referenceProjectVersion:e,targetProjectVersion:r})})();async function Zr(){let t=process.argv[2];if(!t)return en();let e=process.argv[3];if(!e)throw new Error("Missing reference project version.");let r=process.argv[4];if(!r)throw new Error("Missing target project version.");return{projectName:t,referenceProjectVersion:e,targetProjectVersion:r}}async function en(){try{let t=await new k(Zt).loadProjectConfig(),{projectName:e,projectVersion:r}=await Qt(t),n=await ze({message:`Enter the target project version (e.g. ${r}):`,required:!0});return await Xe({message:`New project ${e}@${n} will be added based on ${r}.
17
+ `,r+="\x1B[G",r+=Mt,this.write(r),this.rl.close()}};var De=class extends Promise{static withResolver(){let e,r;return{promise:new Promise((i,o)=>{e=i,r=o}),resolve:e,reject:r}}};var qt=$(require("node:path"),1),qr=globalThis.setImmediate;function Xr(){let t=Error.prepareStackTrace,e=[];try{Error.prepareStackTrace=(r,n)=>{let i=n.slice(1);return e=i,i},new Error().stack}catch{return e}return Error.prepareStackTrace=t,e}function X(t){let e=Xr();return(n,i={})=>{let{input:o=process.stdin,signal:s}=i,a=new Set,c=new Jt.default;c.pipe(i.output??process.stdout);let u=Ht.createInterface({terminal:!0,input:o,output:c});c.mute();let f=new ce(u),{promise:l,resolve:p,reject:S}=De.withResolver(),h=()=>S(new we);if(s){let m=()=>S(new ge({cause:s.reason}));if(s.aborted)return m(),Object.assign(l,{cancel:h});s.addEventListener("abort",m),a.add(()=>s.removeEventListener("abort",m))}a.add(Vt((m,x)=>{S(new se(`User force closed the prompt with ${m} ${x}`))}));let d=()=>S(new se("User force closed the prompt with SIGINT"));return u.on("SIGINT",d),a.add(()=>u.removeListener("SIGINT",d)),ft(u,m=>{let x=Gt.AsyncResource.bind(()=>K.clearAll());u.on("close",x),a.add(()=>u.removeListener("close",x));let g=()=>{let y=()=>f.checkCursorPos();u.input.on("keypress",y),a.add(()=>u.input.removeListener("keypress",y));let b=null;m(()=>{let P=!1;try{let L=t(n,w=>{P?p(w):b={value:w}});if(L===void 0){let w=e[1]?.getFileName();throw w&&!w.startsWith("file://")&&(w=qt.default.resolve(w)),new Error(`Prompt functions must return a string.
18
+ at ${w}`)}let[R,I]=typeof L=="string"?[L]:L;f.render(R,I),K.run()}catch(L){S(L)}if(P=!0,b!==null){let{value:L}=b;b=null,p(L)}})};return"readableFlowing"in o?qr(g):g(),Object.assign(l.then(y=>(K.clearAll(),y),y=>{throw K.clearAll(),y}).finally(()=>{a.forEach(y=>y()),f.done({clearContent:!!i.clearPromptOnDone}),c.end()}).then(()=>l),{cancel:h})})}}var Xt=require("node:util");var _=class{separator=(0,Xt.styleText)("dim",Array.from({length:15}).join(Z.line));type="separator";constructor(e){e&&(this.separator=e)}static isSeparator(e){return!!(e&&typeof e=="object"&&"type"in e&&e.type==="separator")}};function zt(t,e){let r=e!==!1;return/^(y|yes)/i.test(t)?r=!0:/^(n|no)/i.test(t)&&(r=!1),r}function Yt(t){return t?"Yes":"No"}var Xe=X((t,e)=>{let{transformer:r=Yt}=t,[n,i]=D("idle"),[o,s]=D(""),a=O(t.theme),c=H({status:n,theme:a});J((p,S)=>{if(n==="idle")if(M(p)){let h=zt(o,t.default);s(r(h)),i("done"),e(h)}else if(oe(p)){let h=Yt(!zt(o,t.default));S.clearLine(0),S.write(h),s(h)}else s(S.line)});let u=o,f="";n==="done"?u=a.style.answer(o):f=` ${a.style.defaultAnswer(t.default===!1?"y/N":"Y/n")}`;let l=a.style.message(t.message,n);return`${c} ${l}${f} ${u}`});var zr={validationFailureMode:"keep"},ze=X((t,e)=>{let{prefill:r="tab"}=t,n=O(zr,t.theme),[i,o]=D("idle"),[s,a]=D(String(t.default??"")),[c,u]=D(),[f,l]=D(""),p=H({status:i,theme:n});async function S(g){let{required:y,pattern:b,patternError:P="Invalid input"}=t;return y&&!g?"You must provide a value":b&&!b.test(g)?P:typeof t.validate=="function"?await t.validate(g)||"You must provide a valid value":!0}J(async(g,y)=>{if(i==="idle")if(M(g)){let b=f||s;o("loading");let P=await S(b);P===!0?(l(b),o("done"),e(b)):(n.validationFailureMode==="clear"?l(""):y.write(f),u(P),o("idle"))}else ie(g)&&!f?a(""):oe(g)&&!f?(a(""),y.clearLine(0),y.write(s),l(s)):(l(y.line),u(void 0))}),A(g=>{r==="editable"&&s&&(g.write(s),l(s))},[]);let h=n.style.message(t.message,i),d=f;typeof t.transformer=="function"?d=t.transformer(f,{isFinal:i==="done"}):i==="done"&&(d=n.style.answer(f));let m;s&&i!=="done"&&!f&&(m=n.style.defaultAnswer(s));let x="";return c&&(x=n.style.error(c)),[[p,h,m,d].filter(g=>g!==void 0).join(" "),x]});var ee=require("node:util");var Yr={icon:{cursor:Z.pointer},style:{disabled:t=>(0,ee.styleText)("dim",t),description:t=>(0,ee.styleText)("cyan",t),keysHelpTip:t=>t.map(([e,r])=>`${(0,ee.styleText)("bold",e)} ${(0,ee.styleText)("dim",r)}`).join((0,ee.styleText)("dim"," \u2022 "))},i18n:{disabledError:"This option is disabled and cannot be selected."},indexMode:"hidden"};function Ye(t){return!_.isSeparator(t)&&!t.disabled}function Qe(t){return!_.isSeparator(t)}function Qr(t){return t.map(e=>{if(_.isSeparator(e))return e;if(typeof e!="object"||e===null||!("value"in e)){let i=String(e);return{value:e,name:i,short:i,disabled:!1}}let r=e.name??String(e.value),n={value:e.value,name:r,short:e.short??r,disabled:e.disabled??!1};return e.description&&(n.description=e.description),n})}var Pe=X((t,e)=>{let{loop:r=!0,pageSize:n=7}=t,i=O(Yr,t.theme),{keybindings:o}=i,[s,a]=D("idle"),c=H({status:s,theme:i}),u=G(),f=!o.includes("vim"),l=ae(()=>Qr(t.choices),[t.choices]),p=ae(()=>{let w=l.findIndex(Qe),v=l.findLastIndex(Qe);if(w===-1)throw new Y("[select prompt] No selectable choices. All choices are disabled.");return{first:w,last:v}},[l]),S=ae(()=>"default"in t?l.findIndex(w=>Ye(w)&&w.value===t.default):-1,[t.default,l]),[h,d]=D(S===-1?p.first:S),m=l[h];if(m==null||_.isSeparator(m))throw new Error("Active index does not point to a choice");let[x,g]=D();J((w,v)=>{if(clearTimeout(u.current),x&&g(void 0),M(w))m.disabled?g(i.i18n.disabledError):(a("done"),e(m.value));else if(ne(w,o)||he(w,o)){if(v.clearLine(0),r||ne(w,o)&&h!==p.first||he(w,o)&&h!==p.last){let E=ne(w,o)?-1:1,j=h;do j=(j+E+l.length)%l.length;while(!Qe(l[j]));d(j)}}else if(Fe(w)&&!Number.isNaN(Number(v.line))){let E=Number(v.line)-1,j=-1,B=l.findIndex(te=>_.isSeparator(te)?!1:(j++,j===E)),Le=l[B];Le!=null&&Ye(Le)&&d(B),u.current=setTimeout(()=>{v.clearLine(0)},700)}else if(ie(w))v.clearLine(0);else if(f){let E=v.line.toLowerCase(),j=l.findIndex(B=>_.isSeparator(B)||!Ye(B)?!1:B.name.toLowerCase().startsWith(E));j!==-1&&d(j),u.current=setTimeout(()=>{v.clearLine(0)},700)}}),A(()=>()=>{clearTimeout(u.current)},[]);let y=i.style.message(t.message,s),b=i.style.keysHelpTip([["\u2191\u2193","navigate"],["\u23CE","select"]]),P=0,L=Oe({items:l,active:h,renderItem({item:w,isActive:v,index:E}){if(_.isSeparator(w))return P++,` ${w.separator}`;let j=v?i.icon.cursor:" ",B=i.indexMode==="number"?`${E+1-P}. `:"";if(w.disabled){let te=typeof w.disabled=="string"?w.disabled:"(disabled)",er=v?i.icon.cursor:"-";return i.style.disabled(`${er} ${B}${w.name} ${te}`)}return(v?i.style.highlight:te=>te)(`${j} ${B}${w.name}`)},pageSize:n,loop:r});if(s==="done")return[c,y,i.style.answer(m.short)].filter(Boolean).join(" ");let{description:R}=m;return`${[[c,y].filter(Boolean).join(" "),L," ",R?i.style.description(R):"",x?i.style.error(x):"",b].filter(Boolean).join(`
19
+ `).trimEnd()}${$t}`});async function Qt(t){let e=new Map;for(let s of t.projects){let a=e.get(s.name);a?a.push(s.version):e.set(s.name,[s.version])}let r=Array.from(e.keys()).sort(),n=await Pe({message:"Choose project name:",choices:r.map(s=>({name:s,value:s})),pageSize:15}),i=(e.get(n)??[]).sort(),o=await Pe({message:"Choose project version:",choices:i.map(s=>({name:s,value:s})),pageSize:15});return{projectName:n,projectVersion:o}}var Zt=process.cwd();(async()=>{let{projectName:t,referenceProjectVersion:e,targetProjectVersion:r}=await Zr();await lt({workingDir:Zt,projectName:t,referenceProjectVersion:e,targetProjectVersion:r})})();async function Zr(){let t=process.argv[2];if(!t)return en();let e=process.argv[3];if(!e)throw new Error("Missing reference project version.");let r=process.argv[4];if(!r)throw new Error("Missing target project version.");return{projectName:t,referenceProjectVersion:e,targetProjectVersion:r}}async function en(){try{let t=await new k(Zt).loadProjectConfig(),{projectName:e,projectVersion:r}=await Qt(t),n=await ze({message:`Enter the target project version (e.g. ${r}):`,required:!0});return await Xe({message:`New project ${e}@${n} will be added based on ${r}.
20
20
  Do you want to proceed?`})||(console.log("Aborted."),process.exit(0)),{projectName:e,referenceProjectVersion:r,targetProjectVersion:n}}catch(t){console.error(`Error: ${t}`),process.exitCode=1;return}}