From c3276a745d8a3dc5cb87d205fdffdf4268de1983 Mon Sep 17 00:00:00 2001 From: wangyudong Date: Tue, 30 Dec 2025 23:47:20 +0800 Subject: [PATCH 1/5] fix: switch to async spawn to unblock spinner animation and switch from `ora` to `nanospinner` fix ExperimentalWarning --- package-lock.json | 211 +++------------------------------------- package.json | 4 +- src/commands/install.ts | 36 +++++-- 3 files changed, 43 insertions(+), 208 deletions(-) diff --git a/package-lock.json b/package-lock.json index a168c6d..c73d745 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@inquirer/prompts": "^7.9.0", "chalk": "^5.6.2", "commander": "^12.1.0", - "ora": "^9.0.0" + "nanospinner": "^1.2.2" }, "bin": { "openskills": "dist/cli.js" @@ -1287,7 +1287,6 @@ "integrity": "sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -1420,6 +1419,7 @@ "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -1545,33 +1545,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "license": "MIT", - "dependencies": { - "restore-cursor": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-spinners": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.3.0.tgz", - "integrity": "sha512-/+40ljC3ONVnYIttjMWrlL51nItDAbBrq2upN8BPyvGU/2n5Oxw3tbNwORCaNuNqLJnxGqOfjUuhsv7l5Q4IsQ==", - "license": "MIT", - "engines": { - "node": ">=18.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/cli-width": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", @@ -1686,7 +1659,6 @@ "dev": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -1804,22 +1776,10 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/get-east-asian-width": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", - "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "license": "ISC", "dependencies": { @@ -1862,30 +1822,6 @@ "node": ">=8" } }, - "node_modules/is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-unicode-supported": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", - "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1956,22 +1892,6 @@ "dev": true, "license": "MIT" }, - "node_modules/log-symbols": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", - "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", - "license": "MIT", - "dependencies": { - "is-unicode-supported": "^2.0.0", - "yoctocolors": "^2.1.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", @@ -1989,18 +1909,6 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/mimic-function": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", - "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", @@ -2087,6 +1995,15 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/nanospinner": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/nanospinner/-/nanospinner-1.2.2.tgz", + "integrity": "sha512-Zt/AmG6qRU3e+WnzGGLuMCEAO/dAu45stNbHY223tUxldaDAeE+FxSPsd9Q+j+paejmm0ZbrNVs5Sraqy3dRxA==", + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.1" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -2097,60 +2014,6 @@ "node": ">=0.10.0" } }, - "node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-9.0.0.tgz", - "integrity": "sha512-m0pg2zscbYgWbqRR6ABga5c3sZdEon7bSgjnlXC64kxtxLOyjRcbbUkLj7HFyy/FTD+P2xdBWu8snGhYI0jc4A==", - "license": "MIT", - "dependencies": { - "chalk": "^5.6.2", - "cli-cursor": "^5.0.0", - "cli-spinners": "^3.2.0", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^2.1.0", - "log-symbols": "^7.0.1", - "stdin-discarder": "^0.2.2", - "string-width": "^8.1.0", - "strip-ansi": "^7.1.2" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/node_modules/string-width": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", - "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", - "license": "MIT", - "dependencies": { - "get-east-asian-width": "^1.3.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -2196,7 +2059,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, "license": "ISC" }, "node_modules/picomatch": { @@ -2205,7 +2067,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -2255,7 +2116,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -2342,22 +2202,6 @@ "node": ">=8" } }, - "node_modules/restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "license": "MIT", - "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/rollup": { "version": "4.52.5", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz", @@ -2486,18 +2330,6 @@ "dev": true, "license": "MIT" }, - "node_modules/stdin-discarder": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", - "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -2566,6 +2398,7 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -2784,7 +2617,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2813,7 +2645,6 @@ "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -3111,18 +2942,6 @@ "node": ">=8" } }, - "node_modules/yoctocolors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", - "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/yoctocolors-cjs": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", diff --git a/package.json b/package.json index e6240d8..e661d8c 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "@inquirer/prompts": "^7.9.0", "chalk": "^5.6.2", "commander": "^12.1.0", - "ora": "^9.0.0" + "nanospinner": "^1.2.2" }, "devDependencies": { "@types/node": "^24.9.1", @@ -57,4 +57,4 @@ "typescript": "^5.9.3", "vitest": "^4.0.3" } -} +} \ No newline at end of file diff --git a/src/commands/install.ts b/src/commands/install.ts index dc35b18..a97900b 100644 --- a/src/commands/install.ts +++ b/src/commands/install.ts @@ -1,9 +1,9 @@ import { readFileSync, readdirSync, existsSync, mkdirSync, rmSync, cpSync, statSync } from 'fs'; import { join, basename, resolve } from 'path'; import { homedir } from 'os'; -import { execSync } from 'child_process'; +import { spawn } from 'child_process'; import chalk from 'chalk'; -import ora from 'ora'; +import { createSpinner } from 'nanospinner'; import { checkbox, confirm } from '@inquirer/prompts'; import { ExitPromptError } from '@inquirer/core'; import { hasValidFrontmatter, extractYamlField } from '../utils/yaml.js'; @@ -97,17 +97,33 @@ export async function installSkill(source: string, options: InstallOptions): Pro mkdirSync(tempDir, { recursive: true }); try { - const spinner = ora('Cloning repository...').start(); + const spinner = createSpinner('Cloning repository...').start(); try { - execSync(`git clone --depth 1 --quiet "${repoUrl}" "${tempDir}/repo"`, { - stdio: 'pipe', + await new Promise((resolve, reject) => { + const gitProcess = spawn('git', ['clone', '--depth', '1', '--quiet', repoUrl, `${tempDir}/repo`], { + stdio: 'pipe', + }); + let stderr = ''; + gitProcess.stderr?.on('data', (data) => { + stderr += data.toString(); + }); + gitProcess.on('close', (code) => { + if (code === 0) { + resolve(); + } else { + reject(new Error(stderr.trim() || `git clone failed with code ${code}`)); + } + }); + gitProcess.on('error', (err) => { + reject(err); + }); }); - spinner.succeed('Repository cloned'); + spinner.success({ text: 'Repository cloned' }); } catch (error) { - spinner.fail('Failed to clone repository'); - const err = error as { stderr?: Buffer }; - if (err.stderr) { - console.error(chalk.dim(err.stderr.toString().trim())); + spinner.error({ text: 'Failed to clone repository' }); + const err = error as Error; + if (err.message) { + console.error(chalk.dim(err.message)); } console.error(chalk.yellow('\nTip: For private repos, ensure git SSH keys or credentials are configured')); process.exit(1); From 5421e1dc732604651a31cbab6acea2e073c57536 Mon Sep 17 00:00:00 2001 From: wangyudong Date: Wed, 31 Dec 2025 12:47:03 +0800 Subject: [PATCH 2/5] feat: Introduce OpenSkills VSCode extension for managing, installing, and syncing skills. --- vscode-extension/.gitignore | 3 + vscode-extension/.vscodeignore | 8 + vscode-extension/LICENSE | 21 ++ vscode-extension/openskills-vscode-0.0.1.vsix | Bin 0 -> 11113 bytes vscode-extension/package-lock.json | 58 +++++ vscode-extension/package.json | 161 ++++++++++++++ vscode-extension/resources/icon.svg | 5 + vscode-extension/src/configManager.ts | 39 ++++ vscode-extension/src/extension.ts | 208 ++++++++++++++++++ vscode-extension/src/gitUtils.ts | 160 ++++++++++++++ vscode-extension/src/skillsProvider.ts | 126 +++++++++++ vscode-extension/src/syncUtils.ts | 125 +++++++++++ vscode-extension/src/types.ts | 14 ++ vscode-extension/tsconfig.json | 17 ++ 14 files changed, 945 insertions(+) create mode 100644 vscode-extension/.gitignore create mode 100644 vscode-extension/.vscodeignore create mode 100644 vscode-extension/LICENSE create mode 100644 vscode-extension/openskills-vscode-0.0.1.vsix create mode 100644 vscode-extension/package-lock.json create mode 100644 vscode-extension/package.json create mode 100644 vscode-extension/resources/icon.svg create mode 100644 vscode-extension/src/configManager.ts create mode 100644 vscode-extension/src/extension.ts create mode 100644 vscode-extension/src/gitUtils.ts create mode 100644 vscode-extension/src/skillsProvider.ts create mode 100644 vscode-extension/src/syncUtils.ts create mode 100644 vscode-extension/src/types.ts create mode 100644 vscode-extension/tsconfig.json diff --git a/vscode-extension/.gitignore b/vscode-extension/.gitignore new file mode 100644 index 0000000..a73617e --- /dev/null +++ b/vscode-extension/.gitignore @@ -0,0 +1,3 @@ +out +node_modules +.vscode-test diff --git a/vscode-extension/.vscodeignore b/vscode-extension/.vscodeignore new file mode 100644 index 0000000..4d4e0cc --- /dev/null +++ b/vscode-extension/.vscodeignore @@ -0,0 +1,8 @@ +.vscode/** +.vscode-test/** +out/test/** +src/** +.gitignore +tsconfig.json +**/*.ts +**/*.map diff --git a/vscode-extension/LICENSE b/vscode-extension/LICENSE new file mode 100644 index 0000000..c13f991 --- /dev/null +++ b/vscode-extension/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vscode-extension/openskills-vscode-0.0.1.vsix b/vscode-extension/openskills-vscode-0.0.1.vsix new file mode 100644 index 0000000000000000000000000000000000000000..a268a43d8027806218392f02fc14d4e4e6fdb698 GIT binary patch literal 11113 zcmb7q1#Dc~lC5KArkI)8j+tX-W{jDk&6qYbGc$9HF>}n!%*-6y@i;TO@8#b2XQW@P zqodO;E$!W1d)4Y%r63Ikjt&9>4GmJOm#vM$6@M`U3Id`F0|J5x0s>;<=44_Eu&}db zZ~<7j*%;bdn3@2b+SR1((3p|=n>u?~uwv4jr@{P&HB|x|RmhO33&jgU`PNe0&JqXH zDPBD4Tivad^(;_|tp`{)IPA1LwD*(fnPRT0COjpRS)GQhcIx;UcXSUBe3J?2ALC$_jD9shU&Li`~Vu}S3Ip8&GzPv6bA!w|Yn$c+~d4!QLyGIUS)A0W8X zaIH$e5$%1t)-_%$NWbO8O;)xt56Z0^OEurzz@?$9;1`NIIsjcO;5TiG2QE;FJ~vN^ zD|Mq!xv4{Vi$PGG-jEO(Y7ohbZxZ#Qnc|7o+y?+>BGlw+F<(Z2fl8$15-Hd2AEspJ z>jqlXPZ=J)&OVcfhJSO|hGdZ{Eb+DM1|c!!$1b=9WEjTek(Yj|>e7NQm)2gIrB+np zMOL$HIObF#55t|QG*C73s;@k(%tbvVOIm&`aJlO-8Biq$(f*R{dq!@juRcbO2&pCJ zq>8a&1eD8HhO`KO#_O^~`~@>9zH^ItxE}1j1|u(s=K(SACEjjvc>r;2V5yjmRm5@y zeotu+H5gGAA>nV@fm4GmY!&>08O0tYod+9hpPB38K8t2h;&7yWEdhQzmCn`Akq$kY> z>>Ro-3=Bjn5l7x%-e}EkIy3wMc0uwzCBk2Ez(o7U$k!jD9xszN)c5x#csPMkO#Nf9 zD7`1${l!C~sL6_9V^^HU_ZHU@o-gHarb&=y-C<6@} zcO0#n7?01NYTdQ%*@HMwZgew5ZyqH&VqG&bt?*+?mX(oCt~g|(%WCCTjHcBbeaEQ# z*_Ej8*CmdS6#jM$I(ND^hu_mb;{yl?+WTGmvz_hxL2%Mnakn=C=rXw3SbN6^$@MZJ zi$3rL?%B+7ngEfdrXlRX7?@blT*LSpS(Has2?FcNpiiDII;%g*(TgfOpbYaa8!c%2 zpWZ+@V4tZT^v3hawr;(a=cFW&jF?Z9?JaR#naL38GW?+L=VF9W`Q8Su-sLMS_%Qhp zJ#MCE%y+nKSiFT{)-3kPPBzwV{hVaJZPl^dvR*-o3`r_=4T2^_zof)j+im|1cK!yE z=F@6y!u*j^Z%1Kspv4T2Ol>JGin+3CpcZJ+$36K+^#h+QzO#-G|Fd=IcLwOv&DMV3 z?Z4u048Uk_Xk=w*X2M_zu(KW0&<$VVME7RA6@dPRL@#ridfr$A6mFeSg8bQEa5^## zA^P26Hj$iImj`Y5JZ=#Wx_q zR*kcWO9TtU56+Bi&8OmPHhhUFNSpxH0zDC@X`oPUB9u=~SdqO@fTKiV8Ic@nj8aW*(ny&9OKTNzn>d#?N=u2(Q8?1yKd%%hD z0GDm^xt{begJ4(Fh!`-M!Gf<>rS#jx*le@NO1qppB2vfW#yrvi$!vZJW9P251qL}f zhj+bW$!VY^DpdBFkBNH#)K_new_hY3r}qO?!ey1v^lz5+F9CYCnwQSOMew3RuYzs# zf`;bG>ZU5-C)*+iDP8z}*R}&2_x#M2lVK)NP$H>nw6Xh1YWb@rw2|mkJTnCr=3G*0 zxHVMYGZ((Lmpbr$@jsk@RJ1y3#H|r?(3sNsG80K4V};s@g&3+A>k29v4|j#Bm>VEf z-hzV^gaN$-{gedK{sIXf{GEHK1G71!OI(2-60uUjf^B`C%k`jhb zhfiTnd6nAIi#<_P#_XeN+qcEnYP)uo!}}sE<#D_2!;Y4E{i13vO2gE+mDlyf1>qV; zp_l6b$6xhEs;(+>lop02-Iarq>q$h@o!L%@s(e}TUy9&3ZTD=tGS5l1Jmk_;({#Ur z2Xzg$tS1=Mea<$ekLNyMt>Tcf^caxr5(4e97~KFr1q;nyvh)r4Xx4H$h&Q`?*V;tb zNw;00Kbw_vaTW2x4!ZO++L03P;A4z2`1gYp*o?&1lc$t4o#7qY695CbyF7}HovAgw zPrg~Z>A669sQ?YQ^{R8~NcX+*>@^*^eQUwJJqLk;cHMDEW_M=nvL8M#RffGA_oQ|A z(JG65C}XJZRPq3~=D~^JJdEkB#$@r-LRdo~dx+fvIb2tJZr zeeRqof?ve+t#N(4U8QFo`K?0nurL$XL(QoM*Xgo-P3$ zwkXw691-aa@N=j5&SD6OvhdpOHBFhH`BngQEHdyIpLWzX9woi}lAVH#?MSq>jw^JM znT3^1PU|Z|zdaU1d9QllG4i%T+Xt{P|1VHTa8tCt@-Csve2RQG)wao%5*WLe_~kIL zDMWlkS;2ZV6w!ohZ*U6IP|#xJPm^>G9I8BL`+jH@C_F53-|%2K`_Z~lT-5G5vk4?uoGJTm zo_#tRm`Zf41`TG&WF38dGFJhF4hufry-mRvY-@{0yTbN90dR+B#z@s}S!vA6480C@ zn7=|A?TXCOi9OhMXvbY(eF6mf1|n^}#Qf*8^=JABQ9QAbUzj`C;ze0q%!My2t@6$$ zpY9#&jI2pu2-Xb1&cE2zme_^#Cu@hV@njPXf5Hd`eLbGMSjZzJ%3lJ|F zO2p4+XCkER_&la3|9DN6ifl>)mDTg`{h84p$i}5tG!?i$o-?jb{O2< zsqlS1Ix}Bk3krYy7IUootrn1VVkl0i>q+m;-}|)F+*CZt(fifEy}^{H8D*?9mckMF z3#-@yJm<4T(u=_Ht99;f$=vj5%0BWZb}hb8KP-(JoIE|_MHuC>%I+wOv4W+~^xeAz z0)ccam-@J4Cpc2Yp&E8H-Qn=U`*V%Rj)8-fKo!VD4Y*!7YzU<`2N*rHm9&#KhWb=j728&EKA{~_}1E%F1W%~woUsaTT6kVCB89xzip;=s(D6$iSbLSK)RA$Z&9Hv9RsB1sN}uQ0@Jy zXmUvoA1xPrY45H(hg|G_?{$2MYBBG9Cr9tszfWuRyO4i><6rUjGH&PW#OU-}#=IAD zi0*D!KS5;3%~pA4>ts;P3rV{eG9k02`A!XH*OXKYa*v0O2@Hr*$*}$95h89WI{cjKrLW*C`d7Gpmio5gMa)m+R^pd@L0}-K$6Faw(w^_IZ*;^hcXw zG3TLpLU4BTbO1AaG3{`QA56W(0}b3RRj3&48?7l5kaX!+b6-Gg&SL79oYGAuAp4b` zq>Vch+5z0ImTn*uu*hH*23#G7B$4zrUMbX;QHig5RWd|x{$X_aRE)ZbU{g#Q^{`WN z)Ti)=FbA>@>4JC2=(N8s6i8QIzX%j$73a=@Rq_r_m4idA!{$3j%p%?9M}M|m^= zR{&30=w}*$Ap=V`anBnum7U*R_f@Fj!jZpGEnfATZ#}5kH1dgMi`teb8Ci28Em7WT z{2rZu4PfJZDSP!VfJ;=r?hn62*FAhEaPGUek{E zsuQ-X({suaeM6N16M{C8{t%{XgVPf)5%P25G|ZF2wz^0@zXFta*9MUMrZ(fQ6Ho9# z@pg~PD<}EBwTxhf#bZBj%Dg=~xgQPYD&I7p%f&aqHq2eGdnopKj>8Md2Jmy1M#=eF zuv+t{TL?(bP1|so@T2wD5KP5WepUe%gqA*Uv2x6mW|pfTYz>MC(j~=982&7{xiyUc zx;0~QsfFVUsA}b{DwZRM&DF^ zvo*6O;pAB=Y6b22-n{ z9V;b0FNXUHhe`)W?r#{rRzf4o#-cKe?xX3tHeSmp=22J9V3U-MQ;)~Pa27s6Xk)0J zT;9fL_7FKR#V&ECO)=<9%wtZLCgCl*3rjB3Ww9`h{6j^|rt7CaPHHaBlGU8n|NKmVI6yeg4k9tI8&UC&D@i2s~S6~wyG=R!ZD$i zr1$=L3+c(x)>8+4pk3_NN0U<1GL&Z44z%U-1YnTd}Fn>uGyIMtr z*z1Kj%L*A{+G#%>PFlK@*VB|dhgF+$vnWsccT3kq?_x-z z4r6UpF;W&acUlZ5ynRlExe)kWNsy_c7C|9FKp>F+uS!DrpOwVQ!rB_3;ArP!VQk{~ zUQQ}C^p#gQk$n%8ty|>IMhm5$UBC)P@dFWOrj61Z9|XBbP8%xKl5`}4m}EMhBaL|) zO`zOL2wCne8+?6RX-%4Dp_i#JQ`cTIJMB7*j3pvq(A=twfy1l8%`^op9ZL|ES> z8N+66MHfm0@x0dZP+N6a%ewQlS6g*bYSg4GMImLC1-sS=<9TiChk{WZ?16@f^+|ln zVlDrJ`CdejuV{J0KO`{ZEYrMY2H0AXw)w)NS!k4A%8)mdKN})~UK|s}>}aF!bD9n0 zz*0WHp6#?YNl};wy0fr3M!*jwUNu}pqybsH8S{e9Lc~5Ix-Xoo8|EpPeYP7RDT2i6 z$N&~8uAt%GXJw&}<(YZO=L;*-d`MPbqel@hE0dK8%ME-rKpx~*vBVPC_AWUa2^rrT zfoc*#$GjH4x?9)#jKVf}H;wjKts>wgMEXKf_z{pd(4*VC(2*%YkUt%~dp$NsOpQSr z%3n-z!f=W=u9ysLL4cNEiONa?l(3HrXX(rYurn|(dwnzvqfP0p_=3pz#?$=M+wrn;nORz!4-a8?Rzy?!`v|r;^k;Dw zW#WE}ZVWNQvoT{(#(e;?Nv9BRoEgqwV%tcQdLLC%aD3Fa6GL4Ua~#GnoJMUG6BXA+ z_sSmjRb_wo5In$%q6I1ZIpxA1*Z*$-BKci(|08r|fKpXK6l z04;NuUI)VxAtf}X^S&WX3noeiB-)#3K44dyEz^9SK>(K+KDF9nD#*XgG#C#r=tKi|wc6KcglD3K z=1=&DAB>*N(@bXMAibN?F(-1QL?D>$d?P0)Io?=!y^?wsn9{rT$#C<_eoNzC>J~wXZ&^dR=+qEk)iSDzto5RpFoaX59hY7r%&i!QFz zg)oQhkKVAxN3c?CqqtOLO1rL=`wH#!4W?Re?#G>HiqTmJP04&U+P>ckR`a=c%g+ql>Kd&8rUOS0!8t9{wnn0i(b# zE01oq-qwrxBYOG6E}cF;*`9%iizm7dKNKHU2+~glC$|j7?;W2afM)&Hbk$LH-ZOKr z(1^$5GpntK_$F&B6i*7Bar@)B@(H7rRW+wb?LZ*Roa(k-rP|fYchMu9g4hj zs>8c%K4}fcCfwtuw>xMSNRE-adja;J0k4@$ryP@YDkxb~c?KlykJlDeo-(_w6kPPb zpnfy*YpKDsCg93dEEo+eY8KiO4nMWLq_%;Cmm5>w0#sTCn(CXMIeNBjz%eUWeAh zn=WFO*m^Uhy-HO>ml;Uf=o1?$fUhIcY!j+#Fst&Lh*hN}m&g@W$Vpem)hIIAj?c@E zh6b<;VP=;Gb%P0Pm>Mw3laHSLpTwT6$38k$D zWliUYS5vNo$s0azutj>}Kjj=gQpYdnjW$PZgNM*4rakCDvwmlnG2#4@Fc#Yv&zJT2 zR?=3fZEqlLCeV0F$_TG_jQ~W@c6!@;;Ld*8U6QoCerv&7p8nxlie)4bysaUP<(Zbg z4@NvzR7Nsh$a-SWHJJYme_rr<^WV35}D2q57yU|L^_j>_a> z$cQA>l@3rjV_13297cBQDHSH+51tp^OAu?>#n3xneG|LT8`QYJbLZ+9K&k;Z2YOa0 z-w1 znb6tKL?I0MnP9B3-17WX!%su2)RJPI(th;p!Z~K4`EjD40b8@*GWk>b;8OxzLgR#^ zoI6utdcBoR7QFKLVKMH!nj1# zd~gKSn3+yo_$SYv+|Fc6cJX^XRhLBM6KgL4 z+^alC#%fr`&&6c&-0n(v3CxY}1v|4_pwC`gon9&7 z2CYYKy{vAa4Lq!MQF~VQ=T=`nXl2=1Na@06+zoP(gQ zTi$f`zE#{AXnR;Jo)$;1^)7%8?Tvm?x3^Drz_-kAl}%a`nfNXUz{tOs2cXF2F;EJe_31mxWF@8_CZhN>H8)XuvIeg~UH4S2h z-x%+PLl@44XagVNEPJ!-d5HduTWxy9(b?M=(RW<|{<`G1rb!=Th2&hj(zA)7b+;F4 zY*mY(2@6d}F3;EFC8v3r;){r9g=?(erG?f<#UA}#>@UA}o&SH@M*nIez3col&41OF zu`mhYPerdd6S!#q;c_kl@jcaoyA`7;$OW&Ra+cg-IGCAqF4N^K6QKNU) z02A#o>thIhwP~!aJj+jK$E+;UBoQrrtd%UYF6TQoMfIPEPknv{?2CxDbgdzuZw7_o zA$1+&8KOkE&YDjOCDLEr4(!XJfFU|{$I!HignBnCu;!HyAlNM614IsuU+`NF+b;bTYlU5< zvDMw;KPJbfp%lexRRnv>n^28V3nc05X_RjBtC12YN}tFgdT0emON#A5z#88N47(4d ze6dz6Rb7&l@i9r+PyO5-L&p)iG56^6G)z=9oiO|ZIa1k{?pS>F+b3}g(*^(=SNXNI9m)AOPeiv%GqB4LIVG6D-=QX9bz!ERSGjL*-tn#tdrgWUuNBJ zbF$P%I?5q`l-BX??|p7&*>I$-ssB1ceOS01fNZClp*W-f?XgGEuY!FVLO0)1Yh}o& z7^8l6kcJ8&n4gF-e^o`h1nH?5IN{Pan^J~*>Zn`>4fRwywcBHxbC|6n%}`AFejM@y zxER&!x)J0rR*yxd(Xl#ZgfD*yCkwSH@7;wc+p!ZQ3-{73M>rVi8lr3V|MbZq3@%S~ z7>WBVOD;|D^;DHO#1x?sH*d#^BtI%_!CZ5DJ5SB%6Aima-+=j~Ie?xvKaECWT}5CB zz0xSOzt{4DSpF`4SVNe0;Bu!q%{hzSfRK;SeeF5EbobG0K^h>u7_&@i(o%u$uW=;D1e|cJR9yD|=}i8( z2j_+|z=k!i4IbZ+GLIubF@8;#*NAIYg-iE|)4WT=tN3ulk@$SfVnbk(!mI_EVSG7? zG(e_9wxSZL4ktRvRSR7c&HRDKtVBFCQ4S6~Ni?T-I*uA8Rb|9FQ~e;W@+=Q8GJ95v z+S`U@SgTVHE7rJi49yI*RLEWmByi6X8EZsnw4qjeH`tfBQ-72kQ2z~9uY-%fy^YA? z_Dsnu_42$6MyD)UIbl9Sq(-BtgSAr0HpZMyYBh%tIX&lgq~W+XM*Mya6hgl}C)l*5 zAN41o(E22&ZhnR^%a^QWpN!pXmg2KC15aAjwU1eO7KmjY4edUi-4Ux zC!n35`20Y{w3$s^or?Sv0XO_${~5|tMe}Ww3>C3k08Ec!g zR`l0i`AJq+@Ry};x#-j1R~(3y$9{GRR1siVg@^K3TAXYMVO&EoxqGP7DK>@5UvTpJ zV}-w}uKEv21W-T#r11i)z~RZ*ocP?vIho( z-|Y(TEeC>QnG@{|a8@Pi0^pE9lRXes?Rxi|mQvuq8nlc$I6Ku|Q?Qe@M>R9h(bR-B zyR1A(BZDmvS{b*nzZ7{JegAI9E>OJ}LzKxR~ zX^1c$Q-t-Q)HIzDENQr+72!~wzD+bqTW3Ys=MIHb7>M~+o>*Of-l=w=_3*&GwvBUA zB4~t`PdrZpk#4`ERQo()%$jY5pGEi7HWhH8*$@^s$G}Gu|5?E zA#UDG)v6!~LMDo}u9_}9(~fqgvviTQoX^-42lg3VTBjQ%OS>tth`GnxeSwnw4z zxBX7!13qcEQYkOHiJ{hH|LIjchscWN0(^DA!~HN}!6yx)ZQcbB{M)E4-8op?pTDfV zj)IyTjdq&lN_D@8u18jUqo)Yv10hyRzlfeKKlYZhO&nW&wPC)>_Q)#gc)ODD8883h`gH5 zW2-v%VkawH`tN4hQ%jEN<9q$Q$N#_TC&7RGHG6l$OfAf04Q=0tK7RMg8dPNMW|@%N z57cFPi9^xb?8#yAIEl#AaxgN=${gb*=PMW3S??R?T;6yb>j*WMVHwhuUsx{225~77 zBD%6vc4lavd;sB*SoAK#n@DwtLjwDcn{@6B#O)noSu5=3GSZ7(TE|}ryOaeNF;(l} z(6cL#R0NX6?j;m@m&-8MRV9rOJT(AD+5tGwzEGkm#iVhVs?+8}@Wn5(pdej(9&>`x zKEQEDz0=Fbi0@-vVMmZ$4t7UTnbr!ohvGwm)3jFCqugv>#r69YC5YSs{4q-~qH0-+ zGDU6Vff*Q=x8TX@q=r27(%1PGf{iwG3`hkNit8n;D&U_U3%@wv4Km9(#~=y$oxuY9 zev-yO7vxr1g*3>9^W1x@EE24nvTAG&SD}bh^V%PB-+@fmBV!N!zz{ZrakCgA6#_@p ziSz+6kf2$#*t@Y#!syXV#>xiIovG{Q4PVxTS>oIj^stn)?t{?VPk$`LBX5fL*=tvM zz6#saI=W)q7*;G=js9i4EI@vD*pFpnSHPfm=YqbzqJ2K@g_ymw`RnL9MJ5%KFsK}T zaF%+;C-R4MQ8vR5iMA3ex949^+?*rHpZhRoYd#S7q0^GqoDeq7!92j5;vu+qW8yU4 zWHg<3t}a5IdQTEqSoZX@qK(%ztf>2TQy$Qyj;({N2qKIZ0)}rpF*lA)aY$`7D+->$ zeoM1sPlh+7cdwP`J-rm9KY$8={qLiM@A>uLQ4jom`?omzbFlEA82_BZ`X2-kka{50 z`;5Z>V=C(}fWM}h{v2ocZG-+51whbud-z|A_}gsLpBTRfAO19ye-A$V6^%e#=sz+3 z7=!p5#JltSr%(IadHyRJforgTLj0!>{U_3IU-wTB_0J780*B!KMEcX^{U^qs-SgjW z>tE3bbcO#X#-HBnKXLx-`TXv+{}qkEZq)z4`Df?-pJ0Eg{NHV&zoHSSjQvlrKbl7W zg!z-~{=T=WcZU1-5B~f6`Pb7sx&0I8&&>W!jekWW@SOagIR7L{1!;))^8f+@_x^%? L&r?aN-%tMqx->(B literal 0 HcmV?d00001 diff --git a/vscode-extension/package-lock.json b/vscode-extension/package-lock.json new file mode 100644 index 0000000..ab8ac4e --- /dev/null +++ b/vscode-extension/package-lock.json @@ -0,0 +1,58 @@ +{ + "name": "openskills-vscode", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "openskills-vscode", + "version": "0.0.1", + "devDependencies": { + "@types/node": "^20.0.0", + "@types/vscode": "^1.96.0", + "typescript": "^5.0.0" + }, + "engines": { + "vscode": "^1.96.0" + } + }, + "node_modules/@types/node": { + "version": "20.19.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.27.tgz", + "integrity": "sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/vscode": { + "version": "1.107.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.107.0.tgz", + "integrity": "sha512-XS8YE1jlyTIowP64+HoN30OlC1H9xqSlq1eoLZUgFEC8oUTO6euYZxti1xRiLSfZocs4qytTzR6xCBYtioQTCg==", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/vscode-extension/package.json b/vscode-extension/package.json new file mode 100644 index 0000000..4f0b6aa --- /dev/null +++ b/vscode-extension/package.json @@ -0,0 +1,161 @@ +{ + "name": "openskills-vscode", + "displayName": "OpenSkills VSCode", + "description": "Manage, install, and sync OpenSkills (Claude Code compatible skills) from VSCode.", + "version": "0.0.1", + "publisher": "openskills", + "repository": { + "type": "git", + "url": "https://github.com/whyuds/openskills" + }, + "license": "MIT", + "engines": { + "vscode": "^1.96.0" + }, + "categories": [ + "Other" + ], + "activationEvents": [], + "main": "./out/extension.js", + "contributes": { + "configuration": { + "title": "OpenSkills", + "properties": { + "openskills.repositories": { + "type": "array", + "default": [], + "description": "List of Git repositories containing skills.", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "name": { + "type": "string" + }, + "branch": { + "type": "string" + } + } + } + } + } + }, + "commands": [ + { + "command": "openskills.addRepo", + "title": "Add Skill Repository", + "icon": "$(add)" + }, + { + "command": "openskills.refresh", + "title": "Refresh Skills", + "icon": "$(refresh)" + }, + { + "command": "openskills.removeRepo", + "title": "Remove Repository", + "icon": "$(trash)" + }, + { + "command": "openskills.installSelected", + "title": "Install Selected Skills", + "icon": "$(cloud-download)" + }, + { + "command": "openskills.deleteSelected", + "title": "Delete Selected Skills", + "icon": "$(trash)" + }, + { + "command": "openskills.sync", + "title": "Sync to AGENTS.md", + "icon": "$(sync)" + }, + { + "command": "openskills.switchBranch", + "title": "Switch Branch", + "icon": "$(git-branch)" + }, + { + "command": "openskills.pullRepo", + "title": "Pull Latest", + "icon": "$(repo-sync)" + } + ], + "viewsContainers": { + "activitybar": [ + { + "id": "openskills-explorer", + "title": "OpenSkills", + "icon": "resources/icon.svg" + } + ] + }, + "views": { + "openskills-explorer": [ + { + "id": "openskills-skills", + "name": "Skills" + } + ] + }, + "menus": { + "view/title": [ + { + "command": "openskills.addRepo", + "when": "view == openskills-skills", + "group": "navigation@1" + }, + { + "command": "openskills.installSelected", + "when": "view == openskills-skills", + "group": "navigation@2" + }, + { + "command": "openskills.deleteSelected", + "when": "view == openskills-skills", + "group": "navigation@3" + }, + { + "command": "openskills.sync", + "when": "view == openskills-skills", + "group": "navigation@4" + }, + { + "command": "openskills.refresh", + "when": "view == openskills-skills", + "group": "navigation@5" + } + ], + "view/item/context": [ + { + "command": "openskills.pullRepo", + "when": "viewItem == skillRepo", + "group": "inline" + }, + { + "command": "openskills.switchBranch", + "when": "viewItem == skillRepo", + "group": "inline" + }, + { + "command": "openskills.removeRepo", + "when": "viewItem == skillRepo", + "group": "inline" + } + ] + } + }, + "scripts": { + "vscode:prepublish": "npm run compile", + "compile": "tsc -p ./", + "watch": "tsc -watch -p ./" + }, + "devDependencies": { + "@types/node": "^20.0.0", + "@types/vscode": "^1.96.0", + "typescript": "^5.0.0" + } +} \ No newline at end of file diff --git a/vscode-extension/resources/icon.svg b/vscode-extension/resources/icon.svg new file mode 100644 index 0000000..93762b8 --- /dev/null +++ b/vscode-extension/resources/icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/vscode-extension/src/configManager.ts b/vscode-extension/src/configManager.ts new file mode 100644 index 0000000..0132019 --- /dev/null +++ b/vscode-extension/src/configManager.ts @@ -0,0 +1,39 @@ +import * as vscode from 'vscode'; +import { SkillRepo } from './types'; + +export class ConfigManager { + static getRepos(): SkillRepo[] { + const config = vscode.workspace.getConfiguration('openskills'); + return config.get('repositories') || []; + } + + static async addRepo(url: string) { + const config = vscode.workspace.getConfiguration('openskills'); + const repos = this.getRepos(); + if (repos.some(r => r.url === url)) { + return; + } + + // Remove .git suffix and username for shorter name + let name = url.split('/').pop()?.replace('.git', '') || url; + repos.push({ url, name }); + await config.update('repositories', repos, vscode.ConfigurationTarget.Global); + } + + static async updateRepo(url: string, updates: Partial) { + const config = vscode.workspace.getConfiguration('openskills'); + let repos = this.getRepos(); + const index = repos.findIndex(r => r.url === url); + if (index !== -1) { + repos[index] = { ...repos[index], ...updates }; + await config.update('repositories', repos, vscode.ConfigurationTarget.Global); + } + } + + static async removeRepo(url: string) { + const config = vscode.workspace.getConfiguration('openskills'); + let repos = this.getRepos(); + repos = repos.filter(r => r.url !== url); + await config.update('repositories', repos, vscode.ConfigurationTarget.Global); + } +} diff --git a/vscode-extension/src/extension.ts b/vscode-extension/src/extension.ts new file mode 100644 index 0000000..f035f56 --- /dev/null +++ b/vscode-extension/src/extension.ts @@ -0,0 +1,208 @@ +import * as vscode from 'vscode'; +import * as path from 'path'; +import * as fs from 'fs'; +import * as cp from 'child_process'; +import { SkillsProvider } from './skillsProvider'; +import { ConfigManager } from './configManager'; +import { GitUtils } from './gitUtils'; +import { Skill, SkillRepo } from './types'; + +let skillsTreeView: vscode.TreeView; + +export function activate(context: vscode.ExtensionContext) { + const skillsProvider = new SkillsProvider(); + + skillsTreeView = vscode.window.createTreeView('openskills-skills', { + treeDataProvider: skillsProvider, + canSelectMany: true + }); + + context.subscriptions.push(skillsTreeView); + + context.subscriptions.push( + vscode.commands.registerCommand('openskills.refresh', () => skillsProvider.refresh()), + + vscode.commands.registerCommand('openskills.addRepo', async () => { + const url = await vscode.window.showInputBox({ + placeHolder: 'Enter Git Repository URL (e.g., https://github.com/anthropics/skills)', + prompt: 'Add a new Skill Repository' + }); + if (url) { + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: 'Adding repository...', + cancellable: false + }, async () => { + await ConfigManager.addRepo(url); + skillsProvider.refresh(); + }); + } + }), + + vscode.commands.registerCommand('openskills.removeRepo', async (node: SkillRepo) => { + const result = await vscode.window.showWarningMessage(`Remove repository ${node.name}?`, 'Yes', 'No'); + if (result === 'Yes') { + await ConfigManager.removeRepo(node.url); + skillsProvider.refresh(); + } + }), + + vscode.commands.registerCommand('openskills.switchBranch', async (node: SkillRepo) => { + const branches = await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: 'Fetching branches...', + cancellable: false + }, async () => { + return await GitUtils.getRemoteBranches(node.url); + }); + + if (branches.length === 0) { + vscode.window.showErrorMessage('Could not list branches or no branches found.'); + return; + } + + const selected = await vscode.window.showQuickPick(branches, { + placeHolder: `Select branch for ${node.name} (current: ${node.branch || 'default'})` + }); + + if (selected) { + await ConfigManager.updateRepo(node.url, { branch: selected }); + skillsProvider.refresh(); + } + }), + + vscode.commands.registerCommand('openskills.pullRepo', async (node: SkillRepo) => { + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: `Pulling ${node.name}...`, + cancellable: false + }, async () => { + await GitUtils.pullRepo(node.url, node.branch); + }); + skillsProvider.refresh(); + vscode.window.showInformationMessage(`${node.name} updated.`); + }), + + vscode.commands.registerCommand('openskills.sync', async () => { + if (!vscode.workspace.workspaceFolders) { + vscode.window.showErrorMessage('Please open a workspace folder first.'); + return; + } + + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: 'Syncing to AGENTS.md...', + cancellable: false + }, async () => { + const { syncToAgentsMd } = await import('./syncUtils'); + const workspaceRoot = vscode.workspace.workspaceFolders![0].uri.fsPath; + const result = syncToAgentsMd(workspaceRoot); + + if (result.success) { + vscode.window.showInformationMessage(result.message); + } else { + vscode.window.showErrorMessage(result.message); + } + }); + }), + + vscode.commands.registerCommand('openskills.installSelected', async () => { + const selected = skillsTreeView.selection.filter(item => !('url' in item)) as Skill[]; + + if (selected.length === 0) { + vscode.window.showWarningMessage('Please select skills to install (use checkboxes).'); + return; + } + + if (!vscode.workspace.workspaceFolders) { + vscode.window.showErrorMessage('Please open a workspace folder first.'); + return; + } + + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: `Installing ${selected.length} skill(s)...`, + cancellable: false + }, async (progress) => { + const targetBase = path.join(vscode.workspace.workspaceFolders![0].uri.fsPath, '.agent', 'skills'); + + for (let i = 0; i < selected.length; i++) { + const skill = selected[i]; + progress.report({ message: `${skill.name} (${i + 1}/${selected.length})` }); + + const targetDir = path.join(targetBase, skill.name); + + if (!skill.localPath || !fs.existsSync(skill.localPath)) { + vscode.window.showWarningMessage(`Source files missing for ${skill.name}. Try refreshing.`); + continue; + } + + fs.mkdirSync(path.dirname(targetDir), { recursive: true }); + copyRecursiveSync(skill.localPath, targetDir); + } + }); + + skillsProvider.refresh(); + + const syncNow = await vscode.window.showInformationMessage( + `Installed ${selected.length} skill(s). Sync AGENTS.md now?`, + 'Yes', 'No' + ); + if (syncNow === 'Yes') { + vscode.commands.executeCommand('openskills.sync'); + } + }), + + vscode.commands.registerCommand('openskills.deleteSelected', async () => { + const selected = skillsTreeView.selection.filter(item => !('url' in item)) as Skill[]; + + if (selected.length === 0) { + vscode.window.showWarningMessage('Please select skills to delete.'); + return; + } + + if (!vscode.workspace.workspaceFolders) { + vscode.window.showErrorMessage('Please open a workspace folder first.'); + return; + } + + const confirm = await vscode.window.showWarningMessage( + `Delete ${selected.length} skill(s) from this project?`, + 'Yes', 'No' + ); + + if (confirm !== 'Yes') return; + + const targetBase = path.join(vscode.workspace.workspaceFolders[0].uri.fsPath, '.agent', 'skills'); + + for (const skill of selected) { + const targetDir = path.join(targetBase, skill.name); + if (fs.existsSync(targetDir)) { + fs.rmSync(targetDir, { recursive: true, force: true }); + } + } + + skillsProvider.refresh(); + vscode.window.showInformationMessage(`Deleted ${selected.length} skill(s).`); + }) + ); +} + +function copyRecursiveSync(src: string, dest: string) { + const exists = fs.existsSync(src); + const stats = exists && fs.statSync(src); + const isDirectory = stats && stats.isDirectory(); + if (isDirectory) { + if (fs.existsSync(dest)) { + fs.rmSync(dest, { recursive: true, force: true }); + } + fs.mkdirSync(dest, { recursive: true }); + fs.readdirSync(src).forEach((childItemName) => { + copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName)); + }); + } else { + fs.copyFileSync(src, dest); + } +} + +export function deactivate() { } diff --git a/vscode-extension/src/gitUtils.ts b/vscode-extension/src/gitUtils.ts new file mode 100644 index 0000000..d1fc5e0 --- /dev/null +++ b/vscode-extension/src/gitUtils.ts @@ -0,0 +1,160 @@ +import * as cp from 'child_process'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as os from 'os'; +import { Skill } from './types'; + +const CACHE_DIR = path.join(os.tmpdir(), 'openskills-vscode-cache'); + +if (!fs.existsSync(CACHE_DIR)) { + fs.mkdirSync(CACHE_DIR, { recursive: true }); +} + +function extractYamlField(content: string, field: string): string { + const match = content.match(new RegExp(`^${field}:\\s*(.+?)$`, 'm')); + return match ? match[1].trim() : ''; +} + +function hasValidFrontmatter(content: string): boolean { + return content.trim().startsWith('---'); +} + +export class GitUtils { + static getRepoPath(url: string): string { + const dirName = Buffer.from(url).toString('base64').replace(/[^a-zA-Z0-9]/g, ''); + return path.join(CACHE_DIR, dirName); + } + + static isRepoCloned(url: string): boolean { + const repoPath = this.getRepoPath(url); + return fs.existsSync(path.join(repoPath, '.git')); + } + + static async getRemoteBranches(url: string): Promise { + try { + const output = await this.execGitOutput(['ls-remote', '--heads', url]); + return output.split('\n') + .filter(line => line.trim()) + .map(line => { + const parts = line.split('\t'); + return parts[1].replace('refs/heads/', ''); + }); + } catch (e) { + console.error(`Failed to list branches for ${url}`, e); + return []; + } + } + + // Only clone if not exists, no pull + static async ensureRepoCloned(url: string, branch?: string): Promise { + const repoPath = this.getRepoPath(url); + + if (!fs.existsSync(path.join(repoPath, '.git'))) { + if (fs.existsSync(repoPath)) { + fs.rmSync(repoPath, { recursive: true, force: true }); + } + const dirName = path.basename(repoPath); + const args = ['clone', '--depth', '1', url, dirName]; + if (branch) { + args.push('--branch', branch); + } + await this.execGitSilent(CACHE_DIR, args); + } + return repoPath; + } + + // Explicit pull operation + static async pullRepo(url: string, branch?: string): Promise { + const repoPath = this.getRepoPath(url); + + if (!fs.existsSync(path.join(repoPath, '.git'))) { + await this.ensureRepoCloned(url, branch); + return; + } + + await this.execGitSilent(repoPath, ['fetch', 'origin']); + if (branch) { + await this.execGitSilent(repoPath, ['checkout', branch]); + await this.execGitSilent(repoPath, ['pull', 'origin', branch]); + } else { + await this.execGitSilent(repoPath, ['pull']); + } + } + + // Scan skills from local cache only + static scanSkillsFromCache(url: string): Skill[] { + const repoPath = this.getRepoPath(url); + const skills: Skill[] = []; + + if (!fs.existsSync(repoPath)) { + return skills; + } + + const findSkills = (dir: string) => { + try { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + for (const entry of entries) { + if (entry.name.startsWith('.')) continue; + + const fullPath = path.join(dir, entry.name); + if (entry.isDirectory()) { + if (fs.existsSync(path.join(fullPath, 'SKILL.md'))) { + const content = fs.readFileSync(path.join(fullPath, 'SKILL.md'), 'utf-8'); + if (hasValidFrontmatter(content)) { + skills.push({ + name: extractYamlField(content, 'name') || entry.name, + description: extractYamlField(content, 'description'), + path: path.relative(repoPath, fullPath).replace(/\\/g, '/'), + repoUrl: url, + localPath: fullPath + }); + } + } else { + findSkills(fullPath); + } + } + } + } catch (e) { + console.error(`Error scanning dir ${dir}`, e); + } + }; + + findSkills(repoPath); + return skills; + } + + // Clone if needed, then scan (for initial load) + static async getSkillsFromRepo(url: string, branch?: string): Promise { + await this.ensureRepoCloned(url, branch); + return this.scanSkillsFromCache(url); + } + + private static execGitOutput(args: string[]): Promise { + return new Promise((resolve, reject) => { + cp.execFile('git', args, { + windowsHide: true + }, (error, stdout, stderr) => { + if (error) { + reject(new Error(`Git command failed: ${stderr || error.message}`)); + } else { + resolve(stdout); + } + }); + }); + } + + private static execGitSilent(cwd: string, args: string[]): Promise { + return new Promise((resolve, reject) => { + cp.execFile('git', args, { + cwd, + windowsHide: true + }, (error, _stdout, stderr) => { + if (error) { + reject(new Error(`Git command failed: ${stderr || error.message}`)); + } else { + resolve(); + } + }); + }); + } +} diff --git a/vscode-extension/src/skillsProvider.ts b/vscode-extension/src/skillsProvider.ts new file mode 100644 index 0000000..0f2db03 --- /dev/null +++ b/vscode-extension/src/skillsProvider.ts @@ -0,0 +1,126 @@ +import * as vscode from 'vscode'; +import * as fs from 'fs'; +import * as path from 'path'; +import { ConfigManager } from './configManager'; +import { GitUtils } from './gitUtils'; +import { Skill, SkillRepo } from './types'; + +export class SkillsProvider implements vscode.TreeDataProvider { + private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); + readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; + + private selectedSkills: Set = new Set(); + private syncedSkillsCache: Set = new Set(); + + refresh(): void { + this.updateSyncedSkillsCache(); + this._onDidChangeTreeData.fire(); + } + + getSelectedSkills(): Skill[] { + return []; + } + + clearSelection(): void { + this.selectedSkills.clear(); + } + + private getSkillKey(skill: Skill): string { + return `${skill.repoUrl}::${skill.name}`; + } + + private getWorkspaceRoot(): string | undefined { + return vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; + } + + private getInstalledSkillsDir(): string | undefined { + const root = this.getWorkspaceRoot(); + if (!root) return undefined; + return path.join(root, '.agent', 'skills'); + } + + private isSkillInstalled(skillName: string): boolean { + const dir = this.getInstalledSkillsDir(); + if (!dir) return false; + return fs.existsSync(path.join(dir, skillName, 'SKILL.md')); + } + + private updateSyncedSkillsCache(): void { + this.syncedSkillsCache.clear(); + const root = this.getWorkspaceRoot(); + if (!root) return; + + const agentsPath = path.join(root, 'AGENTS.md'); + if (!fs.existsSync(agentsPath)) return; + + const content = fs.readFileSync(agentsPath, 'utf-8'); + // Parse skill names from xxx tags + const regex = /([^<]+)<\/name>/g; + let match; + while ((match = regex.exec(content)) !== null) { + this.syncedSkillsCache.add(match[1].trim()); + } + } + + private isSkillSynced(skillName: string): boolean { + return this.syncedSkillsCache.has(skillName); + } + + getTreeItem(element: SkillRepo | Skill): vscode.TreeItem { + if ('url' in element) { + // It's a Repo + const item = new vscode.TreeItem(element.name, vscode.TreeItemCollapsibleState.Collapsed); + item.contextValue = 'skillRepo'; + item.description = element.branch ? `[${element.branch}]` : ''; + item.tooltip = element.url; + item.iconPath = new vscode.ThemeIcon('repo'); + return item; + } else { + // It's a Skill + const installed = this.isSkillInstalled(element.name); + const synced = this.isSkillSynced(element.name); + const item = new vscode.TreeItem(element.name, vscode.TreeItemCollapsibleState.None); + + // Build status string + const status: string[] = []; + if (installed) status.push('Installed'); + if (synced) status.push('Synced'); + + item.contextValue = installed ? 'skillInstalled' : 'skill'; + item.description = status.length > 0 ? `[${status.join(', ')}]` : element.description; + item.tooltip = `${element.name}\n${element.description}\n${element.path}`; + + // Icon based on status + let iconName = 'tools'; + if (installed && synced) { + iconName = 'pass-filled'; + } else if (installed) { + iconName = 'check'; + } + item.iconPath = new vscode.ThemeIcon(iconName); + item.checkboxState = vscode.TreeItemCheckboxState.Unchecked; + return item; + } + } + + async getChildren(element?: SkillRepo | Skill): Promise<(SkillRepo | Skill)[]> { + if (!element) { + // Root: return repos + this.updateSyncedSkillsCache(); + return ConfigManager.getRepos(); + } else if ('url' in element) { + // Repo: return skills + try { + const skills = await GitUtils.getSkillsFromRepo(element.url, element.branch); + skills.forEach(s => { + s.installed = this.isSkillInstalled(s.name); + }); + return skills; + } catch (e) { + vscode.window.showErrorMessage(`Failed to load skills from ${element.name}: ${e}`); + return []; + } + } + return []; + } +} diff --git a/vscode-extension/src/syncUtils.ts b/vscode-extension/src/syncUtils.ts new file mode 100644 index 0000000..18f1626 --- /dev/null +++ b/vscode-extension/src/syncUtils.ts @@ -0,0 +1,125 @@ +import * as fs from 'fs'; +import * as path from 'path'; + +interface InstalledSkill { + name: string; + description: string; + location: 'project' | 'global'; + path: string; +} + +function extractYamlField(content: string, field: string): string { + const match = content.match(new RegExp(`^${field}:\\s*(.+?)$`, 'm')); + return match ? match[1].trim() : ''; +} + +export function findInstalledSkills(workspaceRoot: string): InstalledSkill[] { + const skills: InstalledSkill[] = []; + const dirs = [ + path.join(workspaceRoot, '.agent', 'skills'), // Universal (priority) + path.join(workspaceRoot, '.claude', 'skills') // Claude-specific (fallback) + ]; + + for (const dir of dirs) { + if (!fs.existsSync(dir)) continue; + + const entries = fs.readdirSync(dir, { withFileTypes: true }); + for (const entry of entries) { + if (entry.isDirectory() || entry.isSymbolicLink()) { + const skillPath = path.join(dir, entry.name, 'SKILL.md'); + if (fs.existsSync(skillPath)) { + const content = fs.readFileSync(skillPath, 'utf-8'); + skills.push({ + name: entry.name, + description: extractYamlField(content, 'description'), + location: 'project', + path: path.join(dir, entry.name) + }); + } + } + } + } + + return skills; +} + +export function generateSkillsXml(skills: InstalledSkill[]): string { + const skillTags = skills + .map(s => ` +${s.name} +${s.description} +${s.location} +`) + .join('\n\n'); + + return ` + +## Available Skills + + + +When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge. + +How to use skills: +- Invoke: Bash("npx openskills read ") +- The skill content will load with detailed instructions on how to complete the task +- Base directory provided in output for resolving bundled resources (references/, scripts/, assets/) + +Usage notes: +- Only use skills listed in below +- Do not invoke a skill that is already loaded in your context +- Each skill invocation is stateless + + + + +${skillTags} + + + + +`; +} + +export function replaceSkillsSection(content: string, newSection: string): string { + const startMarker = ']*>[\s\S]*?<\/skills_system>/; + return content.replace(regex, newSection); + } + + const htmlStartMarker = ''; + const htmlEndMarker = ''; + + if (content.includes(htmlStartMarker)) { + const innerContent = newSection.replace(/]*>|<\/skills_system>/g, ''); + const regex = new RegExp(`${htmlStartMarker}[\\s\\S]*?${htmlEndMarker}`, 'g'); + return content.replace(regex, `${htmlStartMarker}\n${innerContent}\n${htmlEndMarker}`); + } + + return content.trimEnd() + '\n\n' + newSection + '\n'; +} + +export function syncToAgentsMd(workspaceRoot: string): { success: boolean; message: string; count: number } { + const outputPath = path.join(workspaceRoot, 'AGENTS.md'); + + // Create file if it doesn't exist + if (!fs.existsSync(outputPath)) { + fs.writeFileSync(outputPath, '# AGENTS\n\n'); + } + + const skills = findInstalledSkills(workspaceRoot); + + if (skills.length === 0) { + return { success: true, message: 'No skills installed.', count: 0 }; + } + + const xml = generateSkillsXml(skills); + const content = fs.readFileSync(outputPath, 'utf-8'); + const updated = replaceSkillsSection(content, xml); + + fs.writeFileSync(outputPath, updated); + + return { success: true, message: `Synced ${skills.length} skill(s) to AGENTS.md`, count: skills.length }; +} diff --git a/vscode-extension/src/types.ts b/vscode-extension/src/types.ts new file mode 100644 index 0000000..4c17fed --- /dev/null +++ b/vscode-extension/src/types.ts @@ -0,0 +1,14 @@ +export interface Skill { + name: string; + description: string; + path: string; // Relative path in the repo + repoUrl: string; + localPath?: string; // If locally cloned + installed?: boolean; // Whether installed in current workspace +} + +export interface SkillRepo { + url: string; + name: string; // User friendly name or derived from URL + branch?: string; +} diff --git a/vscode-extension/tsconfig.json b/vscode-extension/tsconfig.json new file mode 100644 index 0000000..eea8477 --- /dev/null +++ b/vscode-extension/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es2020", + "outDir": "out", + "lib": [ + "es2020" + ], + "sourceMap": true, + "rootDir": "src", + "strict": true + }, + "exclude": [ + "node_modules", + ".vscode-test" + ] +} \ No newline at end of file From c0110c18acdc1c24f99eb125641670453569664d Mon Sep 17 00:00:00 2001 From: wangyudong Date: Wed, 31 Dec 2025 17:14:22 +0800 Subject: [PATCH 3/5] feat: add VSCode extension for OpenSkills management and synchronization. --- package.json | 10 +- src/index.ts | 26 + tsup.config.ts | 4 +- vscode-extension/.vscodeignore | 18 +- vscode-extension/esbuild.js | 30 + vscode-extension/openskills-vscode-0.0.1.vsix | Bin 11113 -> 21135 bytes vscode-extension/package-lock.json | 2563 ++++++++++++++++- vscode-extension/package.json | 14 +- vscode-extension/src/extension.ts | 18 +- vscode-extension/src/gitUtils.ts | 10 +- vscode-extension/src/skillsProvider.ts | 37 +- vscode-extension/src/syncUtils.ts | 87 +- 12 files changed, 2711 insertions(+), 106 deletions(-) create mode 100644 src/index.ts create mode 100644 vscode-extension/esbuild.js diff --git a/package.json b/package.json index e661d8c..609d415 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,15 @@ "version": "1.3.0", "description": "Universal skills loader for AI coding agents - install and load Anthropic SKILL.md format skills in any agent", "type": "module", - "main": "./dist/cli.js", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.js", + "types": "./dist/index.d.ts" + }, + "./cli": "./dist/cli.js" + }, "bin": { "openskills": "./dist/cli.js" }, diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..7db313e --- /dev/null +++ b/src/index.ts @@ -0,0 +1,26 @@ +/** + * OpenSkills Library Exports + * + * This module exports utility functions and types for external consumption, + * enabling VSCode extensions and other tools to reuse openskills functionality. + */ + +// YAML utilities +export { extractYamlField, hasValidFrontmatter } from './utils/yaml.js'; + +// Directory utilities +export { getSkillsDir, getSearchDirs } from './utils/dirs.js'; + +// Skills discovery +export { findAllSkills, findSkill } from './utils/skills.js'; + +// AGENTS.md manipulation +export { + parseCurrentSkills, + generateSkillsXml, + replaceSkillsSection, + removeSkillsSection, +} from './utils/agents-md.js'; + +// Types +export type { Skill, SkillLocation } from './types.js'; diff --git a/tsup.config.ts b/tsup.config.ts index 92af3ef..728950e 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -3,15 +3,17 @@ import { defineConfig } from 'tsup'; export default defineConfig({ entry: { cli: 'src/cli.ts', + index: 'src/index.ts', }, format: ['esm'], target: 'node18', outDir: 'dist', clean: true, sourcemap: false, - dts: false, + dts: true, splitting: false, treeshake: false, platform: 'node', skipNodeModulesBundle: true, // Don't bundle node_modules }); + diff --git a/vscode-extension/.vscodeignore b/vscode-extension/.vscodeignore index 4d4e0cc..4a61745 100644 --- a/vscode-extension/.vscodeignore +++ b/vscode-extension/.vscodeignore @@ -1,8 +1,12 @@ -.vscode/** -.vscode-test/** -out/test/** -src/** -.gitignore +.vscode +.vscode-test +node_modules +src/ +*.ts +!*.d.ts tsconfig.json -**/*.ts -**/*.map +*.map +.gitignore +**/*.md +!LICENSE.md +esbuild.js diff --git a/vscode-extension/esbuild.js b/vscode-extension/esbuild.js new file mode 100644 index 0000000..77a4717 --- /dev/null +++ b/vscode-extension/esbuild.js @@ -0,0 +1,30 @@ +const esbuild = require('esbuild'); + +const production = process.argv.includes('--production'); + +async function main() { + const ctx = await esbuild.context({ + entryPoints: ['src/extension.ts'], + bundle: true, + format: 'cjs', + minify: production, + sourcemap: !production, + sourcesContent: false, + platform: 'node', + outfile: 'out/extension.js', + external: ['vscode'], + logLevel: 'info', + }); + + if (process.argv.includes('--watch')) { + await ctx.watch(); + } else { + await ctx.rebuild(); + await ctx.dispose(); + } +} + +main().catch(e => { + console.error(e); + process.exit(1); +}); diff --git a/vscode-extension/openskills-vscode-0.0.1.vsix b/vscode-extension/openskills-vscode-0.0.1.vsix index a268a43d8027806218392f02fc14d4e4e6fdb698..b4d7be601345541f3e3a2919d6ed8b2bea395200 100644 GIT binary patch delta 16742 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 IZ2z482gcPKBLDyZ diff --git a/vscode-extension/package-lock.json b/vscode-extension/package-lock.json index ab8ac4e..e089463 100644 --- a/vscode-extension/package-lock.json +++ b/vscode-extension/package-lock.json @@ -7,15 +7,467 @@ "": { "name": "openskills-vscode", "version": "0.0.1", + "license": "MIT", "devDependencies": { "@types/node": "^20.0.0", "@types/vscode": "^1.96.0", + "esbuild": "^0.24.0", + "npm-run-all": "^4.1.5", + "openskills": "file:../", "typescript": "^5.0.0" }, "engines": { "vscode": "^1.96.0" } }, + "..": { + "version": "1.3.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@inquirer/prompts": "^7.9.0", + "chalk": "^5.6.2", + "commander": "^12.1.0", + "nanospinner": "^1.2.2" + }, + "bin": { + "openskills": "dist/cli.js" + }, + "devDependencies": { + "@types/node": "^24.9.1", + "tsup": "^8.5.0", + "typescript": "^5.9.3", + "vitest": "^4.0.3" + }, + "engines": { + "node": ">=20.6.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", + "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", + "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", + "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", + "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", + "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", + "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", + "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", + "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", + "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", + "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", + "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", + "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", + "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", + "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", + "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", + "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", + "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", + "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", + "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", + "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", + "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", + "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", + "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", + "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@types/node": { "version": "20.19.27", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.27.tgz", @@ -33,26 +485,2111 @@ "dev": true, "license": "MIT" }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" }, "engines": { - "node": ">=14.17" + "node": ">=4" } }, - "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true, "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", + "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", + "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/openskills": { + "resolved": "..", + "link": true + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.padend": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", + "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } } } } diff --git a/vscode-extension/package.json b/vscode-extension/package.json index 4f0b6aa..ef9ce52 100644 --- a/vscode-extension/package.json +++ b/vscode-extension/package.json @@ -149,13 +149,21 @@ } }, "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./", - "watch": "tsc -watch -p ./" + "vscode:prepublish": "npm run package", + "compile": "npm run check-types && node esbuild.js", + "watch": "npm-run-all -p watch:*", + "watch:esbuild": "node esbuild.js --watch", + "watch:tsc": "tsc --noEmit --watch --project tsconfig.json", + "package": "npm run check-types && node esbuild.js --production", + "check-types": "tsc --noEmit" }, + "dependencies": {}, "devDependencies": { + "openskills": "file:../", "@types/node": "^20.0.0", "@types/vscode": "^1.96.0", + "esbuild": "^0.24.0", + "npm-run-all": "^4.1.5", "typescript": "^5.0.0" } } \ No newline at end of file diff --git a/vscode-extension/src/extension.ts b/vscode-extension/src/extension.ts index f035f56..f305512 100644 --- a/vscode-extension/src/extension.ts +++ b/vscode-extension/src/extension.ts @@ -19,6 +19,14 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push(skillsTreeView); + skillsTreeView.onDidChangeCheckboxState(e => { + e.items.forEach(([item, state]) => { + if (!('url' in item)) { + skillsProvider.setChecked(item as Skill, state === vscode.TreeItemCheckboxState.Checked); + } + }); + }); + context.subscriptions.push( vscode.commands.registerCommand('openskills.refresh', () => skillsProvider.refresh()), @@ -107,7 +115,10 @@ export function activate(context: vscode.ExtensionContext) { }), vscode.commands.registerCommand('openskills.installSelected', async () => { - const selected = skillsTreeView.selection.filter(item => !('url' in item)) as Skill[]; + const checked = skillsProvider.getCheckedSkills(); + const selected = checked.length > 0 + ? checked + : (skillsTreeView.selection.filter(item => !('url' in item)) as Skill[]); if (selected.length === 0) { vscode.window.showWarningMessage('Please select skills to install (use checkboxes).'); @@ -154,7 +165,10 @@ export function activate(context: vscode.ExtensionContext) { }), vscode.commands.registerCommand('openskills.deleteSelected', async () => { - const selected = skillsTreeView.selection.filter(item => !('url' in item)) as Skill[]; + const checked = skillsProvider.getCheckedSkills(); + const selected = checked.length > 0 + ? checked + : (skillsTreeView.selection.filter(item => !('url' in item)) as Skill[]); if (selected.length === 0) { vscode.window.showWarningMessage('Please select skills to delete.'); diff --git a/vscode-extension/src/gitUtils.ts b/vscode-extension/src/gitUtils.ts index d1fc5e0..f37cba5 100644 --- a/vscode-extension/src/gitUtils.ts +++ b/vscode-extension/src/gitUtils.ts @@ -3,6 +3,7 @@ import * as fs from 'fs'; import * as path from 'path'; import * as os from 'os'; import { Skill } from './types'; +import { extractYamlField, hasValidFrontmatter } from 'openskills'; const CACHE_DIR = path.join(os.tmpdir(), 'openskills-vscode-cache'); @@ -10,15 +11,6 @@ if (!fs.existsSync(CACHE_DIR)) { fs.mkdirSync(CACHE_DIR, { recursive: true }); } -function extractYamlField(content: string, field: string): string { - const match = content.match(new RegExp(`^${field}:\\s*(.+?)$`, 'm')); - return match ? match[1].trim() : ''; -} - -function hasValidFrontmatter(content: string): boolean { - return content.trim().startsWith('---'); -} - export class GitUtils { static getRepoPath(url: string): string { const dirName = Buffer.from(url).toString('base64').replace(/[^a-zA-Z0-9]/g, ''); diff --git a/vscode-extension/src/skillsProvider.ts b/vscode-extension/src/skillsProvider.ts index 0f2db03..a586f0c 100644 --- a/vscode-extension/src/skillsProvider.ts +++ b/vscode-extension/src/skillsProvider.ts @@ -9,20 +9,39 @@ export class SkillsProvider implements vscode.TreeDataProvider = new vscode.EventEmitter(); readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; - private selectedSkills: Set = new Set(); + private checkedSkills: Set = new Set(); private syncedSkillsCache: Set = new Set(); + private skillCache: Map = new Map(); refresh(): void { this.updateSyncedSkillsCache(); this._onDidChangeTreeData.fire(); } - getSelectedSkills(): Skill[] { - return []; + setChecked(skill: Skill, checked: boolean): void { + const key = this.getSkillKey(skill); + if (checked) { + this.checkedSkills.add(key); + // Ensure cache has the latest skill object (handled in getChildren usually, but good to have) + this.skillCache.set(key, skill); + } else { + this.checkedSkills.delete(key); + } + } + + getCheckedSkills(): Skill[] { + const result: Skill[] = []; + for (const key of this.checkedSkills) { + if (this.skillCache.has(key)) { + result.push(this.skillCache.get(key)!); + } + } + return result; } clearSelection(): void { - this.selectedSkills.clear(); + this.checkedSkills.clear(); + this.refresh(); } private getSkillKey(skill: Skill): string { @@ -98,7 +117,12 @@ export class SkillsProvider implements vscode.TreeDataProvider { s.installed = this.isSkillInstalled(s.name); + // Update cache + this.skillCache.set(this.getSkillKey(s), s); }); return skills; } catch (e) { diff --git a/vscode-extension/src/syncUtils.ts b/vscode-extension/src/syncUtils.ts index 18f1626..ccbff2e 100644 --- a/vscode-extension/src/syncUtils.ts +++ b/vscode-extension/src/syncUtils.ts @@ -1,18 +1,20 @@ import * as fs from 'fs'; import * as path from 'path'; - -interface InstalledSkill { - name: string; - description: string; - location: 'project' | 'global'; +import { + extractYamlField, + generateSkillsXml as cliGenerateSkillsXml, + replaceSkillsSection, + type Skill +} from 'openskills'; + +interface InstalledSkill extends Skill { path: string; } -function extractYamlField(content: string, field: string): string { - const match = content.match(new RegExp(`^${field}:\\s*(.+?)$`, 'm')); - return match ? match[1].trim() : ''; -} - +/** + * Find all installed skills in workspace (extension-specific version) + * Uses workspace root parameter instead of process.cwd() + */ export function findInstalledSkills(workspaceRoot: string): InstalledSkill[] { const skills: InstalledSkill[] = []; const dirs = [ @@ -43,64 +45,19 @@ export function findInstalledSkills(workspaceRoot: string): InstalledSkill[] { return skills; } -export function generateSkillsXml(skills: InstalledSkill[]): string { - const skillTags = skills - .map(s => ` -${s.name} -${s.description} -${s.location} -`) - .join('\n\n'); - - return ` - -## Available Skills - - - -When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge. - -How to use skills: -- Invoke: Bash("npx openskills read ") -- The skill content will load with detailed instructions on how to complete the task -- Base directory provided in output for resolving bundled resources (references/, scripts/, assets/) - -Usage notes: -- Only use skills listed in below -- Do not invoke a skill that is already loaded in your context -- Each skill invocation is stateless - - - - -${skillTags} +// Re-export from openskills +export { replaceSkillsSection }; - - - -`; -} - -export function replaceSkillsSection(content: string, newSection: string): string { - const startMarker = ']*>[\s\S]*?<\/skills_system>/; - return content.replace(regex, newSection); - } - - const htmlStartMarker = ''; - const htmlEndMarker = ''; - - if (content.includes(htmlStartMarker)) { - const innerContent = newSection.replace(/]*>|<\/skills_system>/g, ''); - const regex = new RegExp(`${htmlStartMarker}[\\s\\S]*?${htmlEndMarker}`, 'g'); - return content.replace(regex, `${htmlStartMarker}\n${innerContent}\n${htmlEndMarker}`); - } - - return content.trimEnd() + '\n\n' + newSection + '\n'; +/** + * Generate skills XML (wrapper to ensure correct type) + */ +export function generateSkillsXml(skills: InstalledSkill[]): string { + return cliGenerateSkillsXml(skills); } +/** + * Sync installed skills to AGENTS.md + */ export function syncToAgentsMd(workspaceRoot: string): { success: boolean; message: string; count: number } { const outputPath = path.join(workspaceRoot, 'AGENTS.md'); From ffbaeca41c0461b3f9e5224630d7cccddb5a401b Mon Sep 17 00:00:00 2001 From: wangyudong Date: Tue, 6 Jan 2026 14:20:17 +0800 Subject: [PATCH 4/5] feat: introduce CLI commands for skill management and a VSCode extension for skill synchronization --- vscode-extension/package.json | 3 ++- vscode-extension/resources/icon.svg | 5 ---- vscode-extension/resources/skills-icon.svg | 7 +++++ vscode-extension/resources/skills-logo.png | Bin 0 -> 9407 bytes vscode-extension/src/extension.ts | 29 +++++++++++++++++++-- vscode-extension/src/skillsProvider.ts | 6 ++++- vscode-extension/src/syncUtils.ts | 18 +++++++++---- 7 files changed, 54 insertions(+), 14 deletions(-) delete mode 100644 vscode-extension/resources/icon.svg create mode 100644 vscode-extension/resources/skills-icon.svg create mode 100644 vscode-extension/resources/skills-logo.png diff --git a/vscode-extension/package.json b/vscode-extension/package.json index ef9ce52..715b2ac 100644 --- a/vscode-extension/package.json +++ b/vscode-extension/package.json @@ -9,6 +9,7 @@ "url": "https://github.com/whyuds/openskills" }, "license": "MIT", + "icon": "resources/skills-logo.png", "engines": { "vscode": "^1.96.0" }, @@ -89,7 +90,7 @@ { "id": "openskills-explorer", "title": "OpenSkills", - "icon": "resources/icon.svg" + "icon": "resources/skills-icon.svg" } ] }, diff --git a/vscode-extension/resources/icon.svg b/vscode-extension/resources/icon.svg deleted file mode 100644 index 93762b8..0000000 --- a/vscode-extension/resources/icon.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/vscode-extension/resources/skills-icon.svg b/vscode-extension/resources/skills-icon.svg new file mode 100644 index 0000000..d81c305 --- /dev/null +++ b/vscode-extension/resources/skills-icon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/vscode-extension/resources/skills-logo.png b/vscode-extension/resources/skills-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0024dddf4727138e6e61b3aba43794848b33d5e1 GIT binary patch literal 9407 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 FV1jn9twaC- literal 0 HcmV?d00001 diff --git a/vscode-extension/src/extension.ts b/vscode-extension/src/extension.ts index f305512..a4db76e 100644 --- a/vscode-extension/src/extension.ts +++ b/vscode-extension/src/extension.ts @@ -12,6 +12,27 @@ let skillsTreeView: vscode.TreeView; export function activate(context: vscode.ExtensionContext) { const skillsProvider = new SkillsProvider(); + // Create Output Channel + const outputChannel = vscode.window.createOutputChannel('OpenSkills'); + + // Patch console to redirect to Output Channel + const originalLog = console.log; + const originalError = console.error; + + console.log = (...args: any[]) => { + const message = args.map(arg => String(arg)).join(' '); + outputChannel.appendLine(`[INFO] ${message}`); + originalLog.apply(console, args); + }; + + console.error = (...args: any[]) => { + const message = args.map(arg => String(arg)).join(' '); + outputChannel.appendLine(`[ERROR] ${message}`); + originalError.apply(console, args); + }; + + outputChannel.appendLine('OpenSkills extension activated'); + skillsTreeView = vscode.window.createTreeView('openskills-skills', { treeDataProvider: skillsProvider, canSelectMany: true @@ -102,9 +123,11 @@ export function activate(context: vscode.ExtensionContext) { title: 'Syncing to AGENTS.md...', cancellable: false }, async () => { + outputChannel.show(); + console.log(`Starting sync process... IDE: ${vscode.env.appName}`); const { syncToAgentsMd } = await import('./syncUtils'); const workspaceRoot = vscode.workspace.workspaceFolders![0].uri.fsPath; - const result = syncToAgentsMd(workspaceRoot); + const result = syncToAgentsMd(workspaceRoot, vscode.env.appName); if (result.success) { vscode.window.showInformationMessage(result.message); @@ -219,4 +242,6 @@ function copyRecursiveSync(src: string, dest: string) { } } -export function deactivate() { } +export function deactivate() { + // Restore console? (Optional, as extension host is dying anyway) +} diff --git a/vscode-extension/src/skillsProvider.ts b/vscode-extension/src/skillsProvider.ts index a586f0c..7da8d49 100644 --- a/vscode-extension/src/skillsProvider.ts +++ b/vscode-extension/src/skillsProvider.ts @@ -4,6 +4,7 @@ import * as path from 'path'; import { ConfigManager } from './configManager'; import { GitUtils } from './gitUtils'; import { Skill, SkillRepo } from './types'; +import { getIdeConfig } from 'openskills'; export class SkillsProvider implements vscode.TreeDataProvider { private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); @@ -69,7 +70,10 @@ export class SkillsProvider implements vscode.TreeDataProvider Date: Sat, 17 Jan 2026 23:54:59 +0800 Subject: [PATCH 5/5] feat(vscode-extension): cloud skills search Document cloud catalog search (~58K)\nAdd remote QuickPick search with retry and install\nRefine indexing/refresh behavior --- .gitignore | 2 + package-lock.json | 6 + vscode-extension/.gitignore | 5 + vscode-extension/.vscodeignore | 11 +- vscode-extension/README.md | 52 ++ vscode-extension/README.zh-CN.md | 52 ++ vscode-extension/openskills-vscode-0.0.1.vsix | Bin 21135 -> 0 bytes vscode-extension/package-lock.json | 38 +- vscode-extension/package.json | 162 +++- vscode-extension/resources/image.png | Bin 0 -> 155592 bytes vscode-extension/resources/skills-icon.png | Bin 0 -> 465 bytes vscode-extension/src/configManager.ts | 40 +- vscode-extension/src/extension.ts | 714 +++++++++++++-- .../src/{gitUtils.ts => services/git.ts} | 138 +-- vscode-extension/src/services/skillScanner.ts | 59 ++ vscode-extension/src/skillsProvider.ts | 826 ++++++++++++++++-- vscode-extension/src/syncUtils.ts | 90 -- vscode-extension/src/types.ts | 35 + vscode-extension/src/utils/fs.ts | 32 + vscode-extension/src/utils/ide.ts | 98 +++ vscode-extension/src/utils/skillCompare.ts | 78 ++ vscode-extension/src/utils/skills.ts | 54 ++ vscode-extension/src/utils/yaml.ts | 14 + 23 files changed, 2157 insertions(+), 349 deletions(-) create mode 100644 vscode-extension/README.md create mode 100644 vscode-extension/README.zh-CN.md delete mode 100644 vscode-extension/openskills-vscode-0.0.1.vsix create mode 100644 vscode-extension/resources/image.png create mode 100644 vscode-extension/resources/skills-icon.png rename vscode-extension/src/{gitUtils.ts => services/git.ts} (50%) create mode 100644 vscode-extension/src/services/skillScanner.ts delete mode 100644 vscode-extension/src/syncUtils.ts create mode 100644 vscode-extension/src/utils/fs.ts create mode 100644 vscode-extension/src/utils/ide.ts create mode 100644 vscode-extension/src/utils/skillCompare.ts create mode 100644 vscode-extension/src/utils/skills.ts create mode 100644 vscode-extension/src/utils/yaml.ts diff --git a/.gitignore b/.gitignore index 6f6d9a4..3568f31 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ dist/ *.log .openskills-temp/ .claude/ +.agent/ +vscode-extension/*.vsix diff --git a/package-lock.json b/package-lock.json index c73d745..2bc0e9a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1287,6 +1287,7 @@ "integrity": "sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -1659,6 +1660,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -2067,6 +2069,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -2116,6 +2119,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -2617,6 +2621,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2645,6 +2650,7 @@ "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", diff --git a/vscode-extension/.gitignore b/vscode-extension/.gitignore index a73617e..99860fe 100644 --- a/vscode-extension/.gitignore +++ b/vscode-extension/.gitignore @@ -1,3 +1,8 @@ out node_modules .vscode-test +*.vsix +.cursor/* +.trae/* +.windsurf/* +.claude/ diff --git a/vscode-extension/.vscodeignore b/vscode-extension/.vscodeignore index 4a61745..73b554b 100644 --- a/vscode-extension/.vscodeignore +++ b/vscode-extension/.vscodeignore @@ -7,6 +7,13 @@ src/ tsconfig.json *.map .gitignore -**/*.md -!LICENSE.md +# Avoid ignoring essential markdown files +!README.md +!CHANGELOG.md +!**/SKILL.md esbuild.js +resources/image.png +resources/skills-icon.png +.trae +.cursor +.agent \ No newline at end of file diff --git a/vscode-extension/README.md b/vscode-extension/README.md new file mode 100644 index 0000000..15fadd6 --- /dev/null +++ b/vscode-extension/README.md @@ -0,0 +1,52 @@ +# Agent Skills Manager + +AgentSkills multi-IDE management extension: browse and install skill repositories for Antigravity, CodeBuddy, Cursor, Qoder, Trae, Windsurf (and VS Code), and search a cloud catalog (~58K skills) from https://claude-plugins.dev/. + +![image](https://raw.githubusercontent.com/lasoons/AgentSkillsManager/refs/heads/main/resources/image.png) + +## Features + +- **Repository Management**: Add, remove, and switch branches of skill repositories +- **Skill Installation**: Install skills into the active IDE skills directory +- **Cloud Skills Search (~58K)**: Search the cloud catalog from https://claude-plugins.dev/ and install with one click/Enter +- **Multi-IDE Support**: Works with VSCode, Cursor, Trae, Antigravity, Qoder, Windsurf, and CodeBuddy +- **Active Skills Directory**: The local skills group shows which directory is active + +## Usage + +1. Open the **Agent Skills** panel in the Activity Bar ![icon](https://raw.githubusercontent.com/lasoons/AgentSkillsManager/refs/heads/main/resources/skills-icon.png) +2. Click **+** to add a skill repository (e.g., `https://github.com/anthropics/skills`) +3. Expand the repository to browse available skills +4. Check the skills you want, then click **Install** +5. Click the search icon to search cloud skills, then press **Enter** (or click **Install**) to download and install + +## Skill Collections + +Preset repositories bundled by default: + +| Repository | Description | +|------------|-------------| +| [anthropics/skills](https://github.com/anthropics/skills) | Official Anthropic skills collection | +| [openai/skills](https://github.com/openai/skills) | Official OpenAI skills catalog | +| [skillcreatorai/Ai-Agent-Skills](https://github.com/skillcreatorai/Ai-Agent-Skills) | Community skills collection | +| [obra/superpowers](https://github.com/obra/superpowers) | Superpowers skill collection | +| [ComposioHQ/awesome-claude-skills](https://github.com/ComposioHQ/awesome-claude-skills) | Curated awesome-claude-skills collection | + +For more repositories, see [heilcheng/awesome-agent-skills](https://github.com/heilcheng/awesome-agent-skills). + +## Configuration + +Skills are installed to the active skills directory in your workspace: +- **VSCode**: `.github/skills` +- **Cursor**: `.cursor/skills` +- **Trae**: `.trae/skills` +- **Antigravity**: `.agent/skills` +- **Qoder**: `.qoder/skills` +- **Windsurf**: `.windsurf/skills` +- **CodeBuddy**: `.codebuddy/skills` + +The extension also scans skills in hidden directories inside repositories (for example `.curated`, `.experimental`). + +## License + +MIT diff --git a/vscode-extension/README.zh-CN.md b/vscode-extension/README.zh-CN.md new file mode 100644 index 0000000..93902f6 --- /dev/null +++ b/vscode-extension/README.zh-CN.md @@ -0,0 +1,52 @@ +# Agent Skills Manager + +AgentSkills 多 IDE 管理扩展:用于在 Antigravity、CodeBuddy、Cursor、Qoder、Trae、Windsurf(以及 VS Code)中浏览与安装 skill 仓库,并支持从 https://claude-plugins.dev/ 搜索云端目录(约 58K skills)。 + +![image](https://raw.githubusercontent.com/lasoons/AgentSkillsManager/refs/heads/main/resources/image.png) + +## 功能 + +- **仓库管理**:添加、删除、切换 skill 仓库分支 +- **Skill 安装**:安装到当前 IDE 对应的 skills 目录 +- **云端 Skill 搜索(约 58K)**:从 https://claude-plugins.dev/ 的云端目录搜索,一键/回车安装 +- **多 IDE 支持**:支持 VSCode、Cursor、Trae、Antigravity、Qoder、Windsurf、CodeBuddy +- **激活目录标识**:在本地 skills 分组上标识当前 IDE 的激活目录 + +## 使用方法 + +1. 在 Activity Bar 打开 **Agent Skills** 面板 ![icon](https://raw.githubusercontent.com/lasoons/AgentSkillsManager/refs/heads/main/resources/skills-icon.png) +2. 点击 **+** 添加 skill 仓库(例如 `https://github.com/anthropics/skills`) +3. 展开仓库浏览可用 skills +4. 勾选需要的 skills,点击 **Install** +5. 点击搜索图标搜索云端 skills,然后按 **回车**(或点 **Install**)下载安装 + +## Skill 仓库推荐 + +扩展默认内置的预置仓库: + +| 仓库 | 说明 | +|------|------| +| [anthropics/skills](https://github.com/anthropics/skills) | Anthropic 官方 skills 集合 | +| [openai/skills](https://github.com/openai/skills) | OpenAI 官方 skills 目录 | +| [skillcreatorai/Ai-Agent-Skills](https://github.com/skillcreatorai/Ai-Agent-Skills) | 社区 skills 集合 | +| [obra/superpowers](https://github.com/obra/superpowers) | Superpowers skills 集合 | +| [ComposioHQ/awesome-claude-skills](https://github.com/ComposioHQ/awesome-claude-skills) | awesome-claude-skills 精选集合 | + +更多仓库可参考 [heilcheng/awesome-agent-skills](https://github.com/heilcheng/awesome-agent-skills)。 + +## 配置说明 + +Skills 会安装到工作区内“当前 IDE 激活的 skills 目录”: +- **VSCode**:`.github/skills` +- **Cursor**:`.cursor/skills` +- **Trae**:`.trae/skills` +- **Antigravity**:`.agent/skills` +- **Qoder**:`.qoder/skills` +- **Windsurf**:`.windsurf/skills` +- **CodeBuddy**:`.codebuddy/skills` + +仓库扫描会包含隐藏目录中的 skills(例如 `.curated`、`.experimental`)。 + +## License + +MIT diff --git a/vscode-extension/openskills-vscode-0.0.1.vsix b/vscode-extension/openskills-vscode-0.0.1.vsix deleted file mode 100644 index b4d7be601345541f3e3a2919d6ed8b2bea395200..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21135 zcmb5VV~}lKm$sREwgS5^olO0049#0RYed002zfolR_=EbMG)U7al4Z47KJ zOii4eyHus@kQoqoTYCB#(c>~)=7E2YYbXadD-$D76p0mv^K7NLUnP(HA^r4h?C`Kw z(zQS=u^wjHVYAcf);dn1p^v+(p7D}MWpW<3I;iKRJJ30S^-IOY8)GQtFlGlbyN)C5 z*h3;9VpumfciEi!_AV6)tX5l<&(XyiTC+Ca| zz?nH=Ogk_U7Y}C)QFIm|@7;;GhNaznKLWPTgv5CDRJ!@@4i+VKC9got*$L2AA+KpmV!#Ty$Vcm(m|`EwoVyyR zk0>blATLX@g(9opwaK(HcFg?QS%2jHAEP5p42+9mC) z_mvQ#NMwVH;&K1mr%b+0B&g_PFXB87q?H-f5V(>c2` zNd(qHmA;CZcVpFQRUXnMamxB@q3ct>$*>9ufR2|2c7Ni_MwkPPaw^*0O?Fs0)zNJDAdNJc2$TOKe_()WF zlz5|LFL}vNs*@sGF#H|9qCuEsq1hcA;%~07ClUVHH(e>7fS$4YqTpco zQZa<%^_`BKmMeo%;2XmBw5ULZVH2&<3I9lV4A|~RHsLsG z6$Lhepp6?wCm@|ZDBFZMcExl4?Q?0=f-r}DbI(ue(cY{hBPx1$u&CG0(=z_sJuXGm zbN<8k7;f>_?eiFU@sTj&dLkts7uk2vuR^M*MaPVZ1c4$dDSMc2V4(KUZa?SlIKngC z6&Nm9I`#pQG7p;w=c}t}!>POW7S(99G^NMfx;QQ&&^syPCfi8#cPf1xyIGh|ISQ7| z(X^FJaEctQfrSVE=sa;BVI^7>E$FQi{Z$KVDrgMJ7IJ)KF#)J~cTbmVo@w z&;(VC6Vxb&ps*>F7VC*WP_mkNo{8#UcuRn4t_xO5`1iEH|d5n+RI*XH3OaWa12WnI+JFF=FN zl~^{tW)%KHX@84BIz?WQL_D)Qyq=K~89NXy@gmdhd#$1S1{cSH-WR0ka1*Law0%#| ze$PKw#v$o)I+>%Jq__G4t=7YC9o&c%m8K7y*N7yF)an^l+Lewbw8RM-+pDBYK_M#h ziUG})XWr1OBrMz2>SXQBzUo$;7GRtC1z7p`;#*;*xgq9x)3wbD9a?*am>$)r&-+?%rJ*3RBzffwIo0);*6#OuR%>1yi%$ z0QKB2Z95>0Zh&b@C+IeCB4P?#^=-Y6Qp4<+M~G@MVo<3Wt`AKLuRoGqMuMt0_I zoAs=CLi$u}D?NR(V&;Y~OKEc~2C7j%-`TXAUZ0=a-?hL5Q;tP!%#6)Hvgi0EFm6{M zepb#*1ks8i!awt23j&)8Tpe+|QrZK(Nv65ad$!w$dmwpQVdd3sM{O+I(Q?(aZfW|P z3Gl$W4LCORhvVye<-PT=BU16zZDR_OCghoPR@s95UESBM0_IE`KX{BsHcxWKgum|A zkler+@{reYrwOdfJs`-cA|U-FYC$rPtPoI3F(k~HmheRYf#Ptar03eGB$&uf$t^0M zymf=EK7<|E3L=7#poYm*iaCO?sL0A4-%8MoqMJ!^u`{V3JQ7CNLe?9;B&8-xCsDCs zM^qpn7hinNv`o5ko8_1ik@BjSB7+(u)B>A~1+J5VqcCIlhaRPy=#I~Oyev_kO@-^~_&0JTA{V1<12!c4 z5ON=)tLjrv4z9$83)$eqhi`WieW|w9i2eexjH91#)}|Al!-{X;KuhQi^VaIwp`g8Q z5cKJlF?@}Cb_T;b?SMl)+ILv9U9s680#D`xs%cj!-ypuh;b>cL(ZJ;#y@f$ML@#uN zPlj&hL=h%ebHUpxtNg3kw`a$CBWprP+%0|JYeT!bQoFFBRE?sBsW?(w5T5R?y`iCP zJwj5f{Xsjv-X}4SO-}U>NA#_;W~bN= zc(ik-5X_m-ljLJ+d<3fo;)%;SS+HpbzOR2$N59e~qgyh7WOP0K-ZO`SnK^We=YqGV zbEk=3H6B`Qh-A!vPDA^8YTDK48-tsyl8xQ2i^`^TS{ix z2K)oNnoPM`5vO|MNgWXknM7A$*gq^%KKahStn&^_m*y|ijuBW`HF?5+qpR0q=Ia`- zLMoM4^~G3B6|M=<^c~{z1yeKL>S0Y?U`m#RtJ_ibMZyRkFEt}L29Hz)D1#-dLk~b> zfGT!6Kf4Hf-GKqYG{_fQT#6v ztn}{@jQwvB>}cX-=i+E&;zVa*^jB;=m7 zj+Ve*PY5C1)?F{BLLZ<9j!pN>U?~jsk_D21I7qL_5Ljf1TEOAbpmo7OEXu--<&t^d4@7dTuTh{w!R5{ z$VZHcwTO;k*T+wHtB7R(yP7hO@buMk#gFRgzGuwU?jK*L*T`4%|9W!v_w(Prs+j+~ zubBVltDTE8o%26B>aU2PwK1^giR^>&$43DDIm#M>+j?ed4*`#-iEx0 z*8lf%CadVkZSW&}(!F>Cp;G?dFIj7Hhz~c*RJPk7hZ#w_xh((4?hWVDr_< z_-1pmw^z3<4)x5XoT_3OGA8)evO-H-qNFn|I{QN&;h(9GXXH&B<8NRs_bZ&KVb%7R z)tWDR+Fd9$2Sd{e{8rQew3PsFY|1k{pnC^a90|a@im;y?XxRTpx zVi%aHF**qKC}XcHP$dN?xSb&v0N4|mO9v|;Qn=$c>PofK?&jNqImEXj9jHVVBz+k? ze1L&|I2)kihj1@4M;N6C_yK0?wPCFmtEKU-kQ@_7!>_nE>Um5>-i&F4&b(d5n>r$W zWi3bb{1Gp-IfSv!_&uc7N~6bHSbJn_v`}y6bXLTfVs!Avp#=UmVT;&4Jj`{Zf>g?8 z&f;F?U3>^8pdB`Nn)Y&GoG%t&5#@Wz#898`jxmck?Il%CO{CYfZ8RsCsKAB&IQFh( zfyxZ)^~VC5fEpmdE8;;PIh!kdP?p5{6Mjz*Zus`_!2Fba`wmc0x3APppiWnWO~l6r zzei|2GW2eouH-=$wVK}-j~rK1)UIDSjqiM9Y<}k#V7;pEJ(l*u;YtY{3CxIr{+PWp z+tT0uv@R>zG#?3x5$+9#jZ%&A&l25(&+!3bV?NV2kJXx0**Bm>GC55#XrYQb6Q2m+ zoGr&j>o^68tOp(o@RT{MFIJYQpr|D&Xvx>fAW0}FiN}kWt1}X*?X@X#B|u^4%#RSPM7Gs1|4l^HuqC4HZTPu`KQS)raTMv8ZQ(B$-4W@`x-fz_p1_{l3@0anw; zEB}WZ=#G^#d4Czn1@Zrn8~+;Y(W?KEeq8H0IDv~pDRX?VuHJ?kYDE~zsx3m!=Hn=a zaC1nLClJYnM=$>PND(*eg^Tl zy}0dBm^$A~OXr}a3NCo9|t-_2^TE(9t zpmUir&+H{)FPuLUATRi&)7M)vcXeb8KxR+W1Wb^NQ9zuMf0(X(@N5H2ed>7 zvZnuFXm(KLOn>x~49$$%7=rZvfva-wqNaugSKNbtI&|q&BUq8oKur^D z{QlUoOhzR<7uke28(jx4xCK+CdG9_l^r$Q zo;lT!3CQNM7-*a%;FSqoh|zM4S};>BWeS%hc1RS2QkY?s%y!F#F=O#G&Vsz4^wi}@ zGXC~9NKhE~f>8MwdsX_X`LT`zB>X3&T z;EI-0nN?s_P<@kEhczSSjJHNoWkA{v!W8A^-*))fO$&QP`}x-4_zK+n-OgPTdr9VJ$hD)?AF_E_;< zzJc&;r1g1p)x!?5Jee%m1$jo7YQG*^TDD5`nh-is+{FU@m~CSZH|Mpm^%JY0g5z`W7(<>(9jD2}0+a{_k6i4E)iw2n)LW|*>@4)j9GkhE4(W*o zAlF|H4?O9{>e(;{M)PeWpwA%Sd5M2gH-N3^z7S3>daa@h>D;RpDi z)35jNPuLhR06+-T{{{r2|9SdZSy)>;$vfJ)S{R!+{->g7QrmF+TbTGl?*=nkx+8X- zDgpLSxg0zwZ%bYn3#6n%($TS2OfhnMzsb@`PzNYXI+Om$2h81SSZM(Gk#udSr)0f2 z{1hhHi8!L>kSphlJgR>$+PsX|(C~0pBcUu~jXiRHzA$Z&nMQ7@NqE>vEGQ6Akp+)m zZkFsWH|Ei(n^jA$Bz<`q^3)|ck;o_p$b|w%AqAbxQkcPXUvBi6JFf!UzCTv3NCrJl zVTG>9hLw+>wzpbjp;u7S&(H-T-9)+OSg4AbmN2Znf+?ggKAH~vZL3@qAc%+1Ab6NE;CnrUYb7BA!)s+k#%#G{pbl|9< z=D9IA>MJ(ALJ%_D^C}zHdD1Bd(y*WaUnbXEvQ3YzN;Ao^n`{oEK*LB^o&jKdH)!|K zp6c~cXFBSq!bs`^Jn}7S??ZwN)(D37ZGR?}t`(f(Ci51=n?DIGlfZqq)oV3x1jE4)zwAi0*6ijuNw;V^VXafu+P_Vbd5Gnpr1h}P%xz?dUI0YL>0zBx%`SD1? z5N?Y&XrXm=lS-yTZu4@+pn4G|ZSGtvdZ6~JprD34V6Cc(ftZ4jh{glLz~CqJ`ZR59 z9NM=;IiqViZzVCTNrr`-fx@Jp4f#n9VZx1Q8c#mTwgr1_{_)v%^>Ax^G*$}ME%EBg z(ZR$HI>-HH&`wn5T2#aktHvxiM3lBZTZ>=HER3&@p z&gCp{5zYk`U=w?>U=G4_v&Ij!VX|U#CBR39XY2I#w3qv_ zcde)HPQ?LCTN8T-GX=vUa#^-IK06)BTR%&t`qhg1T=nN;xtQsPH-3K;6mWiu@Gr|>Sta!k=SWOK^@yuX~5V$yAe_} z258}oVHm(c`K3r3v}!51lEI4QcT|MiszF)SUuS&Tsu58jrDQ7zC@HVlbwn92YgxY( zPHJNeH_dF%;*gbS2A(VrzybIp=Z}wyqsm%l_(%^kx25d!M8+~wDt?wD>?jEtzyaNy zn@THyuQz9AK6ICEI+<>^?aR*+G%H$rqC>{kY*oAaXm>^mXLriWK<@Y>s&CjW2_S9}BC0C|( zV=r1ti0~LT+~r5dlBEm1lbybK`PZvK1XbEVr6C;M4_E8EkK=9CI)juJ4>s)KqOgWk z`vis@)f*IyWa_2;g+8}vKXktvmg@KN;IVN2M zX0w*EiLzU>M^^vyhEkwM7`D@egjl7Ft2`wx05W~OZpqOi2qw9ApWt&!`6yGMhu`2E zrA}hzdxcnnlcu@rfP+D)fFd&e_28I>1w9!pJk>)ikAH8cE&X!7eh`N!4u$G!Jix;+ zgJVHy7$bYo(a}UGuY*rh5D&z#@h^%t0}(OVvR4Sa$ih;pDy#??C+_G%2w*NQpqVDl z8dd*T*bn@bRu&vMK%+PF43h;}FrSt`XfwHz!k`Rxe$g{zY(I?L-YNYn^nd#FNDdgx zg=EUMI8+ObaFs6}rW_0sD?s{Xg5Iwtd6#$S zEo8-YP{b5_VV5uhQJS`Ra5qY96xNDOskSxqz95_%AZv7&MxVUWjIP2cOP6bqkAH8V zw_f|Sy!%n3eaY!gB3Ba{FqID%|)Ro2!^f-)BB#1$kcKR?NOmP!7yT4YaD4UkI$}nu@&YQ%v zCbpM2AkDufKYhyKky58?!8&jGd4gaBL!Wqh{$Y6!`pR0nWSgy5M$Dee*C*_Hy|<|L zl0NJp<)HZn|A)tz5Pv|0Kmh>U5&t(HP@jd(95b$1P!myqPQLK7-Ivf0L?y4{WA3%*4^sP4`|(Wk%Cj!J?9!wy z9O#Svr8z}9hfi5C^;Mj)WVXN=QQ-O3=$pAollsRTVeN$z^Ajm6D{JLq#HqtqNlb6w zoFRMRF_k?dR;|KPVR;T;G64i&zX&Xa6Yx=TWC!I|COtJPf)3SQg3b>#beubCOa*Pz1Adc@=>BMil;aWW zsPdSF*)aA~Qr2DULRU^Hl9uO9L4^r7V9 z1iWaoCyqH|{c<1iW+5{w{C=*a82wbBotE&}_M?4rpleYpH7T5Ia88;{6B1W~W0a`! zoXquwnFx9F=*dFOuqE%oEPKJ%lJ|pk;~D*0(#>9ylJ)kh6v-&1vTxM6US*Z6%R&x~ z{+H=CGwT#ma3p5xCZ_2Z)!5KCU?tC-f5H ze`H1D&-{Ol+%2>J)@@WD`LH-Rf6wvYY~*Z$eL(@tqSB{rzqvH|WO4(qkwMR{ zHS>95dxR;|6{uRUn+sBqV2sBB8!{2$Y0gz0!`TWO4VY#icaUCIwaq8MVNu;FmPvQw zD@o3uqrqY+DU%O8DP1KZ@hk0$$hca&7S9;$O4jmEYf|4f4?pUI&K1dJEAOzwLC4S~ zOZe18wBc&#TiH;;3F3^no40yM`NLPLi2Tw}{UK8p&K#hnSHE~XKJ0++l^RW4&!g}e zV4Rreat`tlMp6Otp_Bb%9||W?(pvwvVpPB7MrUdo(fxhdDE8h`&OFx#e?iMy(xwywO=)u_tv)8FNsqM6lpr*+w3dr5Tq6rgxisa)7^ z0+m$u_PJr4LYdJu)5t5Z9_@+bi;>Wy|Lu4z;aeMkrUq1?&&wwu%jcyCS zD-U*EmNeURZ$&IO?0jU1)tQ(D*UvzX!Oti56?9e#(u+}R2sEh_Hvl6^ zKWD}jOVF5-K#hbrv{UOWVem%-PjxcMF6d<6u3iy6#`Qx{+?j^~vzXOOK?-?;Pkv>K z620d0%jS)(8vLtstQ>mjB{)G5j~{*RTIY>9JRa`%>*42JgBpF!BgsvZd|or;kqD(U z#t?$DcOvwJO9b-tD^j3&GZ`a9&$#t(wf+Pi4GLUaVo^lx8$bYK)-k@qewdalG1&Wg zb%(i^bI({QQyS||P3XEoaeHq zw?-%{13k%``WNAsnTva|%_*$wZMGo#XP0ntRpns>>JduuXL2>o z4WTK>VYW;0G3DEmjRlc1PYYMzgXd6)Q4+(*y;M zV%3+xPqV%uVN6~>LEUn@AnKY~Q$`JBxZl5{TmdScXGl7RbClhe3u@#DP&z_jQoU z##sQrR7(-9*ctKn@X5_IqpsvEP;@Fgf^M1+g~23|mMT$z73Gl^VV^)zYGGoVI&1>G zCs;oxMgMX1*wBmd8Qr>%63?sVBgKpJu#~&pocIVfN06KGIHi;c-daK#a=fga%3ETe+w7i5{t^HEq~o}Nc#9*Dlj_>u8t8~= zEUq#NWHTsOx@$dw>vwuXoIw}wH%nrJWY~eZBM||u2%jUTYQ`uTnFHLU$cWY^QHDH? zvbX@zx(ui2M4Fc&&QH~LPL_Hkou%9;CVCPYb1a4BAhQFI27g{fcILWVbiBFf*x8kj z3l}UYr>SE=Db0Lsb>O>oS3pQK%g{j>Mr|`vtBj!rLI+9{8#Jh=3c8NdG()rE*)Mwt z<-9!pyp+F;g=({3ZfH36G`j;rGk_1toz(%J8ARy-lYf$;I8Lg)RaY&2&g@x<(U0_8 zM?Wg@N9FVi%O^#rsZaz-$o_tz;bbO}`)Lum2X$Iec@cC(WS{ol2tsn4bmxsU#b$T! z%iW$pJZ18GyihzgN;QdzkXd1szYVojtEsSkX;bzp1$qQ9DsC6`*YKHJ$^=mW<5q7N zfjzYV2p-=v;onu#h)BUwXyttf=k&@HaAq^1l?Qi$!%T`A1br^o!0O!QIhgu$?#j?r z0YrA$6c4_nZBG_cj*F|-s`=G&{}%J9?{{*2jUxxVs;lF&arg$y|5-k47i!l`+Jb}3 z9#wKncCFxoK(g2$ZESzTi8{>Y?IyXrB|5`7BYtWD@CVne_18S2lC)7SNjVf$P&E=X zi8wu^VgvL2_HBEy+k*1bnUQQ@yW!fBHV@m(9!ni2sTVzF9u(c)>Z!Imj8LHJ1awqi z?nmtK!n3=A3}UruNC4KsIR(qJ@Uvp6vfetL$ok~V!0r%&Dno3aV!2d#wz+o~+B)3+ zsT=A9rsL_QhvLb+(q6ewHdC^o>ee;f?zT%+QMp45_1K(dbMMo}s1ww%hwlKORVVuL z^CqQ@y;c{2?^NqB-NLcxtsU5$#nu$&cGdT`rZ~_}kruMUPsQZ+px7_++7@)5fvk zlf9>Oc;Zf^>&&ownZvgTR5#Yn?qmX5dvAJfo%ZU5XdkMx4EIDll=~~}5`4`2_JxD>C6gr{78U@^V#z_yI-uA< zB_YCOKN7%RKyEp@Yze6DO}4l=w2|EN&IQDM>bvVLSo&)O!03JUxJ6;A zbP9UAnF&XrrG-4<^7REAS8I7-hPPbt)Bn(-QBFf#8%+%0V`L-Q%NeB30<9*HEnf43 z`;ien6Udv?hC7A&Q^|itV9SdjCi!iVVO*dW;7Ri(mUhs^`KHvAaU+^(Qxmdvi6D}Z z14&CCU2SfNV0G1=sr31tp;i!_T!lF$9vC(w-nW?N5}g~&hD!i0cFtrJ^9&(5L#e)Q zD=bFfW)j$Le7n;4m-)JbkmXI=*gS?;KnewwC=70cJQ4^Ul;^sX`N-`w)+7DQK{;NeShsn42ZQ7@4E;CL`4hd>vu?vjz!)3r&T$2x7j( zUHhTZ#Kn%`;lymGQ;J@t~+@LbmIx@9Xho1kndQMZ zB;45qw9~vE0abq=u^d|Z(RAMd04G%ig$~Ev2bB~Fxa^zul%R=yEgOR@7C1>Es5$ja5*5fLPmKPPoi)o*U8& z&xi%(!N6v0kjc3G8C4=@*yc_8{Hdn}h9TSGzQjgO@~C)lJX(tk#-G=c#b2>wBrB7# zizZ($d4c|qot>~z%{q}Qz}nON7V9Sfx9QuOVMB`e>CA-BzWT~I1^VKS9-{eZ6Np74 zPH>>K*r+It;xGqF2(x(ZLgyUN^tG($`F8o)gO+XYjFf3AxHn6Re0U4x&*z>#TF(S@2}}xZ)goki+5B!n^$ha*lMIquwQo&iCO7xu%4j z$`|j&1quhI7B{d5ZgbIADTVz?egL7I60Ef+=W=6G48x1dmg4gTev_s=sqf_3U==GP zjmz;#Fb9gNno zDAwW)(dJ|6*dg*X=eSKzU zsudkXcP+xENQ*kH;03$Eyu=>kWOQ~3I^a_UTqQ#lMFJXZJD;>H6ST0s;JCDipx`ql)2Q(NvElrle8e7Y2==#lJ zJOppO4I@)9);!VqVn6d&vAOh{<3TTnu zo)zK5@YWBwNU;pww|_0WlKD(bu>Xuw|F@YP$L{JapjW2&oVfc*nar7eZIV%< zF)}-+S!1kX^f>W-Ul%8tNZ3Y>B@T^LGh9=-!gG^j;aQ)2LosGeg$jZa4nb~7r^sj>cew2sz>`ZleTjs^1V-w5F+uj-t zd>e>c($V-){)-M~8loEhESZg=X67rC-9igV#6`(!p(-WQbIwPtVIb@W@#^&~VtiQ$ zFNAM@;#upNq|8D|%VhC*4BM*V>{ai4WK|=(Ws->^Dkg_;q9gYaZR}ddaK)F-(H=T6 zkb1d+xOG6o5Wr9u+R=HbpzJ2M)4+JV?R}3k3lqprwo3G(#>yHphWRpWkkotx|6Fxh zmx6<3ZbKIVjSZmW|vtjF7@@qhtvT2r0lkcWHR#kzjdooz^a95Fmt&m z+63&3G@1|>WO^=mMW~^CImK`8W z(RLXhv}jiug+Hph=OK%}eSNQ4f-CvvqzqG*c}HNU2*I~}z-fmFJ-5^v*jQ3v3=ZAP zMMi@LJQeXq+&M%`)8v~3J!L!AU5A!3`!~wQ+3|@fGF&w{uPI(*0O!j?JiCsX) z5pBl1#8VzR78^&Ek`}}bbyoK}PALw_)}$t4p{wiG+JdnwlVj&Jv2W=q#k4ZCjEYn33;J*&b;E1LilzL*0F%$6eqL5$M=s@ znrZT>n&INW%^pb6vX*^G)7t{daA_ZAm0D(b=PoBLxBo01GFCXoJGf{u#6})9xKdTL zjq?UabBv$CXux}rlRLuAHIz8*hOv%v}@6hS_>lc>x%lP8b^kzDx?(pY|u7|n-0^8 z#D;)P2~qg|f>U!wEpFa)_Sj3UdT&%rzDqt71|QO!uQQHli-Cu1Yq4;xpvo}a%3zAy z@yjRG&uH#7svP017rZywLpV&_;W}?s#FYo1!K?DqMTc@Z~u4JmqSTrU!VJ6(#zHZD`w%LI(w{N4Gk zBdW7afqOS-HO++5UWQlD$~aXgU+&9zSe5IU5F0+f#7!c+^pZ(n&cqQdTaNdz)j$Spt`wtD{Ju~Je2wM zUp;gC;r&n_onW=5(XLdSd!MY>eSb{-M+z9dx?9`=`*#qQ@n2KGe_pBkTL}EG>wgZy z{%Z=jq-piHiIMu<`Ho6|F$Vw(LdL|!)sbK!x6f`-+}7H>(AcCCNg7MMh|&j?YooI7 zx5EJ-p@7ac_2Fu2##h*6&%wR|eu7O;4ufFS6lFu-8p-^|^6C5lKBzi~NeFFwS%@p8 zPt3$VM+t6YW_x|&X$$kb;G;Uz1%_;uu2r;Ej@MlCjv>?63Ywz@E!$W>KJEC*yq|M^ z*NKagINB)Qx>X}o&R%=#zt6XHr3itlvgb6+PTz7U(`C%7n6V#5z(~|9Te=@IGot@t zZ&1x{JcQ!xoG9pb;xQ)ad*$jlKy#f!1hqxWm@f*_PcI+SqhDtp9UVd4tY`u_FrZi~ zjKo67C$DdPk{DLNTofU-d^Mg$&;0lI1U$&(K-!}!qNT8Y#l0j(k-?}F=?SpRtAb|2 z$+D9YL)7PeL6&5b5zIWF$-c!Ab>E$bD=27@IKe-IPb_KhloX2W+<773kWu-BO@KK& zA{Kx?P1RA|dl3xZQlf)P^ zBO8%1A3eMLX;%EytMRV?Xr&h)uTMq=Q;an!Yp!cxbV9&!X5DlX(cKWH=ieSqR$V$j zyLs|BJ|A?v+{{$Z=yiMgdHcA2-#=zPdV*(t^$Q!ZpL(bBi$Vdf$Bk|#q*I2e5QFn5 zdP-Uw+rpCFf$VD$iV=^So?^NJ5nIMQM8#u?FY$yIL`maMNmLelK%s3K777(h0td`N z7*gHfXN5;7Bv`qSA>)&Vs*9F=LL(uGc{md(S&(2LnLtV`GAI0Mn_BdN8p9ASc?fJ5 zGsPiim;92A?VPw?q3lvjO9~A zB{|exhm`0QWeg4)omAIhAHc|GWV|b}8(llwTjNJ6BWRYKv3!dIQ3#%bmJ*djh7~Px zW5i1QLnw6%flc8I6Cw{wG#fXh|IB`O8ssN3?9bv=x$qYCOq5=~JNTVc)R00dP8t0~ zcFmU3{_F(4t(=AHQ56ReFKa?vj$%L-Pck1zE|NTzNy}Z9PT9D!5P0=C>VP6w&Ld73 zler)%6ctTfs4s2iS99MmO^TH@eT_XpRYJ;L`uUODaAV!T#Rl|4{_?j1KJBY$(5RgL z$L5RnAg>#K2ph^Epn>BDQv-OO(WkIi@=o`i|>(mAB^?=HTuu5H2;9K_b>AS@Z5 zmvUp!8ojhe6ZTm?f^CNMy>IK|iz!2<4_UX=$5700=IJEm@m@rJ-S8~4F~GsHtx-ponZOXKnS#P}Qf)#--3VLq&76d}*%?EfG+;+{ zpkvizj!BY=DMMT6uFQ(A83q8GHJn9DntbY-wlv;FMi@;rMVjEUw;(ML>z_(dT^21> zml{I9-6C_7UzWb?0Al%%LNnz#5ii%6Hv{$j@DoWxX9W1)aqfQzR3}UMxZ|!#_(ij* z*4J11K%@wKHoF)cm~>{oSy{9f8R&NNe7pM|gKEdatr|K|T{kt(LV$U{;@oi|c!S|m z%#z4+h!)00UlGF$oJ=~=vx#5_3QXKmU<@w#-YP7G(OK1?0>-MuuYEtvBR1`6Sz@GK zWCV*gXorp{J8lfFlh$P1*_^;TU?T1NFEeO+`j#5FbFpInQsriu(3al5|2r11r4460 z0J(H)M!+(wZwxg2s^bMw6~?hbYoY@4b7u4^#~VxE7e?Lc{}E1B%Xq6b2Bwq>1m!-O z+)Vlz{C#F&d_{CEU5V72IHDzcJO&mTBixxacvj5Kws9zcG~|k8W{@d5JbCAu%Oa$ zkY=LPfbv!!pScE>CPP9QsEmm_zCs}m%GnNcNDbmnOCUk^D0AC%lOT3~+9=zAWh0Hc zUNd-dS=<1QJ#GxQe-Dal2AQJLuolvbH^B2gc{YD9mGF^($v7ul%tWa`Gn^vIKw}Thjo+wvEYYZMl)pnhR<&M;#SF@+JLeV9JMv@H1A?n8A!%FZlWSatVN(X+%MNg#bH!3H@|R&MBHeMd|PE*S{H4y&aOGO+Onm6Y?Pf|_Z zL>3mXL^P%Sjj`r9E`#5a=>NAu0H>`BE8SAT;||u9jn2mZi>=CqRB4o&=cHYt_NpB7 zo=|25@m>$L$LE{%N)=a=cf8~Xy$^yq0-2mF8R&HeRqHQWa~}RuqH?P zl1TbeNsUgJ7FG95EL^|JGHqGEtWED)8mnpA6t{Q2Fh3ExM z7d@+6>C>{P<6#|o-Wtub&bgdk7!r&q_azUFdV*b2_p5qP3s%s2M}?zF)#70G#@!+F z*~Rj<%)Wo`{w>*(mtolly|daqG=)+7~6B*z+P19QjG z*f|dyy2CMkcBiZY<*|=!sq#sR0NA`?IwLW%kOrK~iJYT`Sr;b((MmU4iX-?>OX zuTR=gj$jU(b0ypA5=7UV`GUZ*YZaLN7`^u>(8g4{ovd zPD1R^9Rrb?HKDtt73+6sE!nSS$VA$E)y>1pR@UZ3S{?VO%Cn_$FXhfI|M6ZB#usZJXIlQTkhAYu;g5~8o4gzn@L>`rftalJZ`_s$tPF5( zM{f?2G(R(;EEIK7JzR&Qhz7c&W zE8FP<9Y5L66z_V3Us}Y4KC}~%*K8ElS|~72tYMyLFl)FaNEX3yKd?;Iqt`Id$vCFM z*&^@4T$#wnwALEC1rc3eFLB^t8@}CNsU;`1J;k)&({hp?aJ}FY%rqbKXyK~Yh_ZW) zZjC`ew{^Q+TC>e*8LscS`<>I|l77OWr<0w?-?ae*BUSaVJkKH)pQbys-K&(L4GdnH z_3e|(rfIik;6381nVc{lF7`{}X2*!PC8MMfI|x_wCdm?a?=Hv#YFRmlsr0b&@C_|KJ06&J zz@jF7);@LBit0Nt&!gJQ&R_!F0WE+o=0sM1OBp z7zMiSkE4&2rjEZU6=?DGoBizOVu0qQ2r>aCXRqGLQ4XlGkXuxKm0$@|zUMCqOOK<- zR0f^mM-gjMy5LzO#Db1k>W-5`#kg!|QL`$}DX*4I$(6ZoC)hl(KH|tcUu#D!9~ocz!sohK)1(9Bi!VY%WYQLl-roiaiI_ z?v2Wy7%Lmv$kc2s6Oj7QFkr157Q&q^91UkGE*4JlNRhQ2xOCS$K@`{#W5Cbx%7w?$ z-c8j;A^Y2yyQeCd^w}#nTy|@&QHikz@rCtZE~YGWY1%} z635nIW@7y-=$I!T%K-JF;iEiZ4VSjH4Y$(=lhPmFILqsI_PM>tFXdIX=h1J)-1l^_ zw1szNwDuUkip0hSClv;6+-z;#%f&oh1F4eO)m`QBqObnKV)tDqWO3U#zQPyLpJP={ zLyLCdxx6JDxFd^|g9!`-U7u^aJW2WyK0U9+8r=cyQ_snlyYP;-LrP12pU-A#;?n+F z3ieUbh5o)9kMq#fsXicm%+>k4oN8tsX3*GjIy;SXdC#F~8P~PpVhV=Jby(eundUva zd>PI?$RbCgN6Fq>m!i-v3LK)Ng~xxpJ+rL0+gjW7^oo+oNRQv9Zo}#Wi<$jZ760wj zF=yRro(cI*5jkTuE1&86s8mO|1W;MGQVbV=OFy7YvMOuhxZ6j%CMyXoBX5mmj8q1|P{!yfyvF0*p-0m~O%ux2+%`ih)DbMx5- zFlrS9jj|wl28*eyOXE4D-I>~Zaj2k@?&`bae`WLj$6BwwAOQJJ{Fkl1ujtzzx#&Q2 z7+Nq}?VAO9>#E(dPx#ft65iwra<6^W(RT<*Xs)CcW$P2~O5Oc-4%OXuON24iO#dcW z=B8ZlZq!QKhBBO^pa{k3yd!A5&uR9+-_mbMIlX1+zMGiil%b<92hYvZEYUB&LL1^e zIe2%exdtak9UGgxb*|l}Yuo+p30%$DB42RCsBcm*A*QR+s$%<_>1M6jvhmw!TBSp3 zLPwbC)bMyIzJJyISncPe2>Kkp3iPAeBSBE^;+5X^jt(#zH@uYM->#ZXvSuAsDuhsV z(ui$t1(QN@J>wjD)AfoQe2Q{f46LeLdK+BfD}rxUuN$vvKdLR7Kw%NM0+fT6oe{XR zB<0+&%Z600&>Kk_lA2kXSx(X!mIR@wSOB<=(w9|sA=~C5jHcd(266BHt;U)mX!+^Y z#F)z(K*b=s_N2jB@>_R0Xkz_dlGbZD^)xn*17c$tB|W{F))HLDpKpZ~BApi~ov3%Z zOO>8QN)<5cf@-616{hPU5w)z(sh3US^HCz}5gN`f5Y`G5g<~O+j|&le&Q#RQm~ydv z=L=Ufm~|I$%Bm31#odtNQu2E-bQ;z}t5$FbbA`UW>4WLsG*|-@Klrz)@J!q}(y&hf zu-xCb<|H8H6svHd@%c>LAf$=mY3r0Ju2ibug$u6CEuIVvTG3DIR_DijNu6X)i&%x? zvd&~tD9r}lRNOY7Pk6Kg436A%P>7ff{J#Blm!sPKaJ_Ege*IJ~gWzy{yrE=olK>&{ zTA={pY`jHK2|01m?_}ct-uH1b@n{p6d!Hmj)q<%WmiIU2_jmcJI2Cx#Uwgxnn3LoA zLU$m4P)>Rq)9-Vr>{$#lAE6RYF#ay}M@JKf0BuCgYm=E?;cp19@TaU|KCM&q#dIy| z^E*?be&W1UAFjL}mAj({9jdWddI+j9)))f9i>aBD^A}CjW3Ft24X`6QzzMkSZQ1}c zuiKWtvY!c}xE!0w7Y&5>+-af7{0<{MRb%bnukj3l?DVw$ytWfj(NPn&NUrGNz8IP0 zV({gYPK!p5i1S9flFWn5()qkBI;CILqJ}9iUwdt+hkDQdIFV)T3n0dn&qi4cx{>Cn zfpHZTr%&%PoXCdCC<6LvB<`O97)=BiBg*2AVO7S|;vTMbcT&kk%y)cLnQ zHL$w6r;A%}`7lq6TCR3Jpi7>aI#}F@)r$jyLUNg#`hz8Wa^lWNW!-tXUs9nHUsE!#z}{(zZevF73NR;u8sgl7E#1LEd&dNqew?m;G1KA4C0t! z6fuL~=tAt2L2z_A3Jfw4uM7W+LFDgp41u@QAU2>NSZW*v25C)AjQG331~G~7mnC+K zAk^uP0)vFm5R-@sCppAE4#W$CK`#6w=Olwz9#1$vjsk;xiN9m`Yhixo|8SB; ztgJmguV99MW1Zv>E9VG0+@ruCU*Naqi81|5m3tCMEd3w|?v4V3+++Js;7J&9S2jT{ zaugV3IDP?-kM4way#_=2)%l{jTm_yj(#1AaO`^ZsXkovkOIVT@dKiliXr_}K|f}#J#Gk}ue&$d&i P81bJ0{E?9cBmDXw1>NcG diff --git a/vscode-extension/package-lock.json b/vscode-extension/package-lock.json index e089463..90c2321 100644 --- a/vscode-extension/package-lock.json +++ b/vscode-extension/package-lock.json @@ -1,19 +1,22 @@ { - "name": "openskills-vscode", - "version": "0.0.1", + "name": "agent-skills-manager", + "version": "0.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "openskills-vscode", - "version": "0.0.1", + "name": "agent-skills-manager", + "version": "0.6.0", "license": "MIT", + "dependencies": { + "adm-zip": "^0.5.12" + }, "devDependencies": { + "@types/adm-zip": "^0.5.7", "@types/node": "^20.0.0", "@types/vscode": "^1.96.0", "esbuild": "^0.24.0", "npm-run-all": "^4.1.5", - "openskills": "file:../", "typescript": "^5.0.0" }, "engines": { @@ -22,7 +25,7 @@ }, "..": { "version": "1.3.0", - "dev": true, + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@inquirer/prompts": "^7.9.0", @@ -468,6 +471,16 @@ "node": ">=18" } }, + "node_modules/@types/adm-zip": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.5.7.tgz", + "integrity": "sha512-DNEs/QvmyRLurdQPChqq0Md4zGvPwHerAJYWk9l2jCbD1VPpnzRJorOdiq4zsw09NFbYnhfsoEhWtxIzXpn2yw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/node": { "version": "20.19.27", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.27.tgz", @@ -485,6 +498,15 @@ "dev": true, "license": "MIT" }, + "node_modules/adm-zip": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz", + "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==", + "license": "MIT", + "engines": { + "node": ">=12.0" + } + }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -1791,10 +1813,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/openskills": { - "resolved": "..", - "link": true - }, "node_modules/own-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", diff --git a/vscode-extension/package.json b/vscode-extension/package.json index 715b2ac..2712046 100644 --- a/vscode-extension/package.json +++ b/vscode-extension/package.json @@ -1,12 +1,12 @@ { - "name": "openskills-vscode", - "displayName": "OpenSkills VSCode", - "description": "Manage, install, and sync OpenSkills (Claude Code compatible skills) from VSCode.", - "version": "0.0.1", - "publisher": "openskills", + "name": "agent-skills-manager", + "displayName": "AgentSkillsManager", + "description": "Manage, install, and sync Agent Skills (Claude Code compatible skills) from VSCode.", + "version": "0.6.0", + "publisher": "whyuds", "repository": { "type": "git", - "url": "https://github.com/whyuds/openskills" + "url": "https://github.com/lasoons/AgentSkillsManager" }, "license": "MIT", "icon": "resources/skills-logo.png", @@ -20,9 +20,9 @@ "main": "./out/extension.js", "contributes": { "configuration": { - "title": "OpenSkills", + "title": "Agent Skills Manager", "properties": { - "openskills.repositories": { + "agentskills.repositories": { "type": "array", "default": [], "description": "List of Git repositories containing skills.", @@ -45,59 +45,99 @@ }, "commands": [ { - "command": "openskills.addRepo", + "command": "agentskills.addRepo", "title": "Add Skill Repository", "icon": "$(add)" }, { - "command": "openskills.refresh", + "command": "agentskills.search", + "title": "Search Skills", + "icon": "$(search)" + }, + { + "command": "agentskills.clearSearch", + "title": "Clear Filter", + "icon": "$(clear-all)" + }, + { + "command": "agentskills.refresh", "title": "Refresh Skills", "icon": "$(refresh)" }, { - "command": "openskills.removeRepo", + "command": "agentskills.selectAllInRepo", + "title": "Select All (Repo)", + "icon": "$(checklist)" + }, + { + "command": "agentskills.clearInRepo", + "title": "Clear (Repo)", + "icon": "$(clear-all)" + }, + { + "command": "agentskills.removeRepo", "title": "Remove Repository", "icon": "$(trash)" }, { - "command": "openskills.installSelected", + "command": "agentskills.installSelected", "title": "Install Selected Skills", "icon": "$(cloud-download)" }, { - "command": "openskills.deleteSelected", + "command": "agentskills.deleteSelected", "title": "Delete Selected Skills", "icon": "$(trash)" }, { - "command": "openskills.sync", - "title": "Sync to AGENTS.md", - "icon": "$(sync)" - }, - { - "command": "openskills.switchBranch", + "command": "agentskills.switchBranch", "title": "Switch Branch", "icon": "$(git-branch)" }, { - "command": "openskills.pullRepo", + "command": "agentskills.pullRepo", "title": "Pull Latest", "icon": "$(repo-sync)" + }, + { + "command": "agentskills.deleteLocalSkill", + "title": "Delete Skill", + "icon": "$(trash)" + }, + { + "command": "agentskills.openLocalSkill", + "title": "Open SKILL.md", + "icon": "$(go-to-file)" + }, + { + "command": "agentskills.installSkill", + "title": "Install Skill", + "icon": "$(cloud-download)" + }, + { + "command": "agentskills.deleteSkill", + "title": "Delete Skill", + "icon": "$(trash)" + }, + { + "command": "agentskills.installPersonalSkill", + "title": "Install Skill", + "icon": "$(cloud-download)" } ], "viewsContainers": { "activitybar": [ { - "id": "openskills-explorer", - "title": "OpenSkills", + "id": "agentskills-explorer", + "title": "Agent Skills", "icon": "resources/skills-icon.svg" } ] }, "views": { - "openskills-explorer": [ + "agentskills-explorer": [ { - "id": "openskills-skills", + "id": "agentskills-skills", "name": "Skills" } ] @@ -105,46 +145,86 @@ "menus": { "view/title": [ { - "command": "openskills.addRepo", - "when": "view == openskills-skills", + "command": "agentskills.addRepo", + "when": "view == agentskills-skills", "group": "navigation@1" }, { - "command": "openskills.installSelected", - "when": "view == openskills-skills", + "command": "agentskills.installSelected", + "when": "view == agentskills-skills", "group": "navigation@2" }, { - "command": "openskills.deleteSelected", - "when": "view == openskills-skills", + "command": "agentskills.deleteSelected", + "when": "view == agentskills-skills", "group": "navigation@3" }, { - "command": "openskills.sync", - "when": "view == openskills-skills", + "command": "agentskills.search", + "when": "view == agentskills-skills", "group": "navigation@4" }, { - "command": "openskills.refresh", - "when": "view == openskills-skills", + "command": "agentskills.clearSearch", + "when": "view == agentskills-skills && agentskills.hasFilter", + "group": "navigation@4.1" + }, + { + "command": "agentskills.refresh", + "when": "view == agentskills-skills", "group": "navigation@5" } ], "view/item/context": [ { - "command": "openskills.pullRepo", + "command": "agentskills.pullRepo", "when": "viewItem == skillRepo", "group": "inline" }, { - "command": "openskills.switchBranch", + "command": "agentskills.selectAllInRepo", + "when": "viewItem == skillRepo", + "group": "navigation@1" + }, + { + "command": "agentskills.clearInRepo", + "when": "viewItem == skillRepo", + "group": "navigation@2" + }, + { + "command": "agentskills.switchBranch", "when": "viewItem == skillRepo", "group": "inline" }, { - "command": "openskills.removeRepo", + "command": "agentskills.removeRepo", "when": "viewItem == skillRepo", "group": "inline" + }, + { + "command": "agentskills.openLocalSkill", + "when": "viewItem == localSkill", + "group": "inline" + }, + { + "command": "agentskills.deleteLocalSkill", + "when": "viewItem == localSkill", + "group": "inline" + }, + { + "command": "agentskills.installSkill", + "when": "viewItem == skill", + "group": "inline" + }, + { + "command": "agentskills.deleteSkill", + "when": "viewItem == skillInstalled", + "group": "inline" + }, + { + "command": "agentskills.installPersonalSkill", + "when": "viewItem == personalSkill", + "group": "inline" } ] } @@ -158,13 +238,15 @@ "package": "npm run check-types && node esbuild.js --production", "check-types": "tsc --noEmit" }, - "dependencies": {}, + "dependencies": { + "adm-zip": "^0.5.12" + }, "devDependencies": { - "openskills": "file:../", + "@types/adm-zip": "^0.5.7", "@types/node": "^20.0.0", "@types/vscode": "^1.96.0", "esbuild": "^0.24.0", "npm-run-all": "^4.1.5", "typescript": "^5.0.0" } -} \ No newline at end of file +} diff --git a/vscode-extension/resources/image.png b/vscode-extension/resources/image.png new file mode 100644 index 0000000000000000000000000000000000000000..66e9a8e843e6749e59d64852dec9adc278ed01a2 GIT binary patch literal 155592 zcmZ^L1yoeu7w*h3bcb|zcjt(7Hv&?EbV@f!NJ)oumz0Ebih$CMh=71}cf-5<^8eQR zy|wOQU}ny_=X~co`|Q2HeTh(0kwr%#Mgf69=<;$>8Xyn?@GF!Y2?D&tk6PS=K$IYP zsi#_=;NA8sAI;hJhnqV@i1MVkYNy!7Y4%U@9N}JNNpdR$jf8rgH#?NnAGs3Aq`*AH zXezk~N<$`yh-m!eAA_k7%z|0<2vJo{Os9M@_>~=1OEMQN=xM}EF z``9Y}AZGpMNG`E8v1nU;rdQ4O^OLdf%#Vk`X^C(OED-p=t{`6e!_Em$J3?ZlK+u0( zf#m^M5F}(ZN)Y5fuDEq5W#Ggu!ZVjQ|JfP@#e!n}SGORfLLo3xE^lYIQ|5p4`*<@j z6b${Zdx9X=Dj*2sup=ia!+&=zMIT6NX=u1G62smfq2hCW=jtld(vlTZ$L`Ap13~}e zqRc`HVF~oUxmKOSJ9BB7_v+iP7aIAotFkH)Q>TC$Q@0RfbYyn0MRq}vakoo!GZ({t z!<13iSS^v|z|#l$uVHe=BZtsEb}7N`I>CR zs4A$>5EKDwA!|1@nubT@jemG)vil#9#Hm0(G8FXZWn^yBQ^?|jF`gSNz>-v>ae1Z z1BF|5zhhc`zVGeodiwu@^oS5X48WA#Ahxn~3 z`RLVHP_X8|XmZ9tKjXp{#GDCW^35n{5G&Ho^i7~8Whm0GG>K3LowjGasZ@(0K~~lA>U^O2Dk}SHR-$dTuDPL}fk)FQ zAJ)Ow{~bV~05}-3*;`;Q!t73b<8@?}k%Ynv<_W|nV87e4i|X-Wm+vsTF)D4h+&-nL zw3o+;#p^4sWy2J|m7BHBa3!U9N|}aCJ8FCamBP8>3E*B*_=1le#Mp`UmLz>RtvRWMGGIm~>!P|x9x1J@sf{)ir8y{8$Hp0%D2#+0Znvx{nCLG~oa z6+4#W=B{G|Z4GwAkHyb4_!O%wT}W1HG3ZbTB-<~mv$4M*u3dYNO1b48f=0RigmlD3 zBFla}DUg~!hz`7zDEF3rK|G5?yO0gBytB!P>EW}QP?ZWN{cp30@bZAThqK>FZ^$;> zq=aD~r!)Bw(8KxfF zAolE7|FxZmh@@JjkATK7Wge zcYa)=w1He!e?EncW2SRpT7s}0lpuqRof)@GRQ?fwcwJXoP>Sjo&Y>8xgy&IjTn8G! zCUn{5(4{DqVX4JW@8e?SX|Q0z#u10AbTS|^$AkA*U(H-tU3xHC&4&x@`#VpvMA%$T zaD)<(h?4!`djLCg{&S@yprOest$5Aa%HgieYu}}{{LE*=GHN#E{p+C>2CxkRB)mtK z=r40jj{&ZgFc|Ql_fL-P@p4eS8sQ{UtA~{4<$W7>;m^zo3!{(c!kb6SZNI^Y>#%mP zH_+ABxmLRRrfIn=)=mw_I8i}iGyL85SF`;1RbT)1H?@+e@az<~&nZ(8DzQ|mTc`N} z_CxS-{vHuREWVM#47Se86HV(4gd~Pi#tdeLA#Kb=FOi67tFg*E*Sqgmpduq?SZmLv z^BvM+2>sVf@K^NZqCvtx$9($*I?^(1V|JduocBx}?x=emJ7ux3Tx_KSCAsJ3IoKIAspA`g}!2OuGHB2fiLY_gEmeu8R+KdCnf5DO;L#bo=F+kM$rJO}Bo zN82?=zmw*ZmAhT-89(%Ow_LC8k;RIiC(0)}cG^$;ejC6$Ia8_SBFBpJe`AZ;e2v&jHgW}z>d<)?Gf%I4KjN|fv;K-m|G_tZb&4id+ccWzJ+xwed1#OWYwz(d+4(o@(=(-B{wDt2Z{!m@8XCQG$^$;u4Z6=>)D=G*2HDTE zIArjq`7?VQxSe4()RSj9{)=K|#S6&K!W$4=ngNX7D!G*R$Rn=`|{+-*P-$ zJNkUcCV)=C9c=EloQxbKXrb^MsqY=>36;-Q++33_W%6E~(}k*DWV?)`qv(7${4|R!4eK7SP;C#J9jD(gQc6R{S; zVFTmB|9BnBET>z{tOwZ0T}+In1K>z_W2H4Op=AL^92TjB^SiBA;`egKDuPd++>$ zy7G%m+n87T_KEZlydLgX=aHZDi$)L1olj52c~@l{m;7Z-$0v^Wp72|kU-`|ZK=!ohzcb<=7?ssfd9avf`yfxvAZS=U6 zmFbJ77nHwm#mQ9-YnH-F%_fc5T}j;CGElQCeCmIyXKy_Wicf(a&dnNETCo z*YU^g(BmwCW31`~P7<`>wc(*#t*6^kw!3t2yYF!yD-zr8I$?33j+u!{nROIt18|%q zrP(Va-`7W4@WR>FE0n4Kg?_`dn}2S@{vmF&OA0&7{vIk@>>ECZ-N9em6s$}4nfH>F zcZfSK!!8D~=_#0U+x#YXeO zbTKKsx z^4HDg>MpyQ(QuaX5iN#%P5Opt7E_nXj&PoBDY8ueypUu=*E>~ww*G@|h|5L?wa-{s z#TXedka)DQ=D-#J+GJ*Qs#U1sb4{A?!69wr)>z)deR4Byz1smS7C^Y(>#_v&qR+2H z&sXi@yYkIXGbud%jfV^6jaj^ZYzs@Avmdrk-_R>x>wgQ=z&4#t+xID6WYCBNELOAq zgt@R={a#VP)ocJR#LDrkW8Sgz+3$mRyHA~j}CWaH~mpW=(U1a($ ztb(%x=}a~d*Vmr-a-7^`8CoW#jA9NAd>d}FRhZp!pbD&*Syt#GMdWNs+@zO-2j3i>zc0W=&6qR}MiwIj$*|I$ zXv0Fa2%9N=xg0w9u-JdxX(m~d6_i{Ww#t{Gx=*`5r_2!CAR;s#lw!%I+}SlRj3*L; zr^bG^xIde_e}{XNCblEO%i9R(tHy>CgZIJ`NRhrn$@NNX&eGrzO0Qgo|GM63He^uQ&+sc zFd7bW0T=QZ84XWMF#4hSJsZVLN=jkcVv`=s9G}avf~w6Q;i`%!>*oDPl=~9UFsp5D z*nDc)yUc2jn;I@k2`ss7?(yEJbMmD3>32;p)UP*KEFIa31ELenAqDpyH_Bx26jAlT`3$p<70$}Uq;x$L4jvxW_`9(PCnqnb;7^|s z?Uph-c~kY9h?tO9AnpCRM)zlWgHiqRAi8h#V-s~OVnmUv<_5glNS)QosYT>ll5VjR zxE-gwUn#80;x|$A3GOeM^$5u&2w>^w3Zma}wcR`?7z_KF194|xyHFVpN(Z+T$i*JU zca4Nk3vY3%J0) zw<+rNQy&f-9~7UNoeZVLqTm8=iEeB!>DE2mBa*iO9ut$EN6w~Tkvqj_lr1Dm|Lup- zhAjR&{|Vto_egu1k1WgZ)TN=Z`XaNuZYNrB!mW7T%^&uh)=e3(S9KSe-%U1s(v~E~ zofST6pyrlcDBFt6sIv*SzF2V``q2%+0)lb3n;jr_i*1Z$U0 zM8F(=27JucFEIMz+#;1_^TjqF?eC~Ijvv~`A4D#J$ZHWG*^Vae4zY6b1eSV!AM0G! z4sL2gcxiR_$r{ugL?-;R4Om_2HS&y}G-imLXy`-%&6C34@NfZQyg5NdL&P>I5-bXs zecOnNEzAQDJYbdve}w;b2I$@Har@ zByb{?AABUO#eq2G$qz}<-?kQOV}v~%a>mI1RNc#8N+A?vWV|op^jB|S{=Q0hTh=Y{PtK}SfU+d)5P%Z(J9XF z4Sl$of2jTB+xmIq7G(eXb|@uhiQoG5+J5^>`PApEGH69^MlX@yKS%iV$@d0uY9#8` zHu7J)DDE_NoY_+a7M7Rtxjp^E(mx(9z2!5HCIMgMX6!S|QrPeYVs@rIzL2uU;8Xax znXcx!_?6|=wP`ezTu!A(-Z&EqbW}>ZW6hF{VPm_7-xL+Ln=V%=H)ol9J{CLY46iqa zhK;A3w_QK_yTzQCXRdsr6Qv5T!g2e$>$KG~hy{~Ega6w%06#VHB~!aRXDB9u1^3in z)LBre{2gDm-<+q~FLbn+Pu8u8h^Wr@DzMieVzGgN5YzMY64^RF^mC|aFZ#&*$4sZ+d;Z5IcZ<7?YF}Kj> zLq_=%*lE4fJ>mc#iuX|6=3R@9Kv9I^wKo=TOQw}#pVR_ikf+{_F_mF&_rih#NUqjy zn}p?zG>Ows1>|rEIz=;Umo5EkPL6<68<&I%)hpiK`z3H1ucyr9m`kwZc-ft2BT{&K zPW+xfIYwb-X6~gQTcKQndIN8;xa+iBBhIV3o16O{#5nqD+ST9Yq)+t}YO9#LV_nfzR=l*JPEpLs!QHiQu)L@q zq=92;cP_c}S~EsyR`j5(4IYR|hP)>dc;;&x%qIa8eT;zk>Jp6o<8}ulat}EUj(JIaZr(%ObQL(1fP907-qjQ43)v8JPPk1q z!*;j1*E_Xq!^3Pb*>%geyu7@`+&qGWi(RqH)k=<8p&c>q{*&nx=vE8q)SLQK-u1KaC{Y++!6T6_sK2kY4uX;Q?Qhf z_}bch=nV2hCm-L<)@$|6+By3LG5-EJ2U*9)f>f6GM{EoLrf#J5Gx9&#ygicdhbJXi z#Mn*-Ce9mIXyy>*LA}41)lNIg>`+IYu*t@;w-yXAHk$c%_#?CGo1Cy$SB%V-P(Q7x z8++fbJAxBs0CRk=D2JZkO@_$z`)KTG4?H%Sv5b^*JP74VY)-2owDX62t|zMx{&EpN zI>8t81mdX(wU*AXn(3{o`#wOL~D591Up0CqEP{|j{`ZhbYNO?RvzxUCR{H31W(cRBRL^r(GNgE zQCfZzSpz z8zNwJLK`q`3W|+?yyp#e^6K>vg*t7i=stAi?v>#A#5XgJEYb^8YS2H20+yT*WE>^8 zF=v|LlotL<0=rOUxRU=ubYs66%;hA za2=35bN}~#SAB@ZFY;eFkA2G#0@BW=`b8E+S1d+QL*jz4r8CN3jV5AYr*)|HAV>ri zRuE{Lf{=UN*09L{3LoTeUO{0 zkc!8J>)b9NKkSr~npuvXW$8lW7Sil8VDqHyWQH+G9j!>@kGG_SV8KY`RxE=yvHu-5 z6fDm0ln9FR43HJJx82?6NK5Q7G8Rmgjy8>7)kXCss(`X;L|R+2BAU@R;s0ny$pz)y z`a5|Gf`7?}52gmE!)e2N& z>_31HI;D)W(-ivx_qR_4f@H$HhnhGe%^&9m1uOvAcB zK_8)Nj>ZA9sjE{&bjYQH76+pCBGa#SHigYDH?&eKPwFcNEiUGA%zuDN=f~$?xwyLu z0ooNhsF&`~a8F*6GHt^>9Q|JqPmyWAg`k)g;sSlg0r|Ve>W8G^xpC_Q(bY}S0;}Ab z9G(S3)BD5ngwgx&yOyKhN0~niu7}*ompBSNN@kqSNSmsKPWb=!s1e`wC2i2O(3uWU zTyUNWjLyZip!%ZI$%^!`&59J|69$*?zZ1y7JD(Y_O62j< zvjm~kxG>zes4^&jKpe*m{hY&}NB{4BE))*ZO3R}fp``_ZL;Pa?JRdcZVaH0p0Jr++ zpOuL_hbCC=$A`QIQ_)EPoYwN&mA^m0r+(x?P!o>acQn?$jaov=zk7zEA=BDL;>=)J0i#w+}{g8fZ-5-tnld&Ca{Z$EBIeRQ6Yb^ap2jv0D}vm zK@V$35AqRC*tCBPvnzxS>kf_SH!a!|0J6U>lNU%*5~FD!HKou*eIZOtfif~bQ#p*! zGgxjp9$OXS1P!Kg#6~yu-13Qu`i}c;;rOq5iDnOu-x2lxkG3r54H+NyIE>Czz=U7L zv5iE|&09wG#3D}RKoN!qV}-Llc7us-JT?x43+_pkku{sQ-fpn)6O=-Aj{C=}}{!6Te;oRDtPv94d7<^l`wX1J8^((o|;F%y9>1#C`! z)O>k76iP~LIXZAiKh@UyG7VB7>;rC-?^Ue@4%X{{%@N{^3pvf!hwD3vCEtw!MBQq` z_H!oxe*vLHM)q|&`;l?*;;MS-K|Q^XFavd53k4qQ7gR$A^e(!|>n9^%A_HOGSZW7| zyrRBbVqy4qjA%oig+i0n{&xed2LY!?OAfcApE4dquNh_jt_5(}>pLS6_?KcJh`ijd zfGVcR*;Fa_+nlJdg<}eFJqF|*m6YRkkg#gn`2WcVEQi|&6tqC0{DL= z{C=jF&hRcK=6-v&y6xeJL06*Lc~5u>bBN#{KB8bXx!?6ot2#V>ZiC1xEKFR6@Hq(w zFpEqyfrU*+e;CDyut3_tU#(^@17u`nm;4?I%5z|Mg{q3E{ z(u3Sxtbr5En&*L{ItT`ON8oje`nYi7kOUAUHT>R9(ZvC{(Y0~s!)kxPvwh56%zwtS zjr}+t*?`unMa=MGF>K`&&PFI0puZHO+GBx2&=C~~{H0lzH!sgRuH|rDME5@Ilw#NG zpF)7Rbm;y0w|4?d&H35OWAWj|O1@R0$5QklFmL>UcpnBp4?LhGVUu5qH#rYE&SE*Z zeD>qciQsxwf$bmG_wgoHNWQQ4`rZPg5c-xEjIEq$)e`#o|LNn4eYh3QGtC^6(DGUF zcNR0Dw*ScD6A4{D6uwR6+o98RuTJaSZd@EYUDmGOWmxW7Zc%dVe(+vy#}ro*eFwBe z=O4{m#a7Nqc)1cq*_RB0jy0{wZafnC*AWaP-Lk`@?Cpwz1&hcj$(Q|Wh;sgr&a1tH z8GGO2){@46!#9^i&c^qb+e=kTO;C22#Ixy2#LduOh z(bocwLP{rp6G4xWHi1RoK_|{m@3rZi^o{%NWZfcs@yo;2S1dY?Y)j5}eac2}Q;QT2 z0nPzx36drV`KHcmFvhs^`XNcYl}!PBx`;^8p=J=!Ek=yJ%*hk@C7SVe4$oobWW_I-gQl847cso7S$pi0lt() zL6}nYSr&_s00Jz9z>>em&iMcUXxn|C!6U+_kj+Hf+1Q-j7dma?)QEWTAW3qyNHI{f zW)n~!03}~|15-lIEN5z{C>0}^k)VS_c_>GWAxwd;+*Y5lh1)PV`pu-;l&Ngf z4PuBllZ>g=S4uoRv@pV=R`Sxd;z)-9nr%nqW6g@+@5(E&YquE?J<5&Nmj z_RVpHk8oi>2^<9tIT1ThTp~qT1q8F@$1P7*mHggiQVM173=7gOG~)f4xtW; zY_7gHK%QGxQ!MKhZ7p<$v3Vm9x0mRLJ>$oz{R}f$oA51eXzvgaSZXOy-n#gTpc&JA zD)&|AjZU0D9YSSl48!Nl;*iXJwNS--34n;=Ju)CBS=hi$+)9a3O4%d@jtxxfSHD-v zTTY~xTUcJ;jxa@D>Z!h~AX9zcLTi)|sa$tYyPsj4B4JW6?YP*=P}0{Y4YiYOnZ$6CA;b>z3Dvjcb*!vqHo{w{`plM= z&$Pc$bEI7vs7y(Mh;DU4gq|V`jpw2GUlrVPK*v0lE5;oaaIxOV+!2nx3W-DdO<{ zRVc)qe&t@yX_)h`Ss~?~Aqu;*Yh-8P>q;dfn&TapO{D1ouwLMGTGfX>Hxl^X(0W+H zv!9k9lEn4uy1p0jg~G{G`w_XxAJ&@1BOmZ&=z#?C7cZ;3wzSD&W>a$uzW{xA>sF8V zPwivsUY}1zBhK=}K)uI1Sc45K)PZ61NoeV7+6>o8y(;_rDaX`N-)ftOOI47`3JYvZ zRZNp-ox`Lp>x+12kL@yy412LEKNL*sdu#KJGNF94tHqmjEt_|m{}5$)!z;iY$a@qj zNVvWmavS3xG*5v2c5i!yx6!t3oe0f-#q}Kx%WuN9jtTOmH3OS;{on@P*ZTJMPClgMhcW_1Kq*ck& zi#usEia05R42*`a@xJ@8OAR5&6L$;`*1fA**bS_(h^@i^K8GRE$Y^>3_g&+-;-lfj zTgPMhB86Tu84q)X$o;;&^e~*phq(o_>!OjyJ-sX$AlJ}R)ags2qxR`F5m`1|xA|dp z|Lydp8-47>aW}$F{ZK_Th3HFm{bsw~fmbXkL+Py|39i|M$hqnn2_uPVZle`+i<~<6 zBg5eK64W`{im7T>Dmi?X_{3 z)}@}}hXzrzh{Q!&1-H<8QJnQDDdX!gy>It`lOk*??S~bIgd{>qe$!hgR`f0$vUV(2 zUiuX;ju?v#5f_}GI00y0OzLkTSPp9?>&;W2O8b(b7aSU1>t?YoaJ@otsEK{#y9IcG zQ%R>)-e)#~A38tzB4S2hN{R8dM4}{A7OZYV-i{9D%huZ6qEZqQlr$Y^A~FdHx*Z5Y zAgj_aO_1N^`1A;mJJUr!EF|Ye>;1Wi?xODw*;o@-|T8G8v^0>IN6B zRS3ohM+SlP^%l(P&URU5MnL(!H2EJpVk)s$cX}n0-#xWv%g&B(E_{8F5It1!CfGTE z&oz)Jp2mGID=|6Vx@tFBb<-RKuk$V*WMkl?`Z0+SDHpcFbjnn3fNaaz!;r0KGVqD@ zg|>QK^~#*~j7I!vZ1+NUQzLYBugUc z=vP@!q<~WcM!;)jK6V+pS|k3fNHqBVMhCw(ISfl3jIKyQ8R%+`#YBGhhBol0gFs5) zmJ%b7r}<0;W0w(~w`FI-i40K!3qX!=VF`LzTtmiMQVMd>F)YaP*K+JK=AWE4a4>Sh zw+}(C?08(|(h1N+hj%Sy;qJ%uTLm4x!eCTH+Lvmroc;u^#Oks!G>?H>Iz+DI;$rdP zaPtT^;3~j)whVW?EH&UP_A z1rZ`qF1xllf>B>U+;^{P(DQ(E)B7Ssr4&SL&z_l(%(dY)dl>WvVEtTc`%dNUg{y0+ zY5P?+h50LUm3B*qxufl_Jx7_hF^&e@C*n1d120}|v`&?HZohaN>5`QELbKSiI>1@Y zT7z}^X-UuC)7k~%oIlWTRU;Dml78%N<$IbOefVHgFF~;LW|7_It71IWI3kh zgGPHfjyzwukqpNw6QKUIxUUcgd79{6n!gY9F|j)^|H0Q>*EUw4o1bW3u2k}QNo~%s zb0o>OQmfjH*bOs>!YRry#h6vsXvv}G{p%B&1%tP!xidK4d#T47oW|EmfbTVgmfMDs zLG?3oZ$M9Nyv(ge0`BVtd!0_}c&M|&Di+L_`tu-f#5ji>E=}VFCR9x-QC$lG%m-#y zqXj=rZa!-EU!{LwG{gbw=7O>8w@cBtweU*)Y|;+63R9$L{Yu3h<1kYwVzu?^G|QZ^ z;pTY#Q-YuDY!$vsE32)4#zQvCs#a&S+YP~Re}PN+sd`QX<4u<*cDNR(*BvwWa1RqX zw@H|?(waS{h$qMsg_5bPztxB}9%A)7H{sH3ap!n2HE=g$)z*S>e(Cm0OXYeOziq?! z)c($gBeh^RnZ6{VlK~7;Vb5G%M;V#*=vT@LpM#w!Cier(Espk|wF->17;}j){>+c( zk=83`;0rbC2s6U|X}a zW-V$X)3^i6fKhS9Q(Oq+JWFt)<40S^?An{ri-4DvzT;2g`nW7y+MwK)c>LjP0eT_+ zNW>Yi#>%XeG`_tO5*ExE7N_Gc{?i%wq{g zuTh=NX~qQ99|%hJ$g+5$M;2Aa?Z?daT}tvWt;8LY4jZKk)WjDE1iZeuR@prH{Mgjw zA2`G#JETNk$RDydCH!*p)cet$?il`z^rgnHECgFM1}|9??Bye8d1ZK?8xidS5(d_Z zp?>lbs*}A&X@aEism1XtKtq2Fe%?N{k9;G{e1^S+;|mQsqUMZ&FjC+2z^mPos!3_; zXsN(KtXTtJB-hn(b8j%+_pdtdWu?ZaovEdHW~KDgynds!CO*1ywH$=qdE;3+wG=b^{%4(xUEc2GvkyOWY7V}Iw|87JyxdtU+DU-*-T$Eh(BU}Y`(K8a{>Fu28=93KL-AndUalyGo~|g}yO@Am zH~irbw@xP%|ICTw8HQZuTFICBj$)MntGUSO8{3_4#A;y}mXgWV8KzZna$IrN`L?0n zx!*5ev+e7IxMIC?0e9~la>u^aLUJSSfgJEYuX{;H{7xNDF5el_Es5SRj&sJi@G^pD zDJ6WrpuRuR75USUbyP6*FO#z^NjwocNgI7D)*YllA-SKj<(CLfjHuetopvX*$8z3diSwl)3Rd%dN& z9H31GTt6b}ERfj-QS6=>fS5j8Emt|?!?N@6*R)^Jy@Rt^794wS!?jUijrO$>l{D?X zBzr(oQ^mB%8*#I1FwEXw8QoqitTio8vCC=%yCRpy?~)0LGMy$L$hdHJBO}4XEpvBw zA`touLi?ma?Lc%6l*>t(2Na@FnnA2wU3tI1h>Af}u{&ZKMlP%bZ8K_eduvHd`c(&G zeyuoKTy3cl3k>OJDs_gx-O~LMS>YLtM0u1E5`@yp{L(d%jd025Kk}8PFxk>ngK)R)OU8WUP zhRT896B`W6Ipo^^Ur21BXw<>v z@w9oFV3uNuTjVSKn3c~^tMc$ib=^&`*LBvY|5fkNE zWIa(>oXp%fb2oPQz-Vt4dr7T5(AxD5C&t&Yf`Uiz9;uxYLV1YPzd~sJoJ)+x#oL)A z{ux!rBcm24OWSQC=6G8V=lu5gf1K%I=V+t4pp;v+=BRs&#z#JJ87`*N26IGUPIF;$ zr$D~09yR@uZW$$?Cu6d_ZyBIbX_Rf79r_5TQJY_H40k|bH_Bel)Nfb0bwa^;+=;6U zg3kyzTEwvm*le#>bSSE8QWG+}i)(ZR#ekcPY{O!N~I<7!wy$ ziY*XLkW#!8MTeg|pqH;qo>CcpENUQQWNp?TeU^aHhm%97u#h!8wKj?@%A-1i$824x z0Wq$>**+yfjMqNKLt-^O@|8=fmbY=qlV9Rmid{12Eb}Usq7AjR7OM^PTO`YFj1rz- zcHK1K>)NUZj*0M#b-(b#f^2JV4Kxu4K{iI`zuMedle0=#bQx{Ciz^*393how_?*?X z&6YC>K<GtR3FjxkG*m_U=vfqiJ|!;Z1i*KUTuLalQC5#W`o9LeYyA z^B$k`KxDPVYso3+G5*cbXJMiW_t;RB9XNJ?C&Mxggf~lVN}m}?U!PyO&IUf7*UKI! zL`YhZ3~Wt)?#?-7B)*i%BM{&o^QxiOPQP|=oqy4Hld?#QX4Oz$7sDfk<$#rEJupmF zhY^FZKf#f$+PV(&F-_zsQB(ah-BNwAlRscEqO@}hR{T)uCAJrV_(V#YlqZk*%C6U-^>te~D zQ3K>tCCYjOF4DMJFjFy&@Xac+FM6B1AdoOoAXnqX_{uY8^vNbDVYes1g5!BzxuMyK z^uStw{lGcNAj($zHym9m4===VJ(oYf2ZvQ50d#VE=KXcK6{8MZu>b@@WEu0lY& zx0#n3iw8XQktzK8$U8?*^=c%Aj68|l?ei_6@p?gtf~CbP^K=%U)p<;P#2`UzCyz$H zcB@!w5m|vMDj$PqH_fF69*qv!_6;dX4*vY#M~Qdr1}%CF_;+GVhrrr4tm`OlWr7kD zvvWVbPvzd$XYIPkHbGQMFt=uNRfe@BiiDQqFv2pwINi8xP0%6bejni*|K~9`Si)m2 z+pxuz>G!F8x`Va9(wP_i3g%nb5K!0;;yJHzFyxJpm{Ji8jwn^>Nw;%R*IVnpPPbA6qpwA|%f}6s za?kqJ!D~q}(H+M_$R7A+j)E1en2^Tu`O(V!ad9faaA4!KVEIY5;aKEs{QOpDDo$s3 zHQBYcv<`IJ+I_FF7fr2xobC_V66_Z^S-^vvAy2#ZVuX{KqK&A_Az-PxxbWRrm1|W_ zu`jm&66fPl*^zyLyVPka>KIAVj5WHPvx4>7ES3L#~V=n48 zE7DVs8V6Q7=q~>mf|?XWj^R!gDc8W*pU%Id>1=u<;9;XA=VA4Fc(i)q5>4Xq%YR;R zTF|Pc+uO;}hoh^dhpS$;rQNleRO2#uwHJwjlB0U+G-r>Qs2DM0{aUWfoDXIQjrVyQ z`BSp*umPnqFpwX7EuFdu37_zFMF9#W9xhjAhDYzSwGu_4{|LJvNIKNP|NJ7r*IDrv zRp$--*xF#~r;-nX=`zrKT-e>X4cS(W?1mXJSHIfh9-#~jJT2$=^@7-M>_~h?3vCbc z73gj?%0M9QEVz*2FXTZ%Q&di?>l>fJ)+m&;;G*$ePtq_5m=|MgobFKpa{?4$E&><< zhf$mN-Xw>EU+7PY;Q+%gPycCePVaP5*BRifs0VRBTIt1}rszP)?j)u8-B}cRJ1Z#u zR9c7)5Oj*x?0a*8VQEBwplZAjIX)&03?%R=fL7X&i^vy*zmWt%x{-YEF9Hy7VWP-L z5XNNsJ9#V?s2a{sXb6BcXARI-C{5tyZP-IkY7FT5^dtb9p|vddw_FE8qU8xvm3WX9 zgnZp|KM_js$HC$bq(A3*%k7Os>5KS?j7cWYNv{sb@bv!bGBLw*LzjEh_Rn&JKUM=H zXh%ST0Kynn-bESM=QWW7U3dnf>sE##0n3e>0SG$)@@Eg-Hh?{N*uj4Vf>(UN1`4|9 zwPziC&wuP37~ihtc!wE(!n{NHUy{f{#CocYfX|G4?)(Cw-nzb@1xTFan!g~-(wpnApsMH(h!3mx7#WpHcFyUir3|x zQZ&w2j(|{PLG9<)H#D8MF4PQOo2Y*qH4u~+IlAq3!^8__ijqs{0B7zi9L1s;0<2)< zPsR{rK)CFH(!T*sJZuz0QFEg@Zzlsf{iR)S!h-*2Ysf(!?yi%84-+kL)K>mr?W9NF zyLcvG7>8nicpA=t7HX~p+A4f_(d4we{YjN?Lj!rcMbU}eo8V-^c@hvtjYWTVKX52Q-E*A9C7Fa0a^KsOs&+5Wu$~3D5IF_ z2nYv?b12b)Zk~dA9aSPy{*hJ_G66)0hc+}{Apr_?X1m|zBhEqfK&1v=2Pj|5@{TMw z9-Q=>$1nu(Z=S=T`2;Xuip{u5W^+(cWJQE*CKl{a;So2^5dfJ}OJ-la))>&rPA6rc zl}f}vm0hp|+%W=}@I2_q3p&nai%ue0On7_YG6)0TAJzw2%?3{hw z)-xx7Cjq(blb(uNMy1(?f9w_5yem&Z5IIflUnZh|EW}@fmGc1?=2-h)9j_6hOCDT_33F$9{;rfGCe93?sY9kT8J1_-yD&v<>Z8rNo12 zP2~eY3Eopzo4X_{OWIlKe?5a8_Zz@7K`KTmgp)Fm`Uz~LK}^w7>08Uec>h60f?Lko zTuYUl0nG1l9g%?05I(Nsj);tm4lH#pdxzm^jcC>52)6Y-D)Jo`Gnj=mo2MZ_|Ng?S*Q+C!39HJ$FLgD_lKqQ`#Anx(+L)e{KJz%mj>dLkZu-9AN{uH~iuZVDiMbU|zUIii%GZhSJrOor_@1>C>X*mbmn$0) z;!jos>#mwnS4>vf*iq4gFj^Rz#F~V*X`B*}aR<@8D;5Bl& z8IFV#Qm)gmwC?aWk)EE17*OSvX#BE#o_91A1{)?9s5FSv7f9doku8f!>oRDcj6PT&?a2~zzAP3&+2eF@$1M+gXI51MyjnUZ2tc2?) z{h=|-rY^AsJ;s|n5S9h!GLCVKenotxt~_k{p8h`zI{>jQ5TwwCnD$Xj60{|je1-Fd zl);_gPLSs0=}B=|RaZdcg?6r1uGr!b<*@KKzmML|I(;j5+fc@}%h(+I6NJ(2OvXFs znSucpYE9KUr!713={ zv>=9z+Nd+HKdye}J7n-3=e|JtDXS**zBaFmHyLG5gk~jgIXoK2pDna|4`HK+BXdun!!f1awe(J)?!mAQF{Mj?~6et-p^uy7=u2^Nfe3z>FKT;^Wsm7`-LqEV4J zPT1X+J!6Li%j!Mdn*B)E45WJRs032!FjmeVLtMHyC(Dzng@_#ZEi2IZDTr=s0qr#f zwtXZ{oc~hs(gW3&D);FIBX4rE>lV(iqa;f1^0KKJ@X(@`YB+)dKX#aOgX;Uu!ecj!XKKw0AVWvn&f={Ym3QMw#rEU`$(*>yT0y8=hv4 zg|55+nH8Y*2+#P%ggw?Kby^gl$rydEBC^2b9Jhpu5y_4Xf7aw_C)^&Td8<;Ev0`|5 z=qcL9x_v^E(3Gc{?$<2F5#>rH4jnI^iV+Nd`14<-&?W@NfQZS-@j04u19mh<-&no* zVyS$6!gANFcRei4MNJ*oKm_Y&j?@$M>b7<_T}p$} zEe+DrFVfu-5-Q!@4IPJ)zH{#Q&;9Qh49Aec`|h>on(LW! zJ~OsHAbP|2)&u<~1&Fh3;w#E{NlOL!0_^mdF*#dskyT~S`2~yf{q|EGrEFJf-m>y) z@f?ZenC@)a=_FnZk<~*$`Wd#bNn$KuGdb|U*M!s-85>6MEyc}wajO-tO_ENkSX}Pw z-YY~8ib=;HRuT?o=>!Q92TSA#GEeBhvLCDb!4)qv>Xbhzn2Nu8{*JucB!u%CLvsEn z?NCc#T!VNa(K*B#_K&Ybx(LFygnS0N6|@OG=m6;a{%r?oD!F{w?SVjlTj|EI&WIW| z(1`kNWVpY-&TEm4u|eZ)!$r@`+zWZADlgBC-??q;FJgG{VX$e`i4Zd~VyCCz9U!Dy z;8p3P^}cGylN|pk5=lTJDKC*A!BGfTm~?ZUVyfiBMYR@QwHdO8VGkQ=95WB)fU)<+ zO6thQO~>)#x#UgIY?NkRZ|=vFh$aTII031x0_DOCT*A9RY_isOBJCcDfx6E)Qx;8{ z?izCre8+zuA63)^pKfOVtp7dckEwI6^OleAU!543!r=Ux#YvcbEFX4Uh{u}u2J;{r zoIZ^Itx7k^M&n#3Z>wzxTDc18vCivqeuaoA!+UKSDJqKbM~a$-LY-(Zp{RMyY|&Zi zB`^^+X-7-nbeB-noZSpotDU2ipMNh(&&84vAB_7WvA& zcaenXP6+e(3L3MGNlL*5;w#u&RLW;j`Q>%|%(ba+793aEyGEE3N^M`Awd$C~rbDK)x_psHS&6bL49SCTuC*$iDqd@42Yxg9 zoV&{7J(XEu4NHzGdnWt{W$Bq1@&m`HJEEubWJGJ7Z%#k(o*X%gaKH50k?`orEu(5} z#neG0JtykLu@tz?4Q^~Svr0;W~+t`<=yJ+eMJ zbsg+-qsGJ?MhVwU1;@onFauJP19+ANIcSs$mcIvm{TCl)&ve zR$qiqY#W_-&=1^DoQRjuyx+2<<)SZxIkh~?Uc241+S*gb^eRHD=Dum*)hxQC!Gk;} z>L!YO2OoL2$drr9cz%LJYSlk7EmV$fzV}uVjaH6Y*>k&*D}C!&9A;l$9lAGJCw4`b z6_-k13l$nG#`~;s^henVWh*Q+%{#14eKUkFLAS~&PW$sS2O`hOl*X3K{IXnzOQsE7Lk8Yo2EFqBn2^Qi-o`Ui z>O0SMS2*H-{ieuc7{!kf@(lGfTGK5Th29#KrM`1$9{^6me${eE*>hVVgA)XNKEUQI zecnEMWckDZ;v`#F=ts((E)f=ULfKKwCc($`=Rg0Vmn5vfli23Em7T@F!-DWX7kptW zepj2-wt)l5PiOAuNVa7NsjZsT@}ydmJu08D7*>``RGWM`2!njF92@vMyvB$DjSi)y zrpDpYwRz-T15Y`BAle6;VlQrULu$@l;96rGkpcVK>BOF0R4 zN*N#S@59qC68C?Wq0;IX2$scytpZ>?8C%src@NF@${Ttu{BgAF-Fa1(Gp-d{^v1Z3 zVx%7DdMWphsSy9#2XKDcn*;cjPMyQ}5$@exp4*ggtj4KQwF}RK{o?nWj1+9Ur6q1` ztocJrW_FIMBk4(TQH`gtZVlr|I^}fulKd5`ikgu%@86Zg2v&ZH3?H2od|b!Oz4L$4!#S^QOD*ZqC+0; z?cJpU4YmST=xI4y%qfmtom&A+UVdfrXx&{{^G62q@v=?J>iVKX?(+jhaUE%|C$@BMWOVWr7Lo3~$^KSo(RJ6+pMjnQ@}t;VH+pyyI7 zLITMFuc81o1)EuS#l1Ga$Ma$@O7q@@0sLsv52E7=u5y^2ehkE5cxVBA=agFP_4@fk znJE6-3Zy^mjG33m)HK6$wSSezgMmKS{n2zW<;47OB5!&N*7+NOU0Si2B-zwpAbTvE z;lT?@pKqCt)zi_w3Kg=t;~d1`bS_hkwiK6DBhd-ku0uqqsvGa6bK{M3dlkAlV4DdmhWPWA-U(lk ziOAT5Lek~$#(c13X7SeB<@^9k@`Km1E_h{>0zfL)4^YadKh-zvw~l8`r=>`;%?Sty zDAT!Bv16h_Z2?I$ah-=#Gq2{8VVn}UMpN_l;9~HjfBihea^CF^cw*mr2fRE%G7dhu zoD_yen{n_>_`p|S>^omGhnWob2DP+iE;ZhR;xCqOW~&Gt3}(g&zg!xGkDmCP3}MI( z$D8oS1oZsU7)BTgnM#oVy9Ws|Wst+V$Xr?mbC`cW4^uM3=t?zpo`eNFq~P&i_T*dy zY*1^q#9E2PO>1W9!op}SBvzg6EYc==-;rH=9MV#)|Fo$oC4uoc&v8Jw0z7)|W8K2R z7Mr*4y)r@g6P*9`1Cst=8B6_wWzw5b6{*UM#|S&DnTVYGX+3Ihuz|}`xdw`rvFOcY z{yXkwW`XQIObgc=m*kC|?+OUYH`}OfPv7K?3U(C^6$ZVLIQf7J{7+XBqdiL`xu$l}>mgR2o$j~kgPYoFi zUN0}9DceQ2La;k;BxELH(EgwpzWFs>%WfK@|6F3^?P~ULC6?Tisz9W$B0aaa@A~CN zm2V#Va|DGlU7n@SOPmrXp#|}KlY09OQP})xw0aUKI3N$?owt5*C3b`tf^B>D_2#$l z){&+t9=WV$R`Wx7Gh#jeIU)dBq6bO{$oad)8X z=syw=v|w8W4U6(I(gX_Z&(94DFB!lyVFkTSun}@Jh_?NoHa?I=Ma}fq(V0=aDtz`cx`1?Ps>#8`onEJdu6O8Au3htJAR^rOZ9_~*Xe~hF_XC#dY1U_K7MAko=YLbW=z^fsu+C;k z(>lHY!Tbv=v!9gZY_ylQlW?x{X8cDcZ-;Wa+s(@)#+tH z%*#gyOEv=oD?73I2rd=f6sg28^6%f^&E9>f=018U-~&%h{wxU;TE1#IMd;Ml^b+ z%0KHO!|ka_d8X_yTxqbthd)FQjY`)iGTF-(5Q4%iaA<3A^Qc)a;F=(;D^e>vVcUt3_*I%h!KB{ysKs`D6)@6L+Ft*qp^r z#>d}HE8k%F#=VJWx$xDhpJjx}gz%+7Dk^)t=AhZmYBd2nEV>?%jm>qx>X&mVb2x>A zy?pkV2$214DU@`90%y@G+--y#|I;x_DhlSVsMZJhtNp-B_v7BKaY5%+kG7P5QJrTh zrP5ef_1o0*{n_uHL4-L1ACU@;9FPJulbS0Wq_DX)4qa!H$KDCM}1k1@_ zaQ<@>?w+u`Q%0cL_w&=XPv+7sBl2r4!@5#hKWUF@h0yk}y0x9yx{9k)`mn3_X*f@W zE;%8>b*zV^K&`!iNLfXTm8)ToEe=X?%o@xTtKDfkyX}DY1d;&UXO?(Zidx8ov$9kNlna-Nv?}83cZ-#J9<(cPog;F`#u^$# z#34EL)-rmu+F_|D$fTD2DmLLn=o;L7IDvD75nPHAfdu_PG^|2T;qd&7e7zRaXhGi3 zm8oFUSoItY-6A$zCMjBQ-YbZSqSSea1b=%Wq@ExqDp~8K?~w@uUFWDS`y=LNvb8>+ahQ>~T13UdchC#53!jXx?@Wpy-WM1s?AFHD^BR^Mk{3n= z*`;je0N+R!~UG6p__0a1sGbe!6!OlaL4X&PUdT-@I+% zojSnviv&1$j6wiYE#@-Q_l;a34_`>YSy(T;QW-@Id6wALn`*H4Q)UeO_rF5GHqSLl z4@mfSA+^lCGvQd*EWWE36kR9kARd8qe3{|CHru(mL!~*{PtRR&gccMd^Pc`h57##> zu0e+JnieK7-0ka6JYET^35~Q+it24u?G}H{CVYB&;R|Yr%dNsJSnI^kiM+F@_JOfC z-`DGvxG%012eDoP0+!ra6-#f>xHBgxb>ce7AH^I+XvXY zW9|%!jx?Wc%*xz5=N~iH0*FG{3^lB(?B)YxK3QbmpFbW?+HWC|mNSN1>1MXW(>jS= zZ!HZO4d!2UD1=`PNO82bjS>dGmL1YNj6>^P!kAMDX|b)D(Risfb96F&A>2|*g~<2X z%TS@t4N%=H$zgQcYTo;#a@KMIZcDKUb!0VjstScmghbSD3?7mNc9z1%^!y&hfV7{_ zgN86TH4Yt;q+1vJ1`$*&?ACe;&42tU2}RJgpk;}X|3*sYy=vVmHkZzke5z(nQ}MN{ zpV@(=U-SF?T{O}AVA~fej)fynY~&AEutoX5Dk#>L3#p7;JZCcNp!fZMmcKJZ)01a$ld$3cw|7 z#dK7Tnl$QgQj^I=QB;*me5-r5dy=yb!#i)6j9-PFGuH3f~_jBQvST%8f;O>sS>*&k^8&1NAuw*J7UU$CT6fVEID2E zpb!^9m?!ljd^mulkMotcK!dA;@HX3F)2+@|r#mz+S4OM0Pb(fw+7JG-P{)oUYY9w` zt6=q!KdtxY3uJMeV=yNCQ#~O81By+O&r5#dCkXK8!(^7AS6ubSmBDV5G|hQSJ$9p) z^vaQCz~TYiDx-Fb6edK;3H&-=RzGka)`5zE%UnXFOMi@lG7O<_fA`tCEAdG5vdv${<#gYGX_=5w} zp^be72s-ViL3cDKq~=K>NuNDQlffIigZwVUYK(Rdsgg~Hs`EnoT~)8}`vvl1Q5%xI z?A4%dM`KiMn%WkX;Tz^N$DKn_3A{)DMNSjRB(5~?V&@k-s+tYwFk(fYH)G!1UA^z2 zcP9|6ylTD(sEYmh5ek}y2G-%TkJ~+L49A*NP5{&ivx<=Mi*BNEH$ArFEtn!LU=KQUnJ@5V(+1wS8vnPSCwp3Trx?R>D6UAT?0fdpkMx)%K*A+=g*|>c`)BqEUl0_1T8G;Yn)p!2V>~>xv;^+`eFgkfE*9m&c zaP3Ia;71~X70$EiwVH!@gzHAb6`S%6U&n16R2T=a!1iJs)&0HL_|+(4pPUHW<&R!p z0AvCjIxv6>Me|X=Zy-qD>ey19deo8wM^~A47)jQlDH-M-Ah(tsfAh>LH1)pyK-@ze zeMeuP)Ag>R8n02oMDV-QVs>vQMsbJ8V8eNwVb5e^P{jzGU``{-F8pliaXk@0;?ZP(P3MY~K-a5(Q=o_5D5KKDbo1}&e)tdu;fxK#5+PYPGhCq?$3$^--{-9!rd9iOVn zyk9=U2CqeQ6mUO_?XUlgrQs`BxU_?}EYQst9D>;fVy!gw++QpU%OJR*g-!2e+t)oP^{E;8+ z_HRalr^eP#U*NPnu87-n4!(60&jhh6kMLL;RO53n77ugt76wIv z1r~Qj%3(%&!A(=uKo1htL7R8BLhpUbiuXQ#mhpqgw`uJ2HGWz|_SQ=xC~Rvwg_iH| z&2j;QA!=K&Em=B!H!ItmK9wJ-(lX9rCM^orqu#W?b5nfT@9z^N(NCL|gFXhm)x(laI5jSq5q#2P&8Om&FE$0fF?!728|BFC;Kf?D=~ICuggs zj1%aP zu}QAb60I$2Xyufom#9&DcI(sOF;>?yVetUwt-i8hq!ZUJIIXqzH-l~;6{da;QLM?> z$a4&$rt@_*aKcx`XVBticDs1ka9Xvk>b9QjfXD2*-}+dgzkLEzeXc~58lmKi2}f$e zVCuu^gDZ>}Kf~^RJQg8aFF%}k*|-!?O&m5W{@3_<(h1Ob$6=8Kqo_j!EgXj7i0$%rO zxJauJy;=UA*0)kDugIcxKbPUXS6O#}JcK#-k{3pY(wvJ);H_tuU4FBy7Z0m1)A1;S zIjP;KRfIz5sUbvu)**;{h+huWQU&D1>{4c}htx}i1fCIUrc)tRAC=QbSo?T^7fyx5to|6$&*p_Xq$S8?zCZ2Tnx)LH@EQzmT)1W0Ol=j9Fyf>T*( z$C>%G6$%2w&9ww#p$D{0KUPE;1<-7Q>|(0GtCr(PZh;^)B>sO9u8@AP8agRs1pb(i z6INkw8+8gd**19hMsBL4mura0y=E~T`InmB5N(OA#D!6vop`x{s)aXgu!n*%=xC6- zfJy-}xbv|p$kWYw=54c#hnSV+ai4lK|4IXb|GpLh58WmIkd^=sR)NnlwbC%i<)Wec zV}wzLgS2OO?p)c>7Rd?B>R2i{D~5Nw~_sk0?*`bfv9P9Or~`pv}A$M3JCv_%aj_(i z!$QirT)ucoCwYWWuzwSgEY#rr!)7}_Lna5O3oJHhBcKvTdR>&HaUI8dyYLYk;CxkI znNZppx>0Q56zBYks|v0#P0?-t#C?4JdEAJ)EJ${J(MBQjW`EGh^#*L~wIU1z%R#y- z?1+M!a@NFL3487&u9$ehvwhuGbj(|90gN}$_|CG!l~eIIt!er|j0EApy+08CU*0yD zJppHSDMSy=jFY8IBV`a)(r%5w&cXEFc5TfVa10ICuB~sbG0+HZ^Z(NL*hgCmrl{{w zdzG~2_HCxhPJ_q}6JI}IrQsoEXC4)I(!)qF`yPGiWAi@K3>m2J&fDmzAQ?%$SBY); zf|BtS)^(-5i%N77{AJm+23`#OsD##E$9eM%=lCDGxbvyfR?BD^tMYgniFE%NX%v?I zFV0L(p9_z;`TvD))2;F8Rtj;E)fQ94})#LXeOI=PVvZcwrGn^iZ&V zihVRR_)148^?Jzvk;KjFk+92Q|Neoa^aPD5LD@j9zF@8IoK|*^mTbj_^8E)2BipWl z6*@$!CQ)yDDm@_y4IvS$ZWg`@oxNT}@~`U73Y5k>_0%JUb}Pi;1Dlde-P|rVm@;Xw z;pytD`EHFh2I)@9IpcIsVW$xRn}(a z0`0RkC+ALSq9m%C>bRpM&MwYto9Ys|L)aL%W=6}8^SRvjkEzqv9MsiH8LFG=>TAnd z^=^lI(w$G9eqF7H2}qi$d}g)7X`$A5D+PZ1^5R^>tB&^@C^R*f*_!6YYenW!w6B z8lC1TXfNokk%?k8wfS^|<5QHwk?32yu4_piL9d5_d(*>_iMi?M2V_W;?w8en&*vz{7a49)chW46>lMLA?l+$(;>3w%4`KErF%qCK z+R=|bJt(9&Y1G)cE=%A1{76-b5rB6rFismvZjL`Zdqyq%Py!VRWAG9OP2}nBjoh_?N2ybxtqob&$jZyJ7Hq1#1$x{DynDI7jCgDIuo{?d?$rb!z4I2;V z!xff1YZ)0PJ3rgN@|Qf6Q8E@%Nz<1AOIhX)Pt9S@V9Ixf-E+MjJihYeAd#%{ZI=^q z!*{6P^|a7~Y-s@i`-ivILnZmuNJYZqUHiJAGyplDmloSo0FWV2pcqVLpnwcphheii z9U$Wqm*q*ShsA~5h>X{T>?=X7vl8fm893(Q?;&${RQ__5ge;6^TJ40LdYx>NJuIs$ z%wJ}H+|59fW+OL#Kn7-vzpTVw!hGb(QsJD#&t^(HSnF=r>JwP@Jf^25#<>ZyRY$1@grHY^#O&Oh2|Rq3vDo6NdDr!r zJE70sL9;CVF&bTRpdZSiSBFf|6%P5lfxdZDWAbGk^qwYg--h}9?l%1U-|7k=s}w>5 z5DiC;C`LE96Bx(~&%4x(4GH$ilbu@K3alZ5M)~3>nM~A5G|6=a5rhi4PucexFrM_ zQf3n+T%s;wRpes63qGO^*4X7{&$S!^I$V6kg@QP;1crt=qU?-B1 z6x_rww~8}V>_#ylgKpoc-QwT3EfhRKoW=;vfQwTYh?Tuq)==`rLnm=FrJNHNmpJ}q z=-Pc7GY4)~$4?98S3nit6iEboH^M@_;6DGj>*DE~OgG?;j zQ+z0)y%4B?o#+>U%cOi?nC+eB+p^k|wW&o{)_jlel`a>0@we!GKpcz-O4>A2aVXMZbLba3YgC)tNBZOjJxA@)Zudv3HGM|TA>`}cJZpCn zu{u!aWAx21U8NX6L8yng%JY9=$iEJy>mYkF^Bx+=2y0B$5KQRan}Gn3VOe|6AHrTK zak_<#^xPlWG7h3dKSAofpc$%RhAEo1(MEC8NGW_IcI?!eM$v{WG`x^rdQgT?BOe)!`4J*{j4p)Yf|U zMAY;(*!6?}nX)>^@i$YxB5fcfBCErFk!+oYzr%(e=B*u-8owWzS^ve=y654=CrAs=9#w@a?!?vOI_z3%Xalh`-7Cw< zulbIlFCu@P$?xQRNirm)W&dd^Ne9}Hgj*)SX>OFS>x`AA)z50)s@QEh_^hXKYGe`v zd0dFi(V<-e|Cx*7eeZO2M zWVXzcZc1QFh)agNkLT~%O#EUrfywp|%vVY2NP$&NRuUuO4q3{~zXKp8?`N<8@T^=M z(G>~*LPZc+3i#mw@BT&UGJXW`o{?zD$q@Iv`gv1R$5Y>0U+?f<&8;Nyo#*zmD%_HC zhs!9K{V;eKyLo-kQmKk6rWdNbzcHGV$5A{o)LMv z01C!V#Z}Aoi(k%Ag@!d5>*>Bp`62Ie0t)KuJGCjUMw4mi)36N}4LN~`{|JJn23%RxZ=MOTa5DBNuqjA*HSC|-+-+dr> zm9-q-_n|GDrmk%drqyF}e9>nLeC-_jEjjDv+AkTSsl}`!#$uGzmdE7~@B_Fp(i)n* z9Ifnbzc;{F450r9MK?KzP=syKms-vVAEgt8Y9tUBPP}^hKhW<-MYSZF(5AX@bSAb3suV0oEqH=`h z7~7kpiRysbL-&Tq<&Tn)R`X3%Xj9ebDVe0p9Qn9?w07T5?W;-2^pzD^PSy&=(z-%0 z6zk2Q0adfj7TwtT2nfr^z{{2 zwDy}Rj->~pSF!snfQ-Fl=HwJn)4b)PU0k5>ho364Q#I*Xr#m;on;7K{fY-f{lojD=YG}Llu1Y-eHeN8jNiL9)86mcqx~UyPu^v?dcZN3+{pE!o=It=d+2>z+X)5a5_4jp!QgSvj&ZNv z_x+O@Gs{Ghy} zD$ghfP883p()hs+M9x@rCq9{qeq{)Dz!Tc76$5|*6%6T&oocE%vEHdAbFmqkTB)|t zOUg@z3{<8U8Zu1B03?k5B~x$PGbiglR1zgagJ84FLHD>XH1h=U+DCnbc*BmDr*0@O zyoQ&(c`8_$cFOD+*$)g7z&mXKO{$^Qj|q79GPp^5*q4gdz;#jed@ed|{;IWld6MkKKGKsmP|bB$T{NW2(n|Nhv#qPL{lWgJWu2A(@UG(1&5xU2a%83$ zn3k}Y)&bJBRJi&i`tZn7i`OSBN~pb)QLQ2>hctpa=l~q3YWP}63B4pouRR!0RVjo zU#utl;4?-Cnub0gkjt(fgx#Rp;n(x^HmC7>RBZW?3ql8FSS(TZ5;F#u``flo@%@H7 z!~Hghs*EFFJ#@MGmfM0DKy}qAlum@#ObOdR#gmfIfCeJ%|U)p?j`f37>*sZq4( zb_eG*C*nI$x;61$Zwo0G;zdT9F5QbawtUk)aNMlF_Y2Q-uKDp{9qkSL)W<*-FmnvfHi2j@!w}#hfX= zuPH-mNODIL%bK?W2h)ACwrkf9MIO>asMERn>;87 zks%4MCAM8=03kk!p&Vw$`n8I zu0^&xPycIP%?2J`l+{=BM6*pb*byZ~Ll<=>D-|8L+??#lI5-Ws33|9#qh7B<0)p7g zzGo_0oQX0Bf?rhL`ICl3zG^}cZ0(2E2{l)yTB{UGSi>9Nlxel}&5e;qpJPcsX z4K!J-s&L$HZJ1f(r5m?G(3n3HDpX4n1~Q}$ey9~%0T9($Yik1V0A>}z1Biw~ztmEF zVfWb9AwyUvFC&a0u!fPa(^xFXm((nCK&br4`a{lIO&ynA)`l?;W2P*(Esc=j*x9e5 zP?%}p0!AO{xwrFC$Ap2DKK_TVmUeP--(|V!5aS2f2Y9dvfWC4XHzpzY)V0R9i(~eE zphl!F-?de|hFT*CT0nd^XW#b%kQD65HDHT^bNQ0&U~Ag_S^Q39^JY(t0U(DPG!jgy zF{Ca0<`Q@Kyg`2ve5n^-4z6NtaFhJt`vk_`&xx|2p3-&g^-+q%g5WxS!sV+$+ej%K zDf-oHzRo4YOPH3fQ_L6ZWJrvA9dF#IrGu7@cLb?auAeG3=b1UT^6&oDqQL8-sA}m) zjRKiNu}Vi!U_ROO2GBr(W5X>D780P)#STa40}>uOPbO9$pqxTIT2hlw!@pf15y zh3$5LCW{aqhJDO~wL>CiB5QHc`qJD4Ikc%%ngSMS0&V!%Ji`E8`J;Px6HCsBlGrxi z+zKo~4x5&OlvIL5v5a5t@|~ga9zd=C{yRaNDMHAP_)~eBxSZlMb=f9|4JWTF89A8P zINLY&O2qx_+2o&ai{h6*#0BInpM(~vECy8IYKVO4Fj*%{A7LX)w;zwS6^KD&MYk(p zCc(vP(I84E^W&=xB%sGy%JkKWIuTbbN|Ns`U@8|hPaN(gKkLN`*Qbe*q~SDvHAnz? zS47ChcAEHMJ64aivZ0e0KCmy&*3d;PZ>Z5XM1g!NA%aflNd;Yr2(ei#fei9sl<_}^ zYL5NKYsuk>h4K(cjJc@}4NzIqK6h0Wd{5M0!77{9%dch7lk^?VOXv%l%Y$!;D1Iit ztP7hQF`S|hhfzS;NkQK{EDr>C=JAy*rO}Mn(d!Px8)d;Ma-#UTyqlWv!&liVL|k!EnDSd@WGy;#Lm#Dd9)aXyUj>K9grSG8VnW%7Mw&{wbb|3q?&HZs&`-JgqG)Jf zr-11G*eh}ELiSu0t5_JP#Qj5|<2GfS!DT`26;s^veA6hgCrq|Y3$Q&wO>D3^#YNr7 za{ap&fTK!DhCkxOB_SzNs6{mvte?VYjx(DYLRaB*QIlA>Vtg?#HpZX$E+W&_*@er7 z4Ys9lON__GH1x%t5<>+?uEItMUcbC*rN(;Di3Z2#L&nWp+YDcKuA+qc!`m5m8%ZPm zul>)jDN9kjRYYc*+|}vp-KuWv{9Sa{?cf2LT0rC+=>LBffi~tFhbG8;uAY)Hq!WIUb_|aPECW&?5tBvEvvCJjn*#mhsUq`Bm$!Ee0YZ|ryhU{KSl;`Pn z%b;ViHZ`e%t0aa``8dNr!CoOsGlcrRmk*no;#pc9L-Fk8Y=&*<7eXyw6FF*Go18gQ z>$eVluQmAJz2_`|g_Hmq{H9LgKy9Ry zYz`mzV?WNwS0&o=yNJF9s4=5NgB@Cab(kKl zDfo&YfZM?w^S{dd;CBZZ#XIk%ac=YJoz%~CeokSO4ci>`u2g$-q;z0T{#r&f$0IS( zcXduoDqp7twtt4}`aNW^yCjJARqK5L&-NGBp8j{r<)>ugIXdTt8Xz@+4-^D9E<0@V z017rq9v@xz_E84%_KP>=s(Q#}EshU-+7>LLy1)6^8NNz+g0PmS`{oYlJG!r1``<>z z#lJ>)=HmKwd!*MT>08(;dcMMb!53?P*5rI5(WR5BcYCXFUKb(zulK+X+jAso4MhV1 zv#}1$e0l}+L7=FNOh_^d4xsZLJoVcT8;a`Qn67Da!p*&3n{(5oD0?=@_`WZwG|$-V z5_aQJ!Xxqvv_lc7T-87Z=B3DKS?PB_$mvMtwVOH{E~y+;as{-a^hCAQ$Mkz>P9~W+ z9Um~3OHN4weJzyA9pp8lyqH`*Wglh|AcKd90GrJm$Y?K4CY;3xI(XS~wismbEh_KZ zt$e+*4^wKOcrEHM{Y^{?e+5O2U9WI3@*y_ETPPZZ`aeV{PN83j(1)nc{xj`#N8|O^ z;A_#SlB?>zs0HKHWc{2hI#4X)2@vLbj=Yf#u6MoF9Sl5cZ*{8Epa7igZKf3G-1jq{%N(MTyPc z*pr2dQyhyEhY|C<$fN0p_!KDs03tw>PV5fRcm@sA*_PX{=pUhs0}D@@A^s!^oSttImGCUuhsD+3ofw z6d(;1`@<1Gp)?dt#*^9vr@1?DBLONU7d(RK5$x67nwr_8HEFc@@iU9+ z_C4SEk9!Ot1MSy0nvl7fZxM1b9S? zFCsj5J4NYTT;}{%eC!5UbHk|xQMF5cZzm@6Ws-Wh`n(>VWAVNFK zN$Fr@4nVekgR1a1F$@9up0z2P?)oNhll{^yd&tbp%)DpRHF{fn#+N8Vqm0^q!l(rJ zTeI`O25%1W%Xl{D5BXS?Ql(E#sRu2-zN#=M~U7f%@&!VuAdvWs8LP*bNR!3qw zn*GLWBEJh?hFaWOo!VE2kNd95+yr2@2OK0>Z0kibM>W;rwphwCJc`(p6(B~#Uc`kX zH*1^Yw746^voqboHtt)t*zyqng6oji`UuSDPnMpHo z=8Te1kEfEi)o}b`1UQ&4(aI{qYrrvMWs}Dyntk+>P)Yr>^P-Lb;eU1xfOkPvyR7Ae z2p*slBB(#x^cc{5xrk$CxiC5N@Rk8H419mw*%4Q}txe}g!a+on+CK4KHI(ok2o`SBFZnHR$und%uS7K1t6l@;c{F3Ata$OEGR`Le?7|> zEw@>!*uxwrq>~E}$Zzu@VCatN zdJ{?0Q%@5*9mm=k^$^H6_Mt%u1KZ&BoxB~@04ASwl5{Rkp5oIxvJz*%78K~+%B6*N zz+LB5rO0YXy7%I;DBNHo;UVym{Z;rRv6MVyi1 z8j%NuB`K}TL&7^3Ojwf!e%|5hbcpI&*WwLPxEh8HN}k&6nIFgy+A91YBG}4F&9OHv zlG};y6s`#=r1~%`oRqqj2t}EHSAydGq&y$s(Uoz|6JJ+Lg-lr-hms+A`wm32!+KLH zCZ#1>fLGM>;Vp;|g**?;Zd3_z$C4vM-hMk^{D24`dT9NJLeYQ}T~R)-E=L-OO=X4A zmHfwnS%M^TXb~xu0`8T(hI{a-%@lY*WaVJ6N#IuoEJSbfrqvSYN}HfYh5-$eE?DvJ z$+0oCs}v?7Q}^dUq`K1vqcMr%{VRs7pqysb>_6gADhU|L3~NF-yL z2y*5YfJRwEBResG@%G@50t!pi2M?k&Vk!dz=H@aZQ2t|)xu9NfIPTHU8vz+v>_4xe z(C%&CdFIkd$xS~iaMO=^sZb~H%^l<6oQiGHz1Kz}2cHmUyu8{c$!3YadJNA(FMhBr zd}`wygv-3AiBL9e-0c9dg5F;ylXt)#@E5juuuK3`Tr(IxbJBh7Fr)(&U_#X0wPWf^ z`UphkeGqK= zn^+r8v$OU(!yYH?`4>JR?m6t-1iyNQzCJ9HPA?`7aEp%r(m8K(?SvGtzfue z`Z@~)%8#iK>6D6Yy2Rlcx!na(yY#)}g+PoztJU-yZI0|h-xBCt`r?(h@&rQ&z$cbs z_RPgFReVwJx&JkR?qN^(PeurIMVdkQg|lb2p-qAIhlT{zk7hq!*$&u^Zb;ndn*Sb1 zg~_%B^+y@0C}9OMieqk*li$}mRQDvAtS4+YHUHn~6Ps7OaC`twBY7_z9GyG} zfB^j3NjgrOSA6r`<_o4rkZdYi6ky`}!z+R|9e|4kO+wt1MVV^^GL-jl*uF(b{XBKe zaWb<-#bfTrpLP}qV#DhL-f!u(;Q@V($@Z;>i>m{!#rMN|mt9e5&Tir(y}5%L)&@jy zlNw)Y`_K*wc00V=Q5_xT%9&KBEfgV^P$1X62`!(=A z%j5aF)-v*UGpI8J=^sBY{r^GKop<2Y6^P`qk(Ef90d~Rp`caLei7|f81e2ch&g-ay zgp_L`#w9$|5pQ2##3pzEn?^oPJBR51koMMLSuWrE=tC<~5-Q!@-Jx_hNQ=@S-3>}A z-3dPX6{eV9%!F3^ z0I3nSG;Cx{aK$r*tnmNLn93S>*`uMKkHH^)0dDxuex~B-udKv#aPi@~=|aRuQMIcZ z1>)akA3t>NqtQ8khQxC6#GitRmiy>`hUZzwm5^BR2&BzNH;mu^`A!Jw83+p+y*E}F z<9Lstfm{2A%EPUdw(uK$rSuKUu;y_msn1AGJOP;ke~N@L3mkr6uAWeHpC1UL{U-U( zAMo5r$RAakgokiH424kqD}55nfED@w`g#ngN$^X@?3DRZDd|u#t2eU(rfntf+u7Qk z^YK7<;RkIEx;DsFd46&Uy^CzlUJw+Nh=BwwmM#Jq%5!+F3*uiZl!VO{rkjJ)ZHo<; zGn{%n-YcP+f5PRk9u)mkox?H&3oz>3u~n4F23gqJrwusp?BXA6UsbXl{?^X=h@P_{ zzaLSa)GWA4E)iC~XH(Uq>b>7cu>aZXNxdfI|4cq45Ilao6x<0slVV=pXCzL4D}Pgv zswh#Ok_w+rl<|6>Y@rWv+t#0qboG|^Y)svJ>^fgwKDGf>v6h=1xUBn1f6n}Fl7?;% zMc*7HYl~hjWi?Nf$7Sf$xi+~RF=kyKD4QvHtcv=cUFDEoyF33mZfg0XnJG>1m(9w6 z0jQm7Z{?PJ@)PATK@D6r0c%*kIz-@EmxTAUa(P7rFp=I35yj4uR*kx z8^bFr)_n$-jma|9vfzDNd@#{0J761nXu)&by3%fP+sDHbe!WC!XcOOYS=NrS;3kO# z6%`W_v_1>4(tx>Xx=%O70aU%nl#Y%Ka-4)#N%)W~{_W*glneteP--wT@H(F&y&bQ= z!22!^9<1ed^9LcX&rw8cfqqN5aa3lrHP)DHkxWbxGhQdc- zmFxrRgw2QX=3WF|#^VqBZuZm(rw4Bm>x+0eveRe#i~E|4Jc`_=ZpvPDO{vjl=z!K0 z{6B0a#ZnBGzDInToQe-=bPR9tT*Y~e9b+n35O2C?lIR>!So^EVolXrkdem|#Yttan z3*r8f6=N1zlFTDLL_sNhyP2uE{0DLglO(95hQgH!%qvn129BeJSkL_$bjDJG=#_Ui z@_%u-&>Bo?Mdisi(7uix->4;tMfgBbm}a9B^$Ko@^gg(H`y2KbV3}pUO#%K7*OJ1r z1_%7W!s;!}?9DdO4wa>0JcqAw+_}_lnf+Fom`e|l6(Wz`O`bZiK8mx}tr2ev$eBNe zFKc?-W2xB39NQ7%6x~Z%s|LB3V6iNrTlOHaA7$}o%Az>BIWkh7f2G-k1yrC3FrA)6-pPpgkV&C zAAW|54aJ32{mYxu>67}K2PEaG@N~A!7-?M*BKyg;m4mF` zPIlS=WnY^n0(5`;<-65M`Qxr7Zvh2So$lACU2yEBnAVd|mG4>BzAAWq^=+MYVo`rG zK9x0Z7yWeZV;b(-;FO_ke*XcKRR{Jl^J~_lK|yB`97wm$)u43rB_#~DnLQqOY^hFu zGIx8}&+BXda{bomac2rAH3uBoGoh4d97u&m*ntGLYsFw^8Jo2lPvSlV$j6>PCi$vW zX|2t0B(b)9DM~oE+zn~EW@HM-b8L`wFgQ>2;(h2B#Lu34O70j)n-XBk!?WO)@%KN` z9P)*>l6;kawA4yExQ*@6nU8?Rgxg||F%`djPe~G6yt~Tp@l+|7K@3WvMW1E5acY9b zvrkhK+}|||Hxr}S=Iy_)MLXH|&``3h9H_+Nmdj~ooC;9~#tYy;v9?|^>YfbI(kw4c zGSy~1okIHp-i+eDiyOh&NKhI}Wpy%(V1+JM{BDzgA25YyZ)v{nVVv7kIbI{Bh}gS1 z{x#R4f6~&`hE20PKdm*cm4-S)Xs~2S_;tk=&2)g zO`hhqcWvr+CSoQQvzF>x?zqzjZeVBUGltIw^H*Kfw7o^11`oZYkG_jd=M4Wu!UR#s zkp~iR^L+86Z)oJlobYW#Q`OdbJO3Wd(;OL<_0s|&sLI>nW)f7gving^B%j( zqHukR3!fTU!O|v!9EoUnm$}NT{3$*tysM+Dyzd{{(VdZ_Sa}QD9iI|ym_y4A&-D zEbPS>docFO&geOh-sNT;&Q7_Ex?ZE#3wt-cT!*ds^pyMNu)x6zJElE=dhYY3(ueju zEzC?8S_)zvjm*Sa9w_8VRYmfte_x>nhq0YLU4a65d}8Gv^KeXqGhxFh6-G&-@{6%_ zLXH-!4!0^7Kl&h0`dfCrQ?89w^WEC8ieO1{i8+P?{^EKKnao=C9=b8W+e<)^T&rtv z=;oX@%hin|4JxR#-rEsuxo;S8as^&pOf0!wNwNF0CwLRpsmN+FUBj=QM*~^?{?iNI z1whrb`$E@IMz<}EXTyCvb2mGCH_<(OgW|9(_AcSOB*2cRnhu1|R#EpF@1`9yw&3n% zL$L7u(p1hr`jcpe=X~&kv(Uw9=43Y`f>WQC1pAB3sE)F+#InChU{6d>QB#3 zSmF9=Nh@1%)1NjsXuX^CJ1A{KZKkW3=dT*^|7p<8uQ2ra00m{2h%^oU=RNV!^cBk8 zX$k|adE_)xaAj?kWK2VTe}k@^H1lf)ZP65gmO2&Z z8ZXLj6HO(%?^q%Qj9}%h%Cz-QLm_|EImDhE;+XZw1^K;iLHxcAboG;zF1C`A{MYUb} z^?eDMjsW_qFy+)6wz-(M-66PqFTNk^d?#p#f6U8=7HXy7<1O5UFXq~!Upw%&W24M` zBlfKbM+sc?)c|*Fy&L}v4vepT59O;c+CIi(*v=>Z44TffRC~=U_EojweP6BK=<9{@ z`P2jn){I?I&-ah5RG%?d_9FU&>iFp6DMg~AmCb2T+_~-A^Brm{YVoT}J)dt=_B+xO z!Ab8%^tb38b&3G^f(h^x)wcrNoc!0er)lU&4FPwFO8@~lw-z`y>}hV{Ln`d4yWhjK zQ_}>b;}WagFU736CY>e=O+PS>^4QN-m;vNBwE^7fqod_mLrYTrb$C}GqlNMg+l^Yb zqZNHXdC)}?7PV%Mke4Io10$6of#l}+UL$Ts9~S}L>n6i!segB{lU{sXwAeFNPnEifCWn6~rvK*KzfRhO(nZk)> zDOA@zXzn+7TNQ%mPn#GOO6+IT(dhMzkOa`KUQm9ghJ`%{_Z|#H{}>bqOCjxLr{)hk zzDjpVNrjwse4G<-7?I1I9U}x0I3t5j|9(lSXg=beM>860SFrmX3To3*i zz(ht1_7_9VnPF2T93aK-Bqk*hU*gQLJG)k01+A_pmbQ|Iprbp#wzZ1f@!&+fNfE{M zSsv+9yR{f1h8J7&B>Z*cXcpc-XTKgucp4-g(?x(`@P&6bM=fU7<1E!w=Yz)au#8>X z#}VRb=lOB}HYfVrys1``&$VMJrg&E5j^JI9 zpzE7V=CY+ASg#>2p{vXCrSz25lVNgmU`RdyFyaGT^h30gKNRYX&q}_QWgUv%w8xp4 z1EhZlNDYc12Rc~bvVb)3zfgX`iroee?J+ia8uSYXOfDPDbfm~_)Z&q&EhwmrLshF1@%%34R)b+;J)z-Je9Z z?E#?^8^y>Yo5(h(dvJrmfh}CGY?&_-iRD?9WNq#i>a6heF>}UTX}8NaoENAebqUk= zI=3+Qw3%5SPA$mu+3^|EPMDn&)4%5a{T?& zNLq*x2h+VIq3%uxNnB@Pyj#qE(PqsT8Mr~@XF^qd6+{$q6#A#sG~BcDy0Qx)uY`r~ z%Sf1*V`Jy_c5}9xNm4tmB*ENrb`+u*_CT~IPXP<4DfFa=x)Lu=No`}4NW3bQU<ocyQ$>O%jaBAD&iOl^?&9)amLk~5Q~9Iml1C3Q ze}6HK__CUd4w>lMC+e$CP#zp>P=y<;9{Vb#HL$z>_5?exSgC4vr~09F|czdOs4qQcqVY zSMfDO>RgsFZObv$fz^w+hh-&!i}@ST5;F!S{aq$!9*h`IUyUa@eJ4yB_xi%#(|tMp zWFhT0`zu}xman$oLpb_+0jKm>W_aHzL2nWot_Un6z98mXSh>z_ZJk<9S8ht|QymnJ{ra;SV?T`zSqMD_t8|q6fHQUvDnJ$}ya)HMfzW*hG4hw5 z)CU#Vg2>56WgH=pTrPe7BWEh}pK$pU7gf`=ye<5Id>q>JqV1G;Wx%f~F8EMB47rMr z*5Crhx=Kr%Qt}`6bt3K%mXAa~^RuKUm+s8b+Hg>4jjQW#nm)@H%PyMRQ%o1{h_m1S zc&fA=wUb$#Nx@A*$#d{2ii7>iq5C8eR@-8* z@q0M=Z%;u0f?dHZG7@#@W2oRB1#O6%d|W|^PKKoXq6 z1&@lfpONxdq<)~#C*Gp~>WWrS?L>fjkToq~HcPOcOM&=TkO%2d_7||kg(937N7@iX z=ZB8|K%4fAmlp`mtfIKbdRZw$D*qc4XFPl#OpoL`O2gL*b?X_IUNq%7AR;jUgztae z4-5q@hKxXSfcJ^|vDDeuF1MD0Sx2*@$I_mQJH*12NgU>dpBb$jRdO=ojuI-$GpuiH zY$z~s>7sxM{*QiwLHS2xzBNGHHdY5%Yh&C!jgu<9>6?1#Mcb4%oSM)#E<`*9Nl35i zR?pZ2)K#*d0pIdJulTd8-HGi-pe*#&FvjOG;hg(vExk(h#_OUWO1Yk!<1>ITgA^bl@FFKXyu*9Tn#_)s$4$}0&p@6`o78(4n=Ao!5&M4pp0pwU8 zzrk{>P5HZb{tv4$@gq8$Y6K9`CCoJ7VOdc3XV}jJ{L(00h`T0PzqfkH{c7-26GGWs z^O0pKQcR04ZgzvUqg6g4Ie29Q(5nH{UNf+M^HVs`6pV6Z#c~~Q<>_NE-fo?K;W)v( zwl1}uiGfFfdVl$JCPV`Z2*SnaxZ4jwYG5nqLc@SGB+zhr*aDOfkHZ_^?&61#edJmCLKQ_ic-2C5Mon3;HmJn?L2`c-ZNMo2}Gmo@MWcq{_o&5P_IiQi`mVmV|6JHx_D!<1FSK2wCe zb_vaT>2V^aPc?KlQ`E_HrX^|=P?N0?Ak)#_Gw<~u@=s^On_2MosG8QIGM;eE+40)W z3i!TU2dWBtEEFhIcfgzE-H+4@Js@=m-sSX0D+EzpW9ZsdIvfA$NE~bgE*WlqA<<<4BKhI-hy4JdVc9uKotA^lPOx>x{mEmkebUfCwhQ zXEam{e*5izv1E(mCLoyu6i)d^KGCfVe=W zk3*ooRiV%1?a<#kg;}C-gGIt%6V<@zhjaO==)H#wI)ETg9RrugIYIp@xAy1f!uuiL z*ei;9U)##5zs4v5kN!BxHd#$Qrehgf@SBv0*-;pec=sCGMqBlM2K@xhRc?)bdwZrj za(Ge}eBJX{@i>Cf_fL)vfD%F`af4-%LPMS=WJ;E$Bci#qT0v2n=jfJ|zS420p1;k( z(JI&w_fK-)Oz<9c-hFPIuLME;kDkA_9RLcIac@vG7%O|izYrf}y76-y2rM?Dyi@50 z7Q54)K8hia#!T^j(5*J=WJ~Nq+ub$%NAg=F(k;bO=y`SB?(gr1hi&rp2N^B(r)*;e zMeqA)Gl*GC;W_w7iNBPmRrHPZDY7z(+PA|xOE6fVs4 z&~xM=c^IQzVY#fxxRqB`MdpM&E=f{>kxM&=m(Qf3N}~zXRL(%3GWHsu&uFD)-k5Wa z8Q80wRdYMWF#bjhT1u7$=UeYVm4-?Ypr{%Bg{FdjUZ{3a!I8y*sA_T%+aS6LAq zXG&R(0SwN-TWQx$A{Wpwc?`eO~99kU>mF6d)6M3UT=z*1gt9qbWTkYP>N-fGxD^Hwb2|Yqe*QaLfC_IcRt$!iDift;pjnm4)oNj^ZUM z>O6U0@>hES2o#TC)lMD6F_5awY1u8;EBKTrn#k(V8%F4h(~N$oBPUR1`@}_dH=UXF zfLN*Xf`s!;!U^&?_1>cj%W&njjTSRWv+j8H%p~$*&C_&@i^5#-jmFq%XMb@Oo*oV3 z+pR6M-;#&HNqeLl{@&{}pUh}x1=`RDn74}kl$g5%>9VtDp=QUPisd??kKfO#$(GQQ zRt2SdCGF5MCBLIR(`vm*J|i@J)#qHW-KVyCC8tF-Hkv;kerRvqYjYSxqu9fHKM%j1 zPNvt))ZwUf$tFGf4~Lp%z(PZOk|wtuEvKP}lvWXm-im*H*|?^qx`*B(AU9jBcWb9a z0e=1D3wuCD3Ydn0N&gl&STnk>%QQ)C*7d^lerQiAxZSgb99iBFkg2Z4dSyBKODCB` zICjfvui$e#_zRqEmZgrSZaWp1iV|}SEt0TlKCRs9sorW?HY9?9HaC0T}$%Y1{;1zPdW%%iIl?@WG~Tel^Hv$o@2;J#Z%UKihBtf~56d;=jtbQ1(l`}K z@F9^IQ;|509q{EeUtM|9Iyv4Q-f&}*f`Y9-0&NKR7rkQ=X`|tE}}o((|JgP z%C!7k+-TW03=}%=Dr7^zTBlG?EUJbaE20x8=-9$DSR1a`^BH5TEmJ?z@1&6Ki`SWb zQlaKyc#&9W>79_Hn`>G*>tEmhWT5qlbjcsC;>`3^V@L9|PG{xcnE8bIg@;{S9lW6D zw&z8dnIMuZo%y&-!bh_8Z9PhzS|A<;Ql(#h`$)olX76y)Ua&h^J@vpr7VM8g>+2x@ zas)T2LFpJHgmXA(oa3JV$s3i9mXd0W6rS{=DFw@iU9O-nrhJf?{O%BIqiElvdB^qrb$x>-&lBBwWmA{< z1;wX$bnsAp6&tUc@6D(wcW%!SoAWrSelvEx&3WM8Rf|3&VYd&$k1Va;xnZL1+P>qm zB~It$yaOXo^87u8Ck^)leBN8P661a)tfaW)>6^73V*Rx{Jc_qQyYc7G1?yRzQ;KndwS_OT8*1Gr{@KP|P`SW3*S5G~5g zvfx!}0(qLYDO0=|^?-b@cx1+|0{>*JwX8|rD8B8aOPbU~U!-iGv)bM6+FN|!F=USy zf3JYr4a6XC*__ZdDyaDL1+VW12q1w-kGj z8q>?!is9s<{}yMJ`r^r`=0vDI)zDit5O`O!d@qI?x06hAq!swHF?!G~74z|?RYa~* zInayTl=jEkGmls~jymYJ5-ckzj>y5~T@o5){mT44MoXJYaenaZcK+Ky%f(r&9c`(F z^m6ihP68jGrv0T{2B*XaoT8hv*zY9LHs+l4P8-?dR1ngJLvj)r5TI028#~Zjji;*y zy}6Q(Sh>0B6Zc{7w_gFc25fUEM0o2YRVOFETLs0EK-?G&o)K;7GE$j7$@T|Es- zhva9TAo=e=aM^uXDMe5BGeftxa3IUgkw?jX!s<_PdIzUDzM zEoQ(VmCD|FmQ#3NbGf+aFkn*efHHqvi-n%oUHPTDmF7F|XFh)?2`b*^y*2s9%p>U# z+ywK}kk6mI(M)sYSUkd*>?3k><1B$N2ldv92w6!l$Lxr{Ad{xj^Zd0ih)~= z1BrW+p~Dm<$kS7|{pv=fM2B8aO*DB8xl%lhC_7brWX7Okktc`gA1f|MF+$vyG%HwM z!aZ8$a!c>VFr0^Tus+%9A?X)eDecxG%%!Du<6Kqf-6YJB=JJ&)oeoPo^8R8MzUW|9aqw)=)`Op89Hy%lT=W4v2vq{&H zQl!;X^2I|8q1l^IIOFHe@>Er^*t|GIZ}l#w)5*oGxTr0eV3oUYE-*r@Xj)e~x|Zzx z8rPq-^7{jcp39Rz&m9PR*m_WkGISO5Wr?PCN7sfep=^fjAKLYONPuP7gTOoxW6|d} z%Qr-sQpYR6E0spcENqUA^g=8rh)Ec#`22v@(9(93ND+`>HxNojo)77CU5Ay*%zX3c zOBEg_u-p~62C!()RHl17vbn)0ap~tNNYaZ@LIlFjgFosXgiu5YW0RgWY5j_;(LRV- zoP^s_Au~rhua*r<@6+}Uu*!mKzvh|h()9N~8aJUBW5LuxF0TKrlh{j7sA+uK_y$FT zUo*yZ6&o=vg4Sw1Q!(anRaIPTMIor5sIe$rJYO|o30o)teu_~g@l11Hkk)JMT?P(R zuqaqJvGyVW8a_YckxJv;6)6d3$7y&41O|KVO>ltWsvR(bTE+`&FmhVLK7u#J;XYgO zxp*yDK$nu$`DE{%^h?2DDP$hd%V>294svwP{Hwr00+bRryaHMnB-*J`Wx=}RX_W-} zg9BZuaAF<1Ynq?0g#>%4*MFJA3#SY|R^CK?iZ>yNIL?Gn>B1nPIaV&mhv2}FgEucO zf*L>X_IATCv*m}v8%Y5KC|)lLr>;_kj0@6D7T|1(u1$Z=C(7$~)4yOR{b7K0=c?yd zx=;7*?DUx<5IFd{PtQK`TyUg_`6BOw6^vr~@SR_xBdEj*^Z%C^qwDMcD8}fnQ_H)B z6`QC=1^4!@&nJOoLH9n6ogBPBeBS#zhOmLEnVx4ASo?-y$(GChDL6u7^1y zui+CD+Ict}B{0gjPHi4B096bt9HUxSsn$SmhXYrQb}^>hBll}48xWnw0$C01UJiyZ zq-<|#IRos+$_>vcBZv#WlYByDV{~r07mn!JT}u>HEG(!%Bm`M9LVyYK+_Uhi;;%T! zOVS-}5IH&>Y7UEFE~~MziIiv&-ZwOW$oh1f&rjEXcCYU@yC3V(vgr1V0iDsvYX0w! z@3bY;SR!4!Qr*zCuWg3|#t|TyD)&L4;!dY7uD?U);4)gQ8mZ30RP>(3^QDhQMf3$R zxJzSJPpF0=4OIwy4{X$vW4mTQ!|bg{OdXQqD7tpD60t&j?gfAzq$)trpE%iMoLh*7 zEQ~LYzqz&SK*U~4YY~H;L%$o&ocCsrq6SZgR`JtNUwao`H%Qaww|NsVRmHEQ!ch?! z8XCH;E8BDpPmSz8PW`A?j~qh8!!=x8SIA$pHh^{Bh0GEql6aXktK22Uyz5big!%NX zgVzx;?Hf)~Ky6bPl3hSHo@=liteZtHrO+%hXfHV~9~UCaw0=c9s+|#@Y+)Zb5nDjF zW4Kx;Ss3_TPguu{YOuOX`X^&Uy0e~D$6zkb_t3Pl5prSnF8*Hv6t6w=$cQas8?&wq^`vj10M z@Qa(YmDSezg5BE{?3^~r?U>Qoink>Yy&tKObYNq$qPlew>ArxJ77 zP}j;z6P(Sty zPf$g@x20cKaSWz2(X@y91;Y_28GaPTW|3O0~v;jUr#D{*WY@znx0Bk&@ge^*;HdgNQDMcDCdz+X1 zusYugjP(TL^QpbUEu8=1#-ALfe~nZn3+%*{Cb{$;^?)x>_tce#?XJ-4qixQ)E<~~2 zMAHoaa;VlK(yWbT{sHheW0vxi33D{Wm()y!@V^<40^`?!1jSpVss&o77# zIne9GIBJv14 zB10EuT5XyBZT1T~i2$OG{~rpJ>)VuEb-@Ocors_SwmQn+gw@KqA`M57pngcu!l3_E z9D&R$@V&U0&4b;~q))kip>o`26+{p=?9WxFvsit3l62n9FS4=i+RL?Ar!?PFxy+yv zK2E_M$(1n`waup)7OEDPQ}y*3i=A0i@x~hnf;kePvyhtyy+$l(9-6M=10^D?=U%2* zd$k-SL3n?$tf&B-2I#8;>-#h@b5-(uNE|-9 zZo#l_#fb+B{Tj53FG31=au}eNyhwqD|4(JiiXK&IrgOPM>OnddG9ZCM@wZ`%fhYQ& zZ5z$ioy|xx{-KC7BaB4AJjh9q6YSD(Ihm{_CRx6gn6c8PRv50|&_%zJw(1hea3Y;y@!F zmhHT>Q1pzg<{v*O`*OR6!s=i3EizI7xfa!4=@piSAd0=Wv>5`I-wycKOFs&O3%Wu~u6!2$DWF!5Y$jJ~djv37!ym|)WG4q^9K}ed zbnu1rzqCp7?g^&U!_0FP(MoRfDzMTH;n}qe?INsw+!yk?z%AECn3GM_!=7pU}xs=kt(uT0VR)UcGr%G=II9w~etCFzB(c>`RT z_iH4~o*cesg<|J}n`a~?fjmyn@R#>WZ>*_~70j&p_DChvLo8f=f`1Ne#iWTjtpeSU zp)}3b2ZEJHBgf@z-(|P&o2%S(KPhG`nSDF4;>|M)53P({i0k}og6<+mZ+=#o5I=o1 zDUFKlnXu*K2_~LI~G|t*}8;hkBeHp@eADv7o zDV)q`2}#&~f9IVDCCRyY>AM}UL#310ZE z!MzF<5}ew7CE+U!A{&p~9jQnEZ~+`RUlCsUbvnrs;Dpxc_mb{yJ@f82`w((frkTt3X8g8V`^32UcQtLGD&* zgzT?gx*rB&z^eoqe?}5_Nkfdq?qG!qCTnA7KQHey!aZj5)2l@p<;JFu=F4iUOr~|9 zBiN%URZCFxf}FXJhQhBZnS6a0u5}#!O8G=(*Vcyo>Ws27BqjdcWNC-kMP?YPXO`Kao*N#{=bD*5jQL!?tB)gj6q0%od^$2 z%w%UH9t0zcWup7!dm8z$OcPn!Sl;fAwEkwDX@K7m5!wH3XIEi<-EO#>q1Bd#6_Qg8 z1j(ubP&N^gxGP=sSNP3@s@2uAw$$6wL-kJq){Uj ztOs*HYnl((NPV>1$bs(YMiBiWc%EogxRcJlY7X>Q z#V%^v#&FT*2FV1Y%N|eah5w6a?)mpe>3(349{xM5!6**#*AoJT51;}i0s`ZIr2ED= z7RL_%A)>nzrvKXYn(zdz>#7w|y1?HG@LG@3Q>h-ED$C{rUsAw6j|yVX2`F@ein=LV z(g%cWKv(``=d#@hL<=0Vpyx%)x2OA9d``PWt8IOQFgX+I&yrdqBeO^@N1|?*+**d>QP%z$r3tJB zfe!|HH~}}%2(JV=z^3@yB}j!P5Fp?Rlh}tG_p~!N4NBLi#J6t4s&CiJf$U_Vu2T^k zLi$M5qYrB^QPG;GfDdpc(bHASBkyl1JsUcb8M&NrNc4ma1kpH2|BN3I?5ZkXUIKnc z7^EZJ8clpx3bX)I3i$_K`4vxK`qO+e2VLA|n~wY0jubhIv4 zbUtg_#WmblS;@a&;nFTiDJ=}C6JoG@qMeU+U|6X&S+fzep1Qi?o8V6=c~ctqfoWx# z4rq*I1@ssM+#bd57rF6Ui{yn40YK_nIts}-s1i=BD)9Zc=(0k;TOc^Iyw8659hKYpq9zT0FyT0Rg!%f3D zeRWB-)4IdYcjdq2YY;XvzU(l#i*MnUJ37_B?f%+V3=MpXj$2)GTh=rO^t z1WPQy8^#_eBJpwIdjM%%y6QIbvHz^(B(VW6 z7Oe@s&ip}~S0HAr zRbclbq!=R)+lCJPjnEAtYJp)Hyx3dcdvjQt?6iki%BpE7524GiQ6jd#|AgzjWw_p& zBSAyEnQsv~LYMSw_FKMf^x9+XWuI$PfC_Hc+2`s+O%S1OZH4r|wDkd4Fay#`YNBa` zgBX-JSrnq0e2k~6d`^Caoj%VkWS$jft8HK&t#z>cCTB^oI@fQSPF14>f z`uF&`DWFK9Rmk6Oj$>df^W^+oDy%O;aX+#x*Ct8L$sR2Uanb=UnoMw(U;6YVdmZ9? z?Zo?(eN99f3?>Vr@8;9k;G)x|+m1YIKMS?t*jr%!txHJ{yNM10VBh1V zE6kg?9TZw`xZz@AL4!Yc41Z<5fB69P`*PUKkjg`o%>M%2cWCDTz1hR` zh3%A_k~6oYUIQ)Lt@P#_F5Cijux+hSAbuQk_xz~L@HBW%(7q`t+w(aPLx~$z&EgwE5m75ZJK214M=7=L$elQc>^XHJbvdu>ER9%XSHp zME=XocdLO6{?^_oTAbaIERi2Ti)HL`LKpR133~!34vnf9L(bMeVS|LaO z#H7<~5WJXo@L&}OT|WZ z&mTXLeb5Y90QUs6ct9;BqtcOgbG+8DGdHW$ZMl?hH~Z&@-;(@a5*t{`qzMMpyVI;) zVh+ge7WMyMEc8?2|BQv^mh)rp2pFJAzrX?8$O;y}7U81LRgyTnLe7ToKjY^j?Ebwa zy&7-Xz}gKHIlifam(Nu20sR}rkERe)wOuTi9IrA1A+qV}>4?7TO`T-LY|9F?f!-L# z#`UxVm~Rc!H8C?JkfP;e&z|!;?W##Kx?Uh`1Aln~%;)HM=9U{Q+ty5$$<*!Oog@Ot zWfQ~TeuFX2)NZ8RVp%G%l$hu|tau7bO2BaUHNj&N2pnpzQiA?L1pWV)>H?Sh{!(3? zFm^ZqMtKa=JL&u<7_}1t-LJp2rm^;-Hz5x+1pq8)MJjBh0*Gc)56o&fidb2uj*{Q6 zj1A0^PC3?b#~QJkiwCcvDpM=|7dRG%v(!46>>tN(o|5D)rmn<+{Cp+erhAsWdrK|H z9GWt&e>c9aeunmi2+6zQi?iAQv`Fk^(Ti3#^b!Jr*B;2ve%L!8BZ~pu%!c@jW_7Qd zy|i1;>y~RHqteoH`P-qAs8Zb@7i@eFA^&x?{OT9)NLjA;BNkY1e$2huS^9gYi3Pj> zduG!sR3&~L&Oe-@*i>f?Wicjy^0~Y<*YqUk$~eai;k(@@HMBRiXmp@QjF0t&hB+!4 zUSE>hH1XW!`YS!@$+B_)g2^g_X7om)uHM%#J9?ga)8YhxUK%jUJUAKE9Re6AONI*a ze~v|U2qJC42e@HR70TKzt;gDx$YL%zozrcs+COe?R;)4*-?9Cb3uL@D+!&opaMY7ry03N-kX93{oMq}X9^@W{4<|xHj!bR zL&Ldp#KZ`G=|4McRR5#{VgdWGL_;g7h2jHnq)$1S{;zxEcpStJ82vf|N(H`pSXF?V zsGbemtxU>u?f1LWp7UC^CujZh{6A*C@r>b31xY@f3FO9h1E5PD=~CPGWEq4_fxem^efw)PZNsM_N*=`3tb!smnjbQ z*MI+ci}^wm5>ungJ-X{uQh=D8Z?F01wEvM|*y^^|&TpK0d%U1M_BND%l2-0)5Z6SA zZQ@VB#^}~g{GRE&F?5w!&DO{``K!L9@;c}_6@m5N(4*R?Hisu;0D5FuicSp{f2@{B zM6{&#gb=z<_sWT4P*$T`*x8X|z5F$Y%%T3_S*xxe^6+uL4G_Vk)C_L?Y>uNvdB{MK zElwB0^6(h^f2@K@4kn&xcMHXO*dF6=_7_Gt?4i>E;6P4cPC_;WShE?~coRn1t3#nt zmAkwj;048To3=6%4a6RvxDU&UA!xWBdnJYZVz8OV>yvrD zD8R%>Sv<7@R&?K>^yWSolgK$b0wPuZgCz3gSt8l~jUU)m?9&_P+t{KrvsOuIsUAN=o6W!rByXW@s*aD>-hr z>>Y1ZZrA5K??1DwlFbCOsQ0<3DM7zpsLikdw8fsn-?pCSB8^#3tpDNQ8dfJ<}TSE|PGT$r1mxdo% z4#?RFGIQHPxV%D>VpRj5M2BT@1d!C^2j+^Oww^I4Jqy?dXf&{Y`LEas|2|bE0IsLX z>2J&BeprxW3PO!x=AXfdqPsj=INtB(-)iG+c-3h;JoRH9(A$t4-VAhy?co#oZ;n}TRF7jk^1A26c_2FfqGX%U znCMj7wh*gW3{uDMTVI=)t7Kn;rn4K^gvZ<++A;p1j0O{1X(ZZGGyJ=U1_QvXvbP(? zx>NE%Qlx{LpjYz`rC#U1DfOSbe&=_YvEcItoNmt%!9ybb^D-wrr@#xUYIJ{;*2VVG4*=jy`p5%ioC9UW^%<-V1B#U=iI?LJK|HHQxSS74-ff zhf1XJKG#R03rUY)5skM+^HXBS3G7Fl`x?KG`M zU=$fNbkl88C4~8mZy;*{>Iy(c+yA#rgzg=fc&Rdc+Cxn;CU8rLDDUILxj)}cxu<(p z*_^ZQ=sQfPcl$;z+usuT&77!hnB)hbiF9$aBUb=k zr~(9BI)Au29Dl8L#B9?&#B8Hl9REb%UONSv@1gu-T*6?E;!TYRrYf{SCz*K0-W(6{ zy2KATs;A_I>B(@ph`_&rvrzsWHXwXv`%v(2#|uX{4;-#ap3AiLw=AGZzQ{t$GMta; z|Fc2b!o4@OivkoZyHDPN6iloYZ~li_W@E#ABwjCBqW{I|rakD5d}rJc_%=8&F?dC+ zsDhux7NFrj${045kz6&-w|p_@^M~J~TD}&R^H=0aa{w*pB=KDf00_3Qw4DB+8-A7B z{0V4mh`zqLpmu;;`&S2iz}rny#sef!hr0&x3L;YB2B)VP%AiHLHz1?D)Q-=)4y4N} zWU&IQX0?1YJ|hHF1*HKK&vihCuD+dLV45qwXnafi$qW$gGljTaZ(AR8lUcGqOHNNM zRPZ^pJbQUBAx;q@+hwLyr9(nR^bfs}NaJ<6alb)GJ*i~-HT7~2oB0VyJaSUeU19b~ z4eYZB3Hn{@Q4AQ>w|&0jPn((o&z|o2`tAYhER(bd{|TQpJ!i2778)FcyEsc1dYH0V z!UZk&QKA-nyJPE@vF_JjT{Hn!hX>+r@q3ThTI8n5&}eM2<;TRd9OTIgit68vOi{!D zk@r!Jzr#c_J-D%liw;s@b~$IHN(_Xu-B1jHbnWz4Bx&6-ZHNEtPvgByB9Dvp&)|k% ze}>$N1!S-scz>UJxhp;>W$yL(-x#&R4TA@GFJ9p3mDBrR?pl?4PomDMI ziFUw-3V3V@z{L{TcM>(23g9EzoM>HHsc^sV3zeTDbS};EqCCZKF&s`sWD>%|$t#@i zLv->v6+>D9A5~6rAJ>fBhf?JK$e{2ewQ1vf90J3L%6bypF5QCxwFjEqX0B0iXGNc> z1)&s^^q`(;)uBKdKUsJ`gEG?-C?444pM4Uqv8>J{3IyjEoei5DB=pUc^*&dmt`Dd$9dVopRTpPwE$H`&y;Yo;gFfT z$bM2iekmiUF#?nx=Tt83Jv6Keakfr7Rfg|9+fsyLjKQr0rkxUb0P30pJ%E|<$a4?> zzQLfHQK8e(#dT-p1zspPZS|CR0KV|gP$rUjDSs8Uycc$g*QPt$u|!AqsgFnO-$l<~ zVUp13C}k2{{h7U8c1;ot8-Ai!{Tnc|Ic_S05EJS_$M^9TV5+=u2?+$fBN%z~u5&yu z*RBi+^+D^B=>Nk?9ry8A+t)8vrINu|b>0a3YeVF3f`^(YmF~$& zFudwqm3zHtd2;zknDxHsk9W!i%K|rSalYA5-u<@hgR2F?t&oT|Z(jZBv#<4^D(~s- zKe|lzMcq>f)*(Y;%&aoGfrU9AYeE3gyvN!2;!Q42WrV;mXh5)Ut`eSDrot7|B|b)N z+W!sUPw_@d&T)<^=_(pBbGE$S9rk!XIGRXK!3u-vA6yMY4)vfaqhSnC=lG!t#YP|b zP4$VI1}gj}KN{U?4#Ql8IB1dbSX=O%d$=z6PHR%z$xmYOv8EtO2BX`cVrz$Aw|6xb zIVixRS5zfA#F5b6bR?oEF2Ez88v~nX$R=At)#2xtUag2sB>bmJdMJiD8zWH1jKVa} zeO12pxlnq5qLgm5Cu=bmmBp+>90+9E9<22ggldAMtrX(CqVQgTSUPsEe<~8;wA$Q@ zJ0>kc$G~9r^;1*mI3;h)IIV35Vt1Z2eoSq8RauI$x5&p4^_H0{+^Eh0O{l3n!a!}G zpmN%&*D=xh-N(d5G6l(_9?^Xj+fXseW^PN-plc64Gr3VEZEP*5!O6;~xHth@5r{Eu z;F_IzBnP&~$c*S?U%t}TL@}8_PB&Dm7?q`3T$9#+tHc#P_T6w4)S^wDFxx4C^VAaA z2xK34LYx1mph-m&7sL{%kY(H==GU5B5z|#6sNdnc=uz4Oj}DyF5^?+^GqVlel(kUO zHtfsTPn72k#eBHxcNXV#84KT;Aj{uS?qXv*`!QXV0}^g_EX9oPZ8V%t*AByXyV;AM z!8rg5-^G@Nyv(_+RAnIovpVAW%hz5!q^zSJgs=gMEd@@-HdBs*MyP6P*_ITv2b77b z)k&xNrsN3O7*4bgpB&T?#qSSG@@?OgCYi7fC5ZHN{VGmk?4Hp}V^B-lgf}AC!cl)Q z1RH_9hPEJbi$3hW4*G38mKZo0Ygb~NP|UrE%CI-xdXXOUR4dhO?rL7P&~tzJ%=Uc3kzLr${IpD5gMEt-+Y=cy)wd7#X|t-RoCBvxKrv`A;l} z@aO&LpL%JsKhE!rZTCIS|HbCI9a(Z7H>XYpy}Hg?*XT3*{F&=m1kTStn^fM8J5o;@ zMdsGHT>MzvuaR1rXyswY8U!JMl0IU-^V>Z*eL~14;HH~@5lr ztRyaSl<vF87&#axnxev(kL2jtOXbY^U3v(%I%`c1`(9OlCNh;>px}#!*Algm-2Nfqq3AG1 z7YE_$&L~!ZA}y4%r@Rs&7jWf$>fX($;7psUStdDE%(i#)OS*5{{w>Elz%gsN;NePt z@2$UOtyS~6Us|!sb));&?2T)DgM1%48t~@^V9V>qhcv>^{dM1TKVp%=fm6VcG zz)qOn!HE~hYBGgP>0kEV>F>d0T(vs6^JV{~f^CBJf8(-+hEEfA?Rztcouw@p3~USO zZdy5zQr#mQILI0Y`Jb;W1;8R4mt|N7N%%Vm7j?o^FeOqUc}O@-g%c|7dJM;dzE}bzhAStu82<6TywImeuDfkX{5Dn>N%AJ+ExLbaNiGU)egZ zS`etQaMlK0GTGAm^U^%n=;@2-z@P1+uP~937>fKyq1_bAqGH*_sdBV!yO>u8Hsltc zbm;^aIq8k+N-Qd==#p5>?1_U#<~GJmgCCZ+LR{Tt_L{%{MUKcvl>p#bJKBaC~p=%agi`**ehfDS9v4 z9@#7Xp(p3pl%9@!DN|JZh27q#p>p<|SH}a|wH6f{+Ho?>GxV=%)ZZWG*bT!;(secI zzUidt+EgdkLT-G~i2kBd|Mpn(c3Wvq&qgw;$q&Urm}eL1JvS?yNW*}jqwth+yq=;O zLd04x%gj;eX^CJXMY7-CJ7L}*T9>6Ek+hz&t2%6?jQMyiZ25%}!8DbvswOgV`Td1> zaCvGK-F=Iu$A))@mcL*=ZXF}rHKxfA^~heqztyal(CeymI$mTPe0Bojl&}|6wi{)_ zJ`gE+&E9v3UgNt&YY4*r_D7c!>$$q37HtUv&EGkv91e@u`U^_MW`>dcS?j-Z4$pqL zMrmUiiAGQj>|7VC*m>W|$-uJGAsVQT62OF;&`36w>qekKg(feqcK+5<{L=)P1ET4+ zD%2Tbi2z0+G34ksYd_1d`yf3tSB5mPV)<6o1AQ7onOYFhnyO4ai`XFYnth(bd!~&D z?4ioLl(h2b<6k;us8wm{^fcj1*-*SQnHW5Zsupj^9^%t9X3J?~1%9A>5T=cl>X43g zVTQ+BI@4&NP8NM0L!XDsCRfr~$*o`3G$wHd<@z>svTj8G9Nk1KH^uUmm(S3*ldDRrFVE|xNnR@YT;n?P*;(gQE12~rRrNf zL*AT>^_hhcAHv#HGzweobPPw0&mJXw>Le zwvr}FxfD{)%d3ZqL-LOFvXyd2zqM`gOkO6ZV-Iy&MC;b{(j`}J@wk<`YU$Ug#0-rQ zUiEo;(57pQJ1yy_6~;D;n+3nvke0@eL$j-C>SzZXy7~ONWzHaYh;AAp|5NkcTNaPV z?{M_$Pa($7)|ptQm(EmbtGByOAJjArWf$PuSa9>M`QBiKe>mHhr+njdiuQaC$m!?$ z6d^(e`unZTf7iJUyt&@{J&&IoL@CeC!C$d;G%#5@5UMCASiYZ`M&3-xh}zjkpP?7N z#I7ORYl$Gtf4$1efwFEs;OqRBTJc$=mie)Cy7EPuXNLbE$3~_x*xI9bHs70WVrQ*{ z#Yd%LR0^fZ-5pjFTe$4z)=|t`)4H=LzeYxzX?V8~?`t0T_UiZau&me24=9qAr%(+*#Y6ipoMXot-Xdb~#B za&o0UQmjRb*FK5f1J?-2j#2iVSl^px8-^;vXR-184|#Ma8VtSkl(CJH^-7j_Z}C} z);=|kz4}0{e>tC3-;%;bJsdHA4D)+(!V``|UG z6=XUsM`K#9GYp8*iaR|BJF@s$p_(@$krIF^vy(E zTcnjDjqKf6hILPOlDNR=Zqvh8BDr^CUn1>)czy}D7+8RcG>O&vEH}JL$@5lI!>#BR zbn!B=RN7uaK{9Jsp>1Pfi`9)J_+~{>rP3O*|if*)TcIeDINz_hoC*@3E(x^QV+SNBfgB%CA_E;4BrPswvCQ z>AnyEO%4xqZFf|FgJ#MTUpvmTFrn>QTiAL!Xxx6y?iMaWAN^&1;vbB)?-wy!gzid0C+Q{BDo{U(}o zN!{o|lLLuZi;DgY%Ry8#Yvf@R_k6WpmG_92I%h50u`f%gI7B|Fj@#J;rR|Aco+!6J zPp}R>MP|QaR~mIYIeF}wwQG)~XdAg)aCZ!}uyOR_aJ7}=5V5d-&dao*zj1Tm9DJ0dq&Fosu{llWyOR#)%k}(VZw{NI<9LVfnheQbb zct*oSZDv1x-en;<(&+g7wtpt~q-Bd8^>x2^-S+G1xpy$M8@VU7<;-)rGxO>~i7t7* zrgHFcPs?^O`w5=T?Y`b9OH54c%(XL{d7umoF?dEi!?)I(3LJL7KaqPP2O?yxpMD8d zYlYoA0aU)~&_J8~Q6Qq3=|(&H8+FbQo}&Yx>pH8e05-tGMl@Bg4*Gi<&A%-gJ(87MSp+zwd z_;|(Wl{h$x@l|lvrl$Urh(~5WX@u$De?d87)XQuO5XP!of~8}QT{~+>@We{$VdP^oCf0QtmS`3^=KU#fhT36H=uc+)#>SKtD4AgI#(wGd|n8b-nQ*g z3Vdn+xo`dNdgBoMnzsWTqE8>x88xU9J3_udAXnrB1&+B z$VBiR)iyY3S9P7q)sLV_>!H7>VAd_=2se#LmQFln`n;E4E!6_~g6V91pwnzxGKs&% z|1$^hEP+tb6-jJi@)G z?BG^1o>*D*XVT^|`O!LtkEkj7RU&saL{3c@>spfA-jnrUklb3YshXH9jEK)0zeCdv z{w$SFh6!B3QaK%+*uiCR`G?nx&{@+(H%0t2TN0oduaOk+6>iTNs%R)S70 zHL)~Ecb0+d;Be-)1xL? z99e^~+gr1Wy~Qcln`Hg)F*K zj}FWkbxJ`o#4lZ%hBl?FWw`X*Y=(fhRH#L}j+ER(@A@VqeTsZcI~E7?$w5ay$r;C{ zl{negO_pbEP}a@On%HhpjYR&v34 zaJTpjS{M%o^YbTcDBP?D91_KT0_javbCebJuOe1H9^d}sd=_E2+i=4`)RLT<_^ZkU zs&780_nUEfnH;_?Y+hMh9N(3$nCk)5JfznZiL|mF#qXrC2iv7)DmX|HX&;*vgWMPp zukHAoaw_ce=*we`NcGH20FBPb4>U_zU#A_)EteT*M_gAaKfptyWaAs0-9Y?Y!!te_ zL13?smm3n~s19n{r_!f1c-f(^JkIR!(^#Z-9-eWvn z_42X&;^I&d+(zB}K3^1L2a6^WVf;P9wR`(;F-4&sKmBhf^_ZB4yy6-7*C1sy*FUcf zTGK&bAu%?q0WSX#4QxRoHt1~%3YIPS=&ai!;vX`r(|>v@-A#VeIT9?S@b0Aq3V7-l zz%>VRGbQoy%Rl`Z{^$)SgfA5h3joazYtBn#a8s8DqKzPpUMs4t_D>)5Zjc&Ok`KLH zQO1X4xKzP3fvLy{`;!~)eR(X(|CkW@letu?1=Br#beo~3jsT&Httdx&WM@73i*-DQ zYNPyz^9yA0!KtW6huU`C7LkFovkXh3P)YVQ#)fnLx|XHZ zGnD3`=h6E;+Ta%+_Z_;f&P$#0z2aVBVTw$Q3tt(q;{q!`f7g4X*K`GXRjy1u{t zJ{s%flG}_)LD~mR@H)T9{owoUx&RKz`tco_;H{n{wO`usku-A-8Q