diff --git a/.env.example b/.env.example new file mode 100644 index 000000000..a16f944bd --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +GOOGLE_API_KEY= diff --git a/adev-ja/src/content/introduction/essentials/components.md b/adev-ja/src/content/introduction/essentials/components.md index c19b87db3..c04c6c64b 100644 --- a/adev-ja/src/content/introduction/essentials/components.md +++ b/adev-ja/src/content/introduction/essentials/components.md @@ -1,5 +1,5 @@ -Angularでアプリケーションを作成するための基本的な構成要素 +Angularアプリケーションを作成するための基本的な構成要素 コンポーネントは、Angularアプリケーションの主要な構成要素です。各コンポーネントは、より大きなウェブページの一部を表します。アプリケーションをコンポーネントに整理することで、プロジェクトに構造が与えられ、コードが特定の部分に明確に分割されるため、保守と拡張が容易になります。 @@ -73,7 +73,7 @@ h1 { ## コンポーネントの使用 -複数のコンポーネントを組み合わせてアプリケーションを構築します。例えば、ユーザープロフィールページを構築する場合、ページを次のような複数のコンポーネントに分割できます。 +アプリケーションは複数のコンポーネントを組み合わせて構築します。例えば、ユーザーのプロファイルページを作成する場合、次のようにページをいくつかのコンポーネントに分割できます。 ```mermaid flowchart TD @@ -84,14 +84,14 @@ flowchart TD D[UserAddress] ``` -ここでは、`UserProfile`コンポーネントは他のいくつかのコンポーネントを使用して最終的なページを作成します。 +ここで、`UserProfile`コンポーネントは他のいくつかのコンポーネントを使用して最終的なページを作成します。 コンポーネントをインポートして使用するには、次の手順が必要です。 -1. コンポーネントのTypeScriptファイルで、使用するコンポーネントの`import`文を追加します。 -2. `@Component`デコレーターで、使用するコンポーネントの`imports`配列にエントリを追加します。 -3. コンポーネントのテンプレートで、使用するコンポーネントのセレクターと一致する要素を追加します。 +1. コンポーネントのTypeScriptファイルに、使用するコンポーネントの`import`文を追加します。 +2. `@Component`デコレーターの`imports`配列に、使用するコンポーネントのエントリを追加します。 +3. コンポーネントのテンプレートに、使用するコンポーネントのセレクターと一致する要素を追加します。 -`UserProfile`コンポーネントが`ProfilePhoto`コンポーネントをインポートする例を以下に示します。 +`ProfilePhoto`コンポーネントをインポートする`UserProfile`コンポーネントの例を次に示します。 ```angular-ts // user-profile.ts @@ -111,7 +111,7 @@ export class UserProfile { } ``` -Tip: Angularコンポーネントについてもっと知りたいですか? 詳細については、[詳細なコンポーネントガイド](guide/components)を参照してください。 +Tip: Angularコンポーネントの詳細については、[詳細なコンポーネントガイド](guide/components)を参照してください。 ## 次の手順 diff --git a/package.json b/package.json index 91cb22079..c1efc9cc0 100644 --- a/package.json +++ b/package.json @@ -13,11 +13,11 @@ "test": "yarn test:patch", "test:patch": "git apply -v --check --directory origin ./tools/adev-patches/*.patch", "update-origin": "tsx tools/update-origin.ts", - "translate": "tsx tools/translate.ts" + "translate": "tsx --env-file=.env tools/translator/main.ts" }, "packageManager": "yarn@1.22.10", "devDependencies": { - "@google/generative-ai": "0.14.1", + "@google/generative-ai": "0.21.0", "@types/node": "20.14.10", "chokidar": "3.6.0", "consola": "3.2.3", @@ -32,6 +32,6 @@ "textlint-rule-preset-ja-spacing": "2.4.3", "textlint-rule-preset-ja-technical-writing": "10.0.1", "textlint-rule-prh": "^6.0.0", - "tsx": "^4.16.2" + "tsx": "4.19.2" } } diff --git a/tools/translate.ts b/tools/translate.ts deleted file mode 100644 index d8ace511c..000000000 --- a/tools/translate.ts +++ /dev/null @@ -1,225 +0,0 @@ -/** - * @fileoverview GoogleのGenerative AIを使ってMarkdownファイルを翻訳します。 - * - * 動作には Google AI Studio の API キーが必要です。 - * https://aistudio.google.com/app/apikey - * 発行した API キーは環境変数 GOOGLE_API_KEY に設定してください。 - */ - -import { GoogleGenerativeAI } from '@google/generative-ai'; -import { GoogleAIFileManager } from '@google/generative-ai/server'; -import { consola } from 'consola'; -import assert from 'node:assert'; -import { stat, writeFile } from 'node:fs/promises'; -import { resolve } from 'node:path'; -import { parseArgs } from 'node:util'; -import { - cpRf, - exists, - getEnFilePath, - getLocalizedFilePath, - getWordCount, - glob, -} from './lib/fsutils'; -import { rootDir } from './lib/workspace'; - -const apiKey = process.env.GOOGLE_API_KEY; -assert(apiKey, 'GOOGLE_API_KEY 環境変数が設定されていません。'); -const genAI = new GoogleGenerativeAI(apiKey); -const fileManager = new GoogleAIFileManager(apiKey); -const model = genAI.getGenerativeModel({ - model: 'gemini-1.5-flash-002', - systemInstruction: ` -あなたは技術文書の翻訳アシスタントです。 -Markdown形式のテキストを受け取り、テキスト中の英文を日本語に翻訳してください。以下のルールを遵守してください。 -- 翻訳するのは英文のみです。コードブロックは翻訳しないてください。 -- 出力するのは翻訳結果だけです。内容の説明や補足は不要です。 -- 見出しのレベルを維持してください。 -- 改行やインデントの数を維持してください。 -- 英単語の前後にスペースを入れないでください。 -- Note/Tip/HELPFUL/IMPORTANT/QUESTION/TLDR/CRITICAL から始まるプレフィックスは翻訳せず、そのまま出力してください。 -- prh.yml に書かれた日本語の校正ルールに従って翻訳してください。出力に prh.yml は不要です。 -`.trim(), -}); - -async function main() { - const args = parseArgs({ - options: { - text: { type: 'string', default: '', short: 't' }, - write: { type: 'boolean', default: false, short: 'w' }, - }, - allowPositionals: true, - }); - const { write, text } = args.values; - const [target] = args.positionals; - - if (text) { - await translateText(text); - } else { - assert(target, 'ファイルまたはディレクトリを指定してください。'); - - const stats = await stat(target); - if (stats.isFile()) { - await translateFile(target, write); - } else if (stats.isDirectory()) { - await translateDir(target, write); - } - } -} - -async function translateText(text: string) { - // Upload files for translation - const prhFile = await fileManager.uploadFile(resolve(rootDir, 'prh.yml'), { - mimeType: 'text/plain', - displayName: 'prh.yml', - }); - const translatedContent = await model - .generateContent([ - { - fileData: { - mimeType: prhFile.file.mimeType, - fileUri: prhFile.file.uri, - }, - }, - `次のテキストを日本語に翻訳した結果を出力してください。\n`, - text, - ]) - .then(({ response }) => response.text()); - - process.stdout.write(translatedContent); -} - -async function translateDir(dir: string, forceWrite = false) { - const files = await glob('**/*.en.md', { cwd: dir }); - const selectedFiles = await consola.prompt( - `翻訳するファイルを選択してください`, - { - type: 'multiselect', - required: false, - options: files, - } - ); - if (selectedFiles.length === 0) { - return; - } - - for (const file of selectedFiles) { - await translateFile(resolve(dir, file), forceWrite); - } -} - -async function translateFile(file: string, forceWrite = false) { - consola.start(`ファイルを翻訳します: ${file}`); - // Upload files for translation - const prhFile = await fileManager.uploadFile(resolve(rootDir, 'prh.yml'), { - mimeType: 'text/plain', - displayName: 'prh.yml', - }); - const contentFile = await fileManager.uploadFile(file, { - mimeType: 'text/markdown', - displayName: `content.md`, - }); - // Execute translation - consola.info(`翻訳中...`); - const wordCound = await getWordCount(file); - if (wordCound < 10000) { - const translatedContent = await model - .generateContent([ - { - fileData: { - mimeType: prhFile.file.mimeType, - fileUri: prhFile.file.uri, - }, - }, - { - fileData: { - mimeType: contentFile.file.mimeType, - fileUri: contentFile.file.uri, - }, - }, - `content.md を日本語に翻訳した結果を出力してください。`, - ]) - .then(({ response }) => response.text()); - await writeTranslatedContent(file, translatedContent, forceWrite); - } else { - consola.warn( - `ファイルが大きいため、いくつかの断片に分割して翻訳されます。翻訳後の整合性に注意してください。` - ); - const translationChunks: string[] = []; - const chat = await model.startChat({ history: [] }); - let count = 1; - const maxCount = 20; - let lastTranslationChunk = await chat - .sendMessage([ - { - fileData: { - mimeType: prhFile.file.mimeType, - fileUri: prhFile.file.uri, - }, - }, - { - fileData: { - mimeType: contentFile.file.mimeType, - fileUri: contentFile.file.uri, - }, - }, - `content.md を日本語に翻訳してください。翻訳結果のテキストを100行ずつに分割して。その1番目の部分を出力してください。`, - ]) - .then(({ response }) => response.text().trim()); - while (count < maxCount) { - consola.log(`\n---- 翻訳結果 (${count}) ----\n`); - consola.log(lastTranslationChunk); - translationChunks.push(lastTranslationChunk); - translationChunks.push(``); - - // Continue translation - count++; - const chunk = await chat - .sendMessage( - `続けて、翻訳結果の${count}番目の部分を出力してください。${count}番目が存在しなければ「EOF」と出力してください` - ) - .then(({ response }) => response.text().trim()); - // Abort if infinite loop detected - if (chunk === 'EOF' || lastTranslationChunk === chunk) { - break; - } - lastTranslationChunk = chunk; - } - consola.success('翻訳完了'); - const translatedContent = translationChunks.join('\n'); - await writeTranslatedContent(file, translatedContent, forceWrite); - } -} - -async function writeTranslatedContent( - file: string, - content: string, - forceWrite = false -) { - const outputFile = getLocalizedFilePath(file); - const save = - forceWrite || - (await consola.prompt(`翻訳結果を保存しますか?\n保存先: ${outputFile}`, { - type: 'confirm', - initial: false, - })); - if (!save) { - return; - } - - const enFile = getEnFilePath(file); - // .en.* が存在しない場合は原文コピーを忘れているため、.en.md に元ファイルをコピーする - if (!(await exists(enFile))) { - consola.warn( - `原文ファイルが見つかりません。入力ファイルを ${enFile} にコピーします。` - ); - await cpRf(file, enFile); - } - await writeFile(outputFile, content); - consola.success(`保存しました`); -} - -main().catch((error) => { - consola.error(error); - process.exit(1); -}); diff --git a/tools/translator/main.ts b/tools/translator/main.ts new file mode 100644 index 000000000..11347cd3f --- /dev/null +++ b/tools/translator/main.ts @@ -0,0 +1,72 @@ +import consola from 'consola'; +import assert from 'node:assert'; +import { readFile, writeFile } from 'node:fs/promises'; +import { resolve } from 'node:path'; +import { parseArgs } from 'node:util'; +import { + cpRf, + exists, + getEnFilePath, + getLocalizedFilePath, +} from '../lib/fsutils'; +import { rootDir } from '../lib/workspace'; +import { GeminiTranslator } from './translate'; + +async function main() { + const apiKey = process.env.GOOGLE_API_KEY; + assert(apiKey, 'GOOGLE_API_KEY 環境変数が設定されていません。'); + + const args = parseArgs({ + options: { write: { type: 'boolean', default: false, short: 'w' } }, + allowPositionals: true, + }); + const { write } = args.values; + const [file] = args.positionals; + + const fileExists = await exists(file); + if (!fileExists) { + throw new Error(`ファイルが見つかりません: ${file}`); + } + + const content = await readFile(file, 'utf-8'); + const prh = await readFile(resolve(rootDir, 'prh.yml'), 'utf-8'); + + const translator = new GeminiTranslator(apiKey); + const translated = await translator.translate(content, prh); + + console.log(translated); + await writeTranslatedContent(file, translated, write); +} + +async function writeTranslatedContent( + file: string, + content: string, + forceWrite = false +) { + const outputFile = getLocalizedFilePath(file); + const save = + forceWrite || + (await consola.prompt(`翻訳結果を保存しますか?\n保存先: ${outputFile}`, { + type: 'confirm', + initial: false, + })); + if (!save) { + return; + } + + const enFile = getEnFilePath(file); + // .en.* が存在しない場合は原文コピーを忘れているため、.en.md に元ファイルをコピーする + if (!(await exists(enFile))) { + consola.warn( + `原文ファイルが見つかりません。入力ファイルを ${enFile} にコピーします。` + ); + await cpRf(file, enFile); + } + await writeFile(outputFile, content); + consola.success(`保存しました`); +} + +main().catch((error) => { + consola.error(error); + process.exit(1); +}); diff --git a/tools/translator/markdown.ts b/tools/translator/markdown.ts new file mode 100644 index 000000000..37c70c7cc --- /dev/null +++ b/tools/translator/markdown.ts @@ -0,0 +1,14 @@ +export type ContentBlock = string; + +export function splitMarkdown(content: string): ContentBlock[] { + // split content by heading lines (lines starting with ##) + return content.split(/\n(?=##\s)/); +} + +export async function renderMarkdown(blocks: ContentBlock[]) { + const content = blocks + .map((block) => (block.endsWith('\n') ? block.replace(/\n$/, '') : block)) + .join('\n\n'); + // add trailing newline + return content + '\n'; +} diff --git a/tools/translator/translate.ts b/tools/translator/translate.ts new file mode 100644 index 000000000..dcd42f056 --- /dev/null +++ b/tools/translator/translate.ts @@ -0,0 +1,75 @@ +/** + * @fileoverview GoogleのGenerative AIを使ってMarkdownファイルを翻訳します。 + * + * 動作には Google AI Studio の API キーが必要です。 + * https://aistudio.google.com/app/apikey + * 発行した API キーは環境変数 GOOGLE_API_KEY に設定してください。 + */ + +import { GoogleGenerativeAI } from '@google/generative-ai'; +import { GoogleAIFileManager } from '@google/generative-ai/server'; +import { setTimeout } from 'node:timers/promises'; +import { renderMarkdown, splitMarkdown } from './markdown'; + +export class GeminiTranslator { + readonly #genAI: GoogleGenerativeAI; + readonly #fileManager: GoogleAIFileManager; + + constructor(apiKey: string) { + this.#genAI = new GoogleGenerativeAI(apiKey); + this.#fileManager = new GoogleAIFileManager(apiKey); + } + + async translate(content: string, prh: string): Promise { + const systemInstruction = ` +あなたはオープンソースライブラリの開発者向けドキュメントの翻訳者です。 +これから次のMarkdownファイルを日本語に翻訳します。 + +${content} + +あなたはこのMarkdownファイルを段落ごとに分割したテキストを受け取ります。 +次のルールに従って、受け取ったテキストを翻訳してください。 + +- 入出力の形式 入力: { text: "## Hello" } 出力: { text: "## こんにちは" } +- 見出しのレベルを維持する。 +- 改行やインデントの数を維持する。 +- 英単語の前後にスペースを入れない。 +- Note/Tip/HELPFUL/IMPORTANT/QUESTION/TLDR/CRITICAL から始まる特殊なプレフィックスは保持する。 +- 表現の一貫性を保つため、同じ単語には同じ訳語を使う。 + +翻訳作業は、次のYAMLで定義されている日本語の校正ルールに従ってください。 + +${prh} + +`.trim(); + + const model = this.#genAI.getGenerativeModel({ + model: 'gemini-1.5-flash', + generationConfig: { + responseMimeType: 'application/json', + temperature: 0.2, + }, + systemInstruction, + }); + + const chatSession = model.startChat({}); + + const blocks = splitMarkdown(content); + const translated = []; + + for (const block of blocks) { + const { response } = await chatSession.sendMessage([ + { + text: '次の段落を翻訳してください。\n\n', + }, + { + text: JSON.stringify({ text: block }), + }, + ]); + const { text: translatedText } = JSON.parse(response.text()); + translated.push(translatedText); + await setTimeout(3000); + } + return renderMarkdown(translated); + } +} diff --git a/tools/tsconfig.json b/tools/tsconfig.json index 02095e7e3..e6575971a 100644 --- a/tools/tsconfig.json +++ b/tools/tsconfig.json @@ -11,7 +11,7 @@ "build.ts", "watch.ts", "update-origin.ts", - "translate.ts", + "translator", "lint.ts" ] } diff --git a/yarn.lock b/yarn.lock index 840778745..c8c5e626b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -33,125 +33,130 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.8.tgz#58a4dbbcad7eb1d48930524a3fd93d93e9084c6f" integrity sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w== -"@esbuild/aix-ppc64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" - integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== - -"@esbuild/android-arm64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" - integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== - -"@esbuild/android-arm@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" - integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== - -"@esbuild/android-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" - integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== - -"@esbuild/darwin-arm64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" - integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== - -"@esbuild/darwin-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" - integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== - -"@esbuild/freebsd-arm64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" - integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== - -"@esbuild/freebsd-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" - integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== - -"@esbuild/linux-arm64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" - integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== - -"@esbuild/linux-arm@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" - integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== - -"@esbuild/linux-ia32@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" - integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== - -"@esbuild/linux-loong64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" - integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== - -"@esbuild/linux-mips64el@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" - integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== - -"@esbuild/linux-ppc64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" - integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== - -"@esbuild/linux-riscv64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" - integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== - -"@esbuild/linux-s390x@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" - integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== - -"@esbuild/linux-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" - integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== - -"@esbuild/netbsd-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" - integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== - -"@esbuild/openbsd-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" - integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== - -"@esbuild/sunos-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" - integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== - -"@esbuild/win32-arm64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" - integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== - -"@esbuild/win32-ia32@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" - integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== - -"@esbuild/win32-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" - integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== - -"@google/generative-ai@0.14.1": - version "0.14.1" - resolved "https://registry.yarnpkg.com/@google/generative-ai/-/generative-ai-0.14.1.tgz#a9dcdf0b929fb0fa8c072007d6461c1c3cfe1175" - integrity sha512-pevEyZCb0Oc+dYNlSberW8oZBm4ofeTD5wN01TowQMhTwdAbGAnJMtQzoklh6Blq2AKsx8Ox6FWa44KioZLZiA== +"@esbuild/aix-ppc64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz#51299374de171dbd80bb7d838e1cfce9af36f353" + integrity sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ== + +"@esbuild/android-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz#58565291a1fe548638adb9c584237449e5e14018" + integrity sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw== + +"@esbuild/android-arm@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.23.1.tgz#5eb8c652d4c82a2421e3395b808e6d9c42c862ee" + integrity sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ== + +"@esbuild/android-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.23.1.tgz#ae19d665d2f06f0f48a6ac9a224b3f672e65d517" + integrity sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg== + +"@esbuild/darwin-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz#05b17f91a87e557b468a9c75e9d85ab10c121b16" + integrity sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q== + +"@esbuild/darwin-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz#c58353b982f4e04f0d022284b8ba2733f5ff0931" + integrity sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw== + +"@esbuild/freebsd-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz#f9220dc65f80f03635e1ef96cfad5da1f446f3bc" + integrity sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA== + +"@esbuild/freebsd-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz#69bd8511fa013b59f0226d1609ac43f7ce489730" + integrity sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g== + +"@esbuild/linux-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz#8050af6d51ddb388c75653ef9871f5ccd8f12383" + integrity sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g== + +"@esbuild/linux-arm@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz#ecaabd1c23b701070484990db9a82f382f99e771" + integrity sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ== + +"@esbuild/linux-ia32@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz#3ed2273214178109741c09bd0687098a0243b333" + integrity sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ== + +"@esbuild/linux-loong64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz#a0fdf440b5485c81b0fbb316b08933d217f5d3ac" + integrity sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw== + +"@esbuild/linux-mips64el@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz#e11a2806346db8375b18f5e104c5a9d4e81807f6" + integrity sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q== + +"@esbuild/linux-ppc64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz#06a2744c5eaf562b1a90937855b4d6cf7c75ec96" + integrity sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw== + +"@esbuild/linux-riscv64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz#65b46a2892fc0d1af4ba342af3fe0fa4a8fe08e7" + integrity sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA== + +"@esbuild/linux-s390x@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz#e71ea18c70c3f604e241d16e4e5ab193a9785d6f" + integrity sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw== + +"@esbuild/linux-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz#d47f97391e80690d4dfe811a2e7d6927ad9eed24" + integrity sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ== + +"@esbuild/netbsd-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz#44e743c9778d57a8ace4b72f3c6b839a3b74a653" + integrity sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA== + +"@esbuild/openbsd-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz#05c5a1faf67b9881834758c69f3e51b7dee015d7" + integrity sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q== + +"@esbuild/openbsd-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz#2e58ae511bacf67d19f9f2dcd9e8c5a93f00c273" + integrity sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA== + +"@esbuild/sunos-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz#adb022b959d18d3389ac70769cef5a03d3abd403" + integrity sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA== + +"@esbuild/win32-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz#84906f50c212b72ec360f48461d43202f4c8b9a2" + integrity sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A== + +"@esbuild/win32-ia32@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz#5e3eacc515820ff729e90d0cb463183128e82fac" + integrity sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ== + +"@esbuild/win32-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz#81fd50d11e2c32b2d6241470e3185b70c7b30699" + integrity sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg== + +"@google/generative-ai@0.21.0": + version "0.21.0" + resolved "https://registry.yarnpkg.com/@google/generative-ai/-/generative-ai-0.21.0.tgz#a5011aab9e6082e706937b26ef23445933fa0d15" + integrity sha512-7XhUbtnlkSEZK15kN3t+tzIMxsbKm/dSkKBFalj+20NvPKe1kBY7mR2P7vuijEn+f06z5+A8bVGKO0v39cr6Wg== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -977,34 +982,35 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -esbuild@~0.21.5: - version "0.21.5" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" - integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== +esbuild@~0.23.0: + version "0.23.1" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.23.1.tgz#40fdc3f9265ec0beae6f59824ade1bd3d3d2dab8" + integrity sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg== optionalDependencies: - "@esbuild/aix-ppc64" "0.21.5" - "@esbuild/android-arm" "0.21.5" - "@esbuild/android-arm64" "0.21.5" - "@esbuild/android-x64" "0.21.5" - "@esbuild/darwin-arm64" "0.21.5" - "@esbuild/darwin-x64" "0.21.5" - "@esbuild/freebsd-arm64" "0.21.5" - "@esbuild/freebsd-x64" "0.21.5" - "@esbuild/linux-arm" "0.21.5" - "@esbuild/linux-arm64" "0.21.5" - "@esbuild/linux-ia32" "0.21.5" - "@esbuild/linux-loong64" "0.21.5" - "@esbuild/linux-mips64el" "0.21.5" - "@esbuild/linux-ppc64" "0.21.5" - "@esbuild/linux-riscv64" "0.21.5" - "@esbuild/linux-s390x" "0.21.5" - "@esbuild/linux-x64" "0.21.5" - "@esbuild/netbsd-x64" "0.21.5" - "@esbuild/openbsd-x64" "0.21.5" - "@esbuild/sunos-x64" "0.21.5" - "@esbuild/win32-arm64" "0.21.5" - "@esbuild/win32-ia32" "0.21.5" - "@esbuild/win32-x64" "0.21.5" + "@esbuild/aix-ppc64" "0.23.1" + "@esbuild/android-arm" "0.23.1" + "@esbuild/android-arm64" "0.23.1" + "@esbuild/android-x64" "0.23.1" + "@esbuild/darwin-arm64" "0.23.1" + "@esbuild/darwin-x64" "0.23.1" + "@esbuild/freebsd-arm64" "0.23.1" + "@esbuild/freebsd-x64" "0.23.1" + "@esbuild/linux-arm" "0.23.1" + "@esbuild/linux-arm64" "0.23.1" + "@esbuild/linux-ia32" "0.23.1" + "@esbuild/linux-loong64" "0.23.1" + "@esbuild/linux-mips64el" "0.23.1" + "@esbuild/linux-ppc64" "0.23.1" + "@esbuild/linux-riscv64" "0.23.1" + "@esbuild/linux-s390x" "0.23.1" + "@esbuild/linux-x64" "0.23.1" + "@esbuild/netbsd-x64" "0.23.1" + "@esbuild/openbsd-arm64" "0.23.1" + "@esbuild/openbsd-x64" "0.23.1" + "@esbuild/sunos-x64" "0.23.1" + "@esbuild/win32-arm64" "0.23.1" + "@esbuild/win32-ia32" "0.23.1" + "@esbuild/win32-x64" "0.23.1" escape-string-regexp@^2.0.0: version "2.0.0" @@ -3077,12 +3083,12 @@ tslib@^2.1.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== -tsx@^4.16.2: - version "4.16.2" - resolved "https://registry.yarnpkg.com/tsx/-/tsx-4.16.2.tgz#8722be119ae226ef0b4c6210d5ee90f3ba823f19" - integrity sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ== +tsx@4.19.2: + version "4.19.2" + resolved "https://registry.yarnpkg.com/tsx/-/tsx-4.19.2.tgz#2d7814783440e0ae42354d0417d9c2989a2ae92c" + integrity sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g== dependencies: - esbuild "~0.21.5" + esbuild "~0.23.0" get-tsconfig "^4.7.5" optionalDependencies: fsevents "~2.3.3"