diff --git a/messages/ain-Kana.json b/messages/ain-Kana.json index cba5b52..465c5c9 100644 --- a/messages/ain-Kana.json +++ b/messages/ain-Kana.json @@ -1,83 +1,123 @@ { "app": { "Home": { - "title": "トゥンチ  アイヌイタㇰ オㇿ ウン トゥㇷ゚テ エアㇱカイ アエイワンケㇷ゚", - "description": "タン サイッ アナㇰネ アイヌイタㇰ オㇿ ワ シサㇺイタㇰ アヌイェ エアㇱカイ アエイワンケㇷ゚ ネ ルウェ ネ。" + "title": "トゥンチ  アイヌ イタㇰ オㇿ ウン トゥㇷ゚テ エアㇱカイ アエイワンケㇷ゚", + "description": "タン サイッ アナㇰネ アイヌ イタㇰ オㇿ ワ シサㇺ イタㇰ アヌイェ エアㇱカイ アエイワンケㇷ゚ ネ ルウェ ネ。" }, "AboutPage": { "title": "タンペ ヘマンタ アン?", - "description": "タン サイッ アナㇰネ アイヌイタㇰ オㇿ ワ シサㇺイタㇰ アヌイェ エアㇱカイ アエイワンケㇷ゚ ネ ルウェ ネ。" + "description": "タン サイッ アナㇰネ アイヌ イタㇰ オㇿ ワ シサㇺ イタㇰ アヌイェ エアㇱカイ アエイワンケㇷ゚ ネ ルウェ ネ。" } }, "components": { "Banner": { "about": "タンペ ヘマンタ アン?" }, + "ContentInfo": { + "title": "タン サイッ カㇻ クㇽ オルㇱペ" + }, "Composer": { - "source": "イヌイェ イタㇰ", - "recognize": "ハウェ アニ イヌイェ", - "play": "ヌ", - "paste": "コトゥッカ", - "target": "インカㇻ イタㇰ", - "share": "ウココㇿ", - "copy": "コピ", - "translate": "トゥㇷ゚テ", + "wip": "ナア チカㇻ コㇿ オカアㇱ ホントㇺ ネ ルウェ ネ。", "copied": "コピ エキ ワ オケレ", - "alternativeTranslations": "モㇱマ イタㇰ", - "translation": { - "empty": "チトゥㇷ゚テㇷ゚", - "loading": "アトゥㇷ゚テ コㇿ アナン…" - }, - "text": "エトゥㇷ゚テ ルスイ イタㇰ", - "char_max": "{current} モンチ オㇿ タ {current} モンチ エエイワンケ ワ エアン。", "translateForm": "イタㇰトゥㇷ゚テ フォム", - "translationResult": "アトゥㇷ゚テ イタㇰ", - "wip": "ナア チカㇻ コㇿ オカアㇱ ホントㇺ ネ ルウェ ネ。", - "advanced_settings": "イポㇿセ & イタㇰポ", - "PronounSelector": { - "title": "イタㇰポ", - "description": "アイヌイタㇰ オㇿ タ トゥ シンナ イタㇰ アエイワンケ ルウェ ネ: ユカㇻ オㇿ タ アエイワンケ イタㇰ、 ヤヤン ヒ タ アエイワンケ イタㇰ。 ヒ クス、 イナン イタㇰ ピㇼカ ヤ カ エヌㇺケ エアㇱカイ ルウェ ネ。", - "first": "ヤヤン イタㇰ", - "first_description": "ヤヤン ヒ タ アイェ イタㇰ", - "fourth": "アトㇺテ イタㇰ", - "fourth_description": "ユカㇻ オㇿ タ アイェ イタㇰ" + "ComposerInput": { + "source": "アニ エイヌイェ イタㇰ", + "text": "エトゥㇷ゚テ ルスイ イタㇰ", + "recognize": "ハウェ アニ イヌイェ", + "play": "ヌ", + "paste": "コトゥッカ", + "translate": "トゥㇷ゚テ", + "advancedSettings": "イポㇿセ & イタㇰポ", + "placeholder": "イタㇰ ヌイェ ヤン" + }, + "ComposerOutput": { + "target": "アニ エインカㇻ イタㇰ", + "share": "ウココㇿ", + "copy": "コピ", + "play": "ヌ", + "translationResult": "アトゥㇷ゚テ イタㇰ", + "untranslated": "イタㇰ ナア ソモ アトゥㇷ゚テ" }, - "close": "アシ", - "DialectSelector": { - "title": "イポㇿセ", - "description": "アイヌイタㇰ オㇿ タ ヒヨチュンコ サㇰ クス、 ウサ モシㇼ オㇿ タ シンナ イタㇰ アエイワンケ ワ オカ ルウェ ネ。 モシㇼ エヌㇺケ ワ ネ モシㇼ オㇿ タ アエイワンケ ワ オカ イタㇰ エカㇻ エアㇱカイ ルウェ ネ。", - "experimental": "ナア チカㇻ ワ オカアㇱ。", - "saru": "サㇻ", - "chitose": "シコッ", - "mukawa": "ムカ", - "horobetsu": "ポロペッ", - "shizunai": "シピチャリ", - "tokachi": "トカㇷ゚チ", - "kushiro": "クシㇼ", - "samani": "サマニ", - "bihoro": "ペポロ", - "ishikari": "イㇱカㇻ" + "CharCount": { + "charMax": "{current} モンチ オㇿ タ {current} モンチ エエイワンケ ワ エアン。" + }, + "Translation": { + "empty": "チトゥㇷ゚テㇷ゚", + "loading": "アトゥㇷ゚テ コㇿ アナン…" }, "Disclaimer": { "title": "ヤイトゥパレ ヤン", - "disclaimer": "シンナ イタㇰ、 ウェン イタㇰ アカㇻ ヒ カ オカアン ナンコㇿ。 クス、 タネ オカ アイヌイタㇰ エランペウテㇰ ウタㇻ アナㇰネ イテキ オピッタ エイソコㇿ ヤン。 アイヌイタㇰ ピㇼカノ イェ クㇽ エチコピシ ヤㇰ ピㇼカ ナンコㇿ。" + "disclaimer": "シンナ イタㇰ、 ウェン イタㇰ アカㇻ ヒ カ オカアン ナンコㇿ。 クス、 タネ オカ アイヌ イタㇰ エランペウテㇰ ウタㇻ アナㇰネ イテキ オピッタ エイソコㇿ ヤン。 アイヌ イタㇰ ピㇼカノ イェ クㇽ エチコピシ ヤㇰ ピㇼカ ナンコㇿ。" }, - "not_translated": "ナア イタㇰ ソモ アトゥㇷ゚テ" - }, - "ExampleSentences": { - "exampleSentences": "ネ イタㇰ エイワンケ ワ オカ オルㇱペ", - "source": "モトホ:", - "dialect": "イポㇿセ" - }, - "LanguageSelector": { - "ainu": "アイヌイタㇰ", - "japanese": "シサㇺイタㇰ" - }, - "AlternativeTranslations": { - "description": "モㇱマ アナㇰネ、 エネ イタㇰポ カ オカ ヒ:" + "AdvancedSettingsDialog": { + "PronounSelector": { + "title": "イタㇰポ", + "description": "アイヌ イタㇰ オㇿ タ トゥ シンナ イタㇰ アエイワンケ ルウェ ネ: ユカㇻ オㇿ タ アエイワンケ イタㇰ、 ヤヤン ヒ タ アエイワンケ イタㇰ。 ヒ クス、 イナン イタㇰ ピㇼカ ヤ カ エヌㇺケ エアㇱカイ ルウェ ネ。", + "first": "ヤヤン イタㇰ", + "firstDescription": "ヤヤン ヒ タ アイェ イタㇰ", + "fourth": "アトㇺテ イタㇰ", + "fourthDescription": "ユカㇻ オㇿ タ アイェ イタㇰ" + }, + "AdvancedSettingsDialogContent": { + "title": "イポㇿセ & イタㇰポ", + "description": "イポㇿセ ネワ イタㇰポ ウン セッテイ エヌㇺケ ワ、 ナア ピㇼカ イタㇰ エヌイェ エアㇱカイ。", + "close": "アシ" + }, + "DialectSelector": { + "title": "イポㇿセ", + "description": "アイヌ イタㇰ オㇿ タ ヒヨチュンコ サㇰ クス、 ウサ モシㇼ オㇿ タ シンナ イタㇰ アエイワンケ ワ オカ ルウェ ネ。 モシㇼ エヌㇺケ ワ ネ モシㇼ オㇿ タ アエイワンケ ワ オカ イタㇰ エカㇻ エアㇱカイ ルウェ ネ。", + "experimental": "ナア チカㇻ ワ オカアㇱ。", + "saru": "サㇻ", + "chitose": "シコッ", + "mukawa": "ムカ", + "horobetsu": "ポロペッ", + "shizunai": "シピチャリ", + "tokachi": "トカㇷ゚チ", + "kushiro": "クシㇼ", + "samani": "サマニ", + "bihoro": "ペポロ", + "ishikari": "イㇱカㇻ" + } + }, + "ExampleSentences": { + "ExampleSentencesWrapper": { + "title": "ネ イタㇰ エイワンケ ワ オカ オルㇱペ" + }, + "ExampleSentencesError": { + "description": "テータ取得中にエラーか発生しました。時間をおいて再度お試しくたさい。" + } + }, + "LanguageSelector": { + "ainu": "アイヌ イタㇰ", + "japanese": "シサㇺ イタㇰ" + }, + "AlternativeTranslations": { + "AlternativeTranslationsWrapper": { + "title": "モㇱマ イタㇰ" + }, + "AlternativeTranslationsError": { + "description": "テータ取得中にエラーか発生しました。時間をおいて再度お試しくたさい。" + }, + "AlternativeTranslationsContent": { + "description": "モㇱマ アナㇰネ、 エネ イタㇰポ カ オカ ヒ:" + } + } }, - "ContentInfo": { - "title": "タン サイッ カㇻ クㇽ オルㇱペ" + "Entry": { + "Entry": { + "source": "モトホ: ", + "author": "ヌイェ クㇽ: ", + "dialect": "イポㇿセ: " + }, + "EntryDetailsDialog": { + "title": "ナア カンピㇱ オルㇱペ", + "description": "この資料の詳細情報てす。一部不正確な情報か含まれる可能性かあります。", + "book": "モトホ レ", + "entryTitle": "カンピ レ", + "author": "ヌイェ クㇽ", + "dialect": "イポㇿセ", + "url": "ウㇽl" + } } } } diff --git a/messages/ain-Latn.json b/messages/ain-Latn.json index d474192..a664085 100644 --- a/messages/ain-Latn.json +++ b/messages/ain-Latn.json @@ -1,83 +1,123 @@ { "app": { "Home": { - "title": "tunci - Aynuitak or un tupte easkay aeywankep", - "description": "tan sait anakne Aynuitak or wa Sisam’itak a=nuye easkay aeywankep ne ruwe ne." + "title": "tunci - Aynu itak or un tupte easkay aeywankep", + "description": "tan sait anakne Aynu itak or wa Sisam itak a=nuye easkay aeywankep ne ruwe ne." }, "AboutPage": { "title": "tanpe hemanta an?", - "description": "tan sait anakne Aynuitak or wa Sisam’itak a=nuye easkay aeywankep ne ruwe ne." + "description": "tan sait anakne Aynu itak or wa Sisam itak a=nuye easkay aeywankep ne ruwe ne." } }, "components": { "Banner": { "about": "tanpe hemanta an?" }, + "ContentInfo": { + "title": "tan sait kar kur oruspe" + }, "Composer": { - "source": "inuye itak", - "recognize": "hawe ani inuye", - "play": "nu", - "paste": "kotukka", - "target": "inkar itak", - "share": "ukokor", - "copy": "KOPI", - "translate": "tupte", + "wip": "naa ci=kar kor oka=as hontom ne ruwe ne.", "copied": "KOPI e=ki wa okere", - "alternativeTranslations": "mosma itak", - "translation": { - "empty": "cituptep", - "loading": "a=tupte kor an=an..." + "translateForm": "itaktupte FOMU", + "ComposerInput": { + "source": "ani e=inuye itak", + "text": "e=tupte rusuy itak", + "recognize": "hawe ani inuye", + "play": "nu", + "paste": "kotukka", + "translate": "tupte", + "advancedSettings": "iporse & itakpo", + "placeholder": "itak nuye yan" }, - "text": "e=tupte rusuy itak", - "char_max": "{max} monci or ta {current} monci e=eywanke wa e=an.", - "translateForm": "itaktupte fomu", - "translationResult": "a=tupte itak", - "wip": "naa ci=kar kor oka=as hontom ne ruwe ne.", - "advanced_settings": "iporse & itakpo", - "PronounSelector": { - "title": "itakpo", - "description": "Aynuitak or ta tu sinna itak a=eywanke ruwe ne: yukar or ta a=eywanke itak, yayan hi ta a=eywanke itak. hi kusu, inan itak pirka ya ka e=numke easkay ruwe ne.", - "first": "yayan itak", - "first_description": "yayan hi ta a=ye itak", - "fourth": "a=tomte itak", - "fourth_description": "yukar or ta a=ye itak" + "ComposerOutput": { + "target": "ani e=inkar itak", + "share": "ukokor", + "copy": "KOPI", + "play": "nu", + "translationResult": "a=tupte itak", + "untranslated": "itak naa somo a=tupte" + }, + "CharCount": { + "charMax": "{max} monci or ta {current} monci e=eywanke wa e=an." }, - "close": "asi", - "DialectSelector": { - "title": "iporse", - "description": "Aynuitak or ta hiyocunko sak kusu, usa mosir or ta sinna itak a=eywanke wa oka ruwe ne. mosir e=numke wa ne mosir or ta a=eywanke wa oka itak e=kar easkay ruwe ne.", - "experimental": "naa ci=kar wa oka=as.", - "saru": "Sar", - "chitose": "Sikot", - "mukawa": "Muka", - "horobetsu": "Poropet", - "shizunai": "Sipicari", - "tokachi": "Tokapci", - "kushiro": "Kusir", - "samani": "Samani", - "bihoro": "Peporo", - "ishikari": "Iskar" + "Translation": { + "empty": "cituptep", + "loading": "a=tupte kor an=an..." }, "Disclaimer": { "title": "yaytupare yan", - "disclaimer": "sinna itak, wen itak a=kar hi ka oka=an nankor. kusu, tane oka Aynuitak erampewtek utar anakne iteki opitta eysokor yan. Aynuitak pirkano ye kur eci=kopisi yak pirka nankor." + "disclaimer": "sinna itak, wen itak a=kar hi ka oka=an nankor. kusu, tane oka Aynu itak erampewtek utar anakne iteki opitta eysokor yan. Aynu itak pirkano ye kur eci=kopisi yak pirka nankor." }, - "not_translated": "naa itak somo a=tupte" - }, - "ExampleSentences": { - "exampleSentences": "ne itak eywanke wa oka oruspe", - "source": "motoho:", - "dialect": "iporse" - }, - "LanguageSelector": { - "ainu": "Aynuitak", - "japanese": "Sisam’itak" - }, - "AlternativeTranslations": { - "description": "mosma anakne, ene itakpo ka oka hi:" + "AdvancedSettingsDialog": { + "PronounSelector": { + "title": "itakpo", + "description": "Aynu itak or ta tu sinna itak a=eywanke ruwe ne: yukar or ta a=eywanke itak, yayan hi ta a=eywanke itak. hi kusu, inan itak pirka ya ka e=numke easkay ruwe ne.", + "first": "yayan itak", + "firstDescription": "yayan hi ta a=ye itak", + "fourth": "a=tomte itak", + "fourthDescription": "yukar or ta a=ye itak" + }, + "AdvancedSettingsDialogContent": { + "title": "iporse & itakpo", + "description": "iporse newa itakpo un SETTEY e=numke wa, naa pirka itak e=nuye easkay.", + "close": "asi" + }, + "DialectSelector": { + "title": "iporse", + "description": "Aynu itak or ta hiyocunko sak kusu, usa mosir or ta sinna itak a=eywanke wa oka ruwe ne. mosir e=numke wa ne mosir or ta a=eywanke wa oka itak e=kar easkay ruwe ne.", + "experimental": "naa ci=kar wa oka=as.", + "saru": "Sar", + "chitose": "Sikot", + "mukawa": "Muka", + "horobetsu": "Poropet", + "shizunai": "Sipicari", + "tokachi": "Tokapci", + "kushiro": "Kusir", + "samani": "Samani", + "bihoro": "Peporo", + "ishikari": "Iskar" + } + }, + "ExampleSentences": { + "ExampleSentencesWrapper": { + "title": "ne itak eywanke wa oka oruspe" + }, + "ExampleSentencesError": { + "description": "データ取得中にエラーが発生しました。時間をおいて再度お試しください。" + } + }, + "LanguageSelector": { + "ainu": "Aynu itak", + "japanese": "Sisam itak" + }, + "AlternativeTranslations": { + "AlternativeTranslationsWrapper": { + "title": "mosma itak" + }, + "AlternativeTranslationsError": { + "description": "データ取得中にエラーが発生しました。時間をおいて再度お試しください。" + }, + "AlternativeTranslationsContent": { + "description": "mosma anakne, ene itakpo ka oka hi:" + } + } }, - "ContentInfo": { - "title": "tan sait kar kur oruspe" + "Entry": { + "Entry": { + "source": "motoho: ", + "author": "nuye kur: ", + "dialect": "iporse: " + }, + "EntryDetailsDialog": { + "title": "naa kampis oruspe", + "description": "この資料の詳細情報です。一部不正確な情報が含まれる可能性があります。", + "book": "motoho re", + "entryTitle": "kampi re", + "author": "nuye kur", + "dialect": "iporse", + "url": "URL" + } } } } diff --git a/messages/ja.json b/messages/ja.json index 71e6b9f..0a983df 100644 --- a/messages/ja.json +++ b/messages/ja.json @@ -17,67 +17,107 @@ "title": "運営者情報" }, "Composer": { - "source": "入力する言語", - "recognize": "音声入力", - "play": "読み上げる", - "paste": "貼り付け", - "target": "翻訳する言語", - "share": "共有", - "copy": "コピー", - "translate": "翻訳", + "wip": "この機能は現在準備中です。", "copied": "コピーしました", - "alternativeTranslations": "言い換え表現", - "translation": { - "empty": "翻訳", - "loading": "翻訳中…" - }, - "text": "翻訳したい文章", - "char_max": "{max}文字中、{current}文字を入力中。", "translateForm": "翻訳フォーム", - "translationResult": "翻訳結果", - "wip": "この機能は現在準備中です。", - "advanced_settings": "語彙と方言", - "PronounSelector": { - "title": "言葉づかい", - "description": "アイヌ語は、普段の会話をするときと、物語を語るときで使う言葉が異なります。どちらの言葉を使うかを選択することができます。", - "first": "日常語", - "first_description": "会話の言葉で翻訳します。", - "fourth": "雅語", - "fourth_description": "物語の言葉で翻訳します。" + "ComposerInput": { + "source": "入力する言語", + "text": "翻訳したい文章", + "recognize": "音声入力", + "play": "読み上げる", + "paste": "貼り付け", + "translate": "翻訳", + "advancedSettings": "語彙と方言", + "placeholder": "文章を入力" + }, + "ComposerOutput": { + "target": "翻訳する言語", + "share": "共有", + "copy": "コピー", + "play": "読み上げる", + "translationResult": "翻訳結果", + "untranslated": "まだ翻訳していません" }, - "close": "閉じる", - "DialectSelector": { - "title": "方言", - "description": "アイヌ語には標準語がなく、各地域ごとに異なった表現を使っています。地域を選択して、その地域の方言で文章を作成することができます。", - "experimental": "これは実験的な機能です。", - "saru": "沙流", - "chitose": "千歳", - "mukawa": "鵡川", - "horobetsu": "幌別", - "shizunai": "静内", - "tokachi": "十勝", - "kushiro": "釧路", - "samani": "様似", - "bihoro": "美幌", - "ishikari": "石狩" + "CharCount": { + "charMax": "{max}文字中、{current}文字を入力中。" + }, + "Translation": { + "empty": "翻訳", + "loading": "翻訳中…" }, "Disclaimer": { "title": "注意事項", "disclaimer": "機械翻訳を利用しているため、誤った文章を生成することがあります。初学者の方は、かならず講師や上級者に確認してください。" }, - "not_translated": "まだ翻訳していません" - }, - "ExampleSentences": { - "exampleSentences": "用例", - "source": "出典:", - "dialect": "方言" - }, - "LanguageSelector": { - "ainu": "アイヌ語", - "japanese": "日本語" + "AdvancedSettingsDialog": { + "PronounSelector": { + "title": "言葉づかい", + "description": "アイヌ語は、普段の会話をするときと、物語を語るときで使う言葉が異なります。どちらの言葉を使うかを選択することができます。", + "first": "日常語", + "firstDescription": "会話の言葉で翻訳します。", + "fourth": "雅語", + "fourthDescription": "物語の言葉で翻訳します。" + }, + "AdvancedSettingsDialogContent": { + "title": "語彙と方言", + "description": "語彙や文法の設定を変更して、より自然な文章を生成できます。", + "close": "閉じる" + }, + "DialectSelector": { + "title": "方言", + "description": "アイヌ語には標準語がなく、各地域ごとに異なった表現を使っています。地域を選択して、その地域の方言で文章を作成することができます。", + "experimental": "これは実験的な機能です。", + "saru": "沙流", + "chitose": "千歳", + "mukawa": "鵡川", + "horobetsu": "幌別", + "shizunai": "静内", + "tokachi": "十勝", + "kushiro": "釧路", + "samani": "様似", + "bihoro": "美幌", + "ishikari": "石狩" + } + }, + "ExampleSentences": { + "ExampleSentencesWrapper": { + "title": "用例" + }, + "ExampleSentencesError": { + "description": "データ取得中にエラーが発生しました。時間をおいて再度お試しください。" + } + }, + "LanguageSelector": { + "ainu": "アイヌ語", + "japanese": "日本語" + }, + "AlternativeTranslations": { + "AlternativeTranslationsWrapper": { + "title": "言い換え表現" + }, + "AlternativeTranslationsError": { + "description": "データ取得中にエラーが発生しました。時間をおいて再度お試しください。" + }, + "AlternativeTranslationsContent": { + "description": "この他にも、次のような言い換えができます" + } + } }, - "AlternativeTranslations": { - "description": "この他にも、次のような言い換えができます" + "Entry": { + "Entry": { + "source": "出典:", + "author": "著者:", + "dialect": "方言:" + }, + "EntryDetailsDialog": { + "title": "詳細", + "description": "この資料の詳細情報です。一部不正確な情報が含まれる可能性があります。", + "book": "資料", + "entryTitle": "タイトル", + "author": "著者", + "dialect": "方言", + "url": "URL" + } } } } diff --git a/package-lock.json b/package-lock.json index cf919ae..27e8c1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,9 @@ "@mdx-js/react": "^3.1.0", "@next/mdx": "^14.2.5", "@next/third-parties": "^14.2.13", + "@radix-ui/react-collapsible": "^1.1.2", + "@radix-ui/react-icons": "^1.3.2", + "@radix-ui/themes": "^3.1.6", "@tailwindcss/typography": "^0.5.13", "@types/lodash-es": "^4.17.12", "@types/mdx": "^2.0.13", @@ -24,13 +27,13 @@ "mixpanel-browser": "^2.55.1", "next": "14.2.4", "next-intl": "^3.24.0", + "next-themes": "^0.4.4", "react": "^18", "react-dom": "^18", "react-error-boundary": "^4.1.2", "react-icons": "^5.3.0", "react-simple-maps": "^3.0.0", - "react-textarea-autosize": "^8.5.4", - "tailwind-variants": "^0.2.1" + "react-textarea-autosize": "^8.5.4" }, "devDependencies": { "@chromatic-com/storybook": "^1.6.1", @@ -55,10 +58,8 @@ "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-simple-import-sort": "^12.1.0", "eslint-plugin-storybook": "^0.8.0", - "postcss": "^8.4.47", "prettier": "^3.3.3", "storybook": "^8.4.1", - "tailwindcss": "^3.4.14", "tailwindcss-hero-patterns": "^0.1.2", "typescript": "^5.6.3" } @@ -240,6 +241,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "peer": true, "engines": { "node": ">=10" }, @@ -2807,6 +2809,40 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz", + "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==", + "dependencies": { + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz", + "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", + "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", + "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==" + }, "node_modules/@formatjs/ecma402-abstract": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.1.tgz", @@ -3843,120 +3879,1335 @@ "node": ">= 8" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.15.tgz", + "integrity": "sha512-LFWllMA55pzB9D34w/wXUCf8+c+IYKuJDgxiZ3qMhl64KRMBHYM1I3VdGaD2BV5FNPV2/S2596bppxHbv2ZydQ==", + "dev": true, + "dependencies": { + "ansi-html": "^0.0.9", + "core-js-pure": "^3.23.3", + "error-stack-parser": "^2.0.6", + "html-entities": "^2.1.0", + "loader-utils": "^2.0.4", + "schema-utils": "^4.2.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "@types/webpack": "4.x || 5.x", + "react-refresh": ">=0.10.0 <1.0.0", + "sockjs-client": "^1.4.0", + "type-fest": ">=0.17.0 <5.0.0", + "webpack": ">=4.43.0 <6.0.0", + "webpack-dev-server": "3.x || 4.x || 5.x", + "webpack-hot-middleware": "2.x", + "webpack-plugin-serve": "0.x || 1.x" + }, + "peerDependenciesMeta": { + "@types/webpack": { + "optional": true + }, + "sockjs-client": { + "optional": true + }, + "type-fest": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + }, + "webpack-hot-middleware": { + "optional": true + }, + "webpack-plugin-serve": { + "optional": true + } + } + }, + "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@radix-ui/colors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/colors/-/colors-3.0.0.tgz", + "integrity": "sha512-FUOsGBkHrYJwCSEtWRCIfQbZG7q1e6DgxCIOe1SUQzDe/7rXXeA47s8yCn6fuTNQAj1Zq4oTFi9Yjp3wzElcxg==" + }, + "node_modules/@radix-ui/number": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.0.tgz", + "integrity": "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", + "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==" + }, + "node_modules/@radix-ui/react-accessible-icon": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accessible-icon/-/react-accessible-icon-1.1.1.tgz", + "integrity": "sha512-DH8vuU7oqHt9RhO3V9Z1b8ek+bOl4+9VLsh0cgL6t7f2WhbuOChm3ft0EmCCsfd4ORi7Cs3II4aNcTXi+bh+wg==", + "dependencies": { + "@radix-ui/react-visually-hidden": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-alert-dialog": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.4.tgz", + "integrity": "sha512-A6Kh23qZDLy3PSU4bh2UJZznOrUdHImIXqF8YtUa6CN73f8EOO9XlXSCd9IHyPvIquTaa/kwaSWzZTtUvgXVGw==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dialog": "1.1.4", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-slot": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.1.tgz", + "integrity": "sha512-NaVpZfmv8SKeZbn4ijN2V3jlHA9ngBG16VnIIm22nUR0Yk8KUALyBxT3KYEUnNuch9sTE8UTsS3whzBgKOL30w==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-aspect-ratio": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.1.tgz", + "integrity": "sha512-kNU4FIpcFMBLkOUcgeIteH06/8JLBcYY6Le1iKenDGCYNYFX3TQqCZjzkOsz37h7r94/99GTb7YhEr98ZBJibw==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-avatar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.2.tgz", + "integrity": "sha512-GaC7bXQZ5VgZvVvsJ5mu/AEbjYLnhhkoidOboC50Z6FFlLA03wG2ianUoH+zgDQ31/9gCF59bE4+2bBgTyMiig==", + "dependencies": { + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.3.tgz", + "integrity": "sha512-HD7/ocp8f1B3e6OHygH0n7ZKjONkhciy1Nh0yuBgObqThc3oyx+vuMfFHKAknXRHHWVE9XvXStxJFyjUmB8PIw==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.2.tgz", + "integrity": "sha512-PliMB63vxz7vggcyq0IxNYk8vGDrLXVWw4+W4B8YnwI1s18x7YZYqlG9PLX7XxAJUi0g2DxP4XKJMFHh/iVh9A==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.1.tgz", + "integrity": "sha512-LwT3pSho9Dljg+wY2KN2mrrh6y3qELfftINERIzBUO9e0N+t0oMTyn3k9iv+ZqgrwGkRnLpNJrsMv9BZlt2yuA==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-slot": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", + "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", + "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context-menu": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.2.4.tgz", + "integrity": "sha512-ap4wdGwK52rJxGkwukU1NrnEodsUFQIooANKu+ey7d6raQ2biTcEf8za1zr0mgFHieevRTB2nK4dJeN8pTAZGQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-menu": "2.1.4", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.4.tgz", + "integrity": "sha512-Ur7EV1IwQGCyaAuyDRiOLA5JIUZxELJljF+MbM/2NC0BYwfuRrbpS30BiQBJrVruscgUkieKkqXYDOoByaxIoA==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-slot": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "^2.6.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.3.tgz", + "integrity": "sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-escape-keydown": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.4.tgz", + "integrity": "sha512-iXU1Ab5ecM+yEepGAWK8ZhMyKX4ubFdCNtol4sT9D0OVErG9PNElfx3TQhjw7n7BC5nFVz68/5//clWy+8TXzA==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-menu": "2.1.4", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz", + "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.1.tgz", + "integrity": "sha512-01omzJAYRxXdG2/he/+xy+c8a8gCydoQ1yOxnWNcRhrrBW5W+RQJ22EK1SaO8tb3WoUsuEw7mJjBozPzihDFjA==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.4.tgz", + "integrity": "sha512-QSUUnRA3PQ2UhvoCv3eYvMnCAgGQW+sTu86QPuNb+ZMi+ZENd6UWpiXbcWDQ4AEaKF9KKpCHBeaJz9Rw6lRlaQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-popper": "1.2.1", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-icons": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.2.tgz", + "integrity": "sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==", + "peerDependencies": { + "react": "^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.4.tgz", + "integrity": "sha512-BnOgVoL6YYdHAG6DtXONaR29Eq4nvbi8rutrV/xlr3RQCMMb3yqP85Qiw/3NReozrSW+4dfLkK+rc1hb4wPU/A==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.1", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-roving-focus": "1.1.1", + "@radix-ui/react-slot": "1.1.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "^2.6.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-navigation-menu": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.3.tgz", + "integrity": "sha512-IQWAsQ7dsLIYDrn0WqPU+cdM7MONTv9nqrLVYoie3BPiabSfUVDe6Fr+oEt0Cofsr9ONDcDe9xhmJbL1Uq1yKg==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.4.tgz", + "integrity": "sha512-aUACAkXx8LaFymDma+HQVji7WhvEhpFJ7+qPz17Nf4lLZqtreGOFRiNQWQmhzp7kEWg9cOyyQJpdIMUMPc/CPw==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.1", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-slot": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "^2.6.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.1.tgz", + "integrity": "sha512-3kn5Me69L+jv82EKRuQCXdYyf1DqHwD2U/sxoNgBGCB7K9TRc3bQamQ+5EPM9EvyPdli0W41sROd+ZU1dTCztw==", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz", + "integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", + "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", + "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", + "dependencies": { + "@radix-ui/react-slot": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-progress": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.1.tgz", + "integrity": "sha512-6diOawA84f/eMxFHcWut0aE1C2kyE9dOyCTQOMRR2C/qPiXz/X0SaiA/RLbapQaXUCmy0/hLMf9meSccD1N0pA==", + "dependencies": { + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-radio-group": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.2.2.tgz", + "integrity": "sha512-E0MLLGfOP0l8P/NxgVzfXJ8w3Ch8cdO6UDzJfDChu4EJDy+/WdO5LqpdY8PYnCErkmZH3gZhDL1K7kQ41fAHuQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-roving-focus": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.1.tgz", + "integrity": "sha512-QE1RoxPGJ/Nm8Qmk0PxP8ojmoaS67i0s7hVssS7KuI2FQoc/uzVlZsqKfQvxPE6D8hICCPHJ4D88zNhT3OOmkw==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.2.tgz", + "integrity": "sha512-EFI1N/S3YxZEW/lJ/H1jY3njlvTd8tBmgKEn4GHi51+aMm94i6NmAJstsm5cu3yJwYqYc93gpCPm21FeAbFk6g==", + "dependencies": { + "@radix-ui/number": "1.1.0", + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.4.tgz", + "integrity": "sha512-pOkb2u8KgO47j/h7AylCj7dJsm69BXcjkrvTqMptFqsE2i0p8lHkfgneXKjAgPzBMivnoMyt8o4KiV4wYzDdyQ==", + "dependencies": { + "@radix-ui/number": "1.1.0", + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.1", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-slot": "1.1.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "^2.6.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slider": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.2.2.tgz", + "integrity": "sha512-sNlU06ii1/ZcbHf8I9En54ZPW0Vil/yPVg4vQMcFNjrIx51jsHbFl1HYHQvCIWJSr1q0ZmA+iIs/ZTv8h7HHSA==", + "dependencies": { + "@radix-ui/number": "1.1.0", + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz", + "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.1.2.tgz", + "integrity": "sha512-zGukiWHjEdBCRyXvKR6iXAQG6qXm2esuAD6kDOi9Cn+1X6ev3ASo4+CsYaD6Fov9r/AQFekqnD/7+V0Cs6/98g==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.2.tgz", + "integrity": "sha512-9u/tQJMcC2aGq7KXpGivMm1mgq7oRJKXphDwdypPd/j21j/2znamPU8WkXgnhUaTrSFNIt8XhOyCAupg8/GbwQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-roving-focus": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.1.tgz", + "integrity": "sha512-i77tcgObYr743IonC1hrsnnPmszDRn8p+EGUsUt+5a/JFn28fxaM88Py6V2mc8J5kELMWishI0rLnuGLFD/nnQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle-group": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.1.tgz", + "integrity": "sha512-OgDLZEA30Ylyz8YSXvnGqIHtERqnUt1KUYTKdw/y8u7Ci6zGiJfXc02jahmcSNK3YcErqioj/9flWC9S1ihfwg==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-roving-focus": "1.1.1", + "@radix-ui/react-toggle": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.6.tgz", + "integrity": "sha512-TLB5D8QLExS1uDn7+wH/bjEmRurNMTzNrtq7IjaS4kjion9NtzsTGkvR5+i7yc9q01Pi2KMM2cN3f8UG4IvvXA==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.1", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-slot": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", + "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "@radix-ui/react-use-callback-ref": "1.1.0" }, - "engines": { - "node": ">= 8" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "optional": true, - "engines": { - "node": ">=14" + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", + "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, - "funding": { - "url": "https://opencollective.com/unts" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.15.tgz", - "integrity": "sha512-LFWllMA55pzB9D34w/wXUCf8+c+IYKuJDgxiZ3qMhl64KRMBHYM1I3VdGaD2BV5FNPV2/S2596bppxHbv2ZydQ==", - "dev": true, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", + "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", "dependencies": { - "ansi-html": "^0.0.9", - "core-js-pure": "^3.23.3", - "error-stack-parser": "^2.0.6", - "html-entities": "^2.1.0", - "loader-utils": "^2.0.4", - "schema-utils": "^4.2.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">= 10.13" + "@radix-ui/rect": "1.1.0" }, "peerDependencies": { - "@types/webpack": "4.x || 5.x", - "react-refresh": ">=0.10.0 <1.0.0", - "sockjs-client": "^1.4.0", - "type-fest": ">=0.17.0 <5.0.0", - "webpack": ">=4.43.0 <6.0.0", - "webpack-dev-server": "3.x || 4.x || 5.x", - "webpack-hot-middleware": "2.x", - "webpack-plugin-serve": "0.x || 1.x" + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { - "@types/webpack": { - "optional": true - }, - "sockjs-client": { - "optional": true - }, - "type-fest": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - }, - "webpack-hot-middleware": { - "optional": true - }, - "webpack-plugin-serve": { + "@types/react": { "optional": true } } }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" }, - "engines": { - "node": ">=6" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dev": true, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.1.tgz", + "integrity": "sha512-vVfA2IZ9q/J+gEamvj761Oq1FpWgCDaNOOIfbPVp2MVPLEomUr5+Vf7kJGwQ24YxZSlQVar7Bes8kyTo5Dshpg==", "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" + "@radix-ui/react-primitive": "2.0.1" }, - "engines": { - "node": ">=8.9.0" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" + "node_modules/@radix-ui/rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" + }, + "node_modules/@radix-ui/themes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/themes/-/themes-3.1.6.tgz", + "integrity": "sha512-4uaUK0E+3ZRURohKNqnzG8LciTJcpppuBbYxkp7miLyPiaXBwKTrEttdQpExsp/fP6J+ss+JHy5FJhU5lboQkg==", + "dependencies": { + "@radix-ui/colors": "^3.0.0", + "@radix-ui/primitive": "^1.1.0", + "@radix-ui/react-accessible-icon": "^1.1.0", + "@radix-ui/react-alert-dialog": "^1.1.2", + "@radix-ui/react-aspect-ratio": "^1.1.0", + "@radix-ui/react-avatar": "^1.1.1", + "@radix-ui/react-checkbox": "^1.1.2", + "@radix-ui/react-compose-refs": "^1.1.0", + "@radix-ui/react-context": "^1.1.1", + "@radix-ui/react-context-menu": "^2.2.2", + "@radix-ui/react-dialog": "^1.1.2", + "@radix-ui/react-direction": "^1.1.0", + "@radix-ui/react-dropdown-menu": "^2.1.2", + "@radix-ui/react-hover-card": "^1.1.2", + "@radix-ui/react-navigation-menu": "^1.2.1", + "@radix-ui/react-popover": "^1.1.2", + "@radix-ui/react-portal": "^1.1.2", + "@radix-ui/react-primitive": "^2.0.0", + "@radix-ui/react-progress": "^1.1.0", + "@radix-ui/react-radio-group": "^1.2.1", + "@radix-ui/react-roving-focus": "^1.1.0", + "@radix-ui/react-scroll-area": "^1.2.1", + "@radix-ui/react-select": "^2.1.2", + "@radix-ui/react-slider": "^1.2.1", + "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-switch": "^1.1.1", + "@radix-ui/react-tabs": "^1.1.1", + "@radix-ui/react-toggle-group": "^1.1.0", + "@radix-ui/react-tooltip": "^1.1.4", + "@radix-ui/react-use-callback-ref": "^1.1.0", + "@radix-ui/react-use-controllable-state": "^1.1.0", + "@radix-ui/react-visually-hidden": "^1.1.0", + "classnames": "^2.3.2", + "react-remove-scroll-bar": "^2.3.6" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, "node_modules/@rrweb/types": { @@ -5171,7 +6422,7 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", - "dev": true, + "devOptional": true, "dependencies": { "@types/react": "*" } @@ -6064,7 +7315,8 @@ "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "peer": true }, "node_modules/anymatch": { "version": "3.1.3", @@ -6081,7 +7333,8 @@ "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "peer": true }, "node_modules/argparse": { "version": "2.0.1", @@ -6089,6 +7342,17 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/aria-hidden": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/aria-query": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", @@ -7164,6 +8428,11 @@ "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", "dev": true }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + }, "node_modules/clean-css": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", @@ -7268,6 +8537,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "peer": true, "engines": { "node": ">= 6" } @@ -7844,6 +9114,11 @@ "node": ">=8" } }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, "node_modules/detective": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", @@ -7876,7 +9151,8 @@ "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "peer": true }, "node_modules/diffie-hellman": { "version": "5.0.3", @@ -7910,7 +9186,8 @@ "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "peer": true }, "node_modules/doctrine": { "version": "3.0.0", @@ -9507,6 +10784,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/get-symbol-description": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", @@ -10958,6 +12243,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "peer": true, "engines": { "node": ">=10" } @@ -12058,6 +13344,7 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "peer": true, "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -12170,6 +13457,15 @@ "node": ">= 0.6" } }, + "node_modules/next-themes": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.4.tgz", + "integrity": "sha512-LDQ2qIOJF0VnuVrrMSMLrWGjRMkq+0mpgl6e0juCLqdJ+oo8Q84JRWT6Wh11VDQKkMMe+dVzDKLWs5n87T+PkQ==", + "peerDependencies": { + "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" + } + }, "node_modules/next/node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", @@ -12332,6 +13628,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "peer": true, "engines": { "node": ">= 6" } @@ -12783,6 +14080,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -12791,6 +14089,7 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "peer": true, "engines": { "node": ">= 6" } @@ -13047,6 +14346,7 @@ "version": "15.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "peer": true, "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -13063,6 +14363,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "peer": true, "dependencies": { "camelcase-css": "^2.0.1" }, @@ -13091,6 +14392,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "lilconfig": "^3.0.0", "yaml": "^2.3.4" @@ -13115,6 +14417,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "peer": true, "engines": { "node": ">=14" }, @@ -13242,6 +14545,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "peer": true, "dependencies": { "postcss-selector-parser": "^6.0.11" }, @@ -13755,6 +15059,51 @@ "node": ">=0.10.0" } }, + "node_modules/react-remove-scroll": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.2.tgz", + "integrity": "sha512-KmONPx5fnlXYJQqC62Q+lwIeAk64ws/cUw6omIumRzMRPqgnYqhSSti99nbj0Ry13bv7dF+BKn7NB+OqkdZGTw==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-simple-maps": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/react-simple-maps/-/react-simple-maps-3.0.0.tgz", @@ -13771,6 +15120,27 @@ "react-dom": "^16.8.0 || 17.x || 18.x" } }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-textarea-autosize": { "version": "8.5.4", "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.4.tgz", @@ -13791,6 +15161,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "peer": true, "dependencies": { "pify": "^2.3.0" } @@ -15050,6 +16421,7 @@ "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", @@ -15106,34 +16478,11 @@ "url": "https://opencollective.com/unts" } }, - "node_modules/tailwind-merge": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.4.tgz", - "integrity": "sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/dcastil" - } - }, - "node_modules/tailwind-variants": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tailwind-variants/-/tailwind-variants-0.2.1.tgz", - "integrity": "sha512-2xmhAf4UIc3PijOUcJPA1LP4AbxhpcHuHM2C26xM0k81r0maAO6uoUSHl3APmvHZcY5cZCY/bYuJdfFa4eGoaw==", - "dependencies": { - "tailwind-merge": "^2.2.0" - }, - "engines": { - "node": ">=16.x", - "pnpm": ">=7.x" - }, - "peerDependencies": { - "tailwindcss": "*" - } - }, "node_modules/tailwindcss": { "version": "3.4.14", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", + "peer": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -15360,6 +16709,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "peer": true, "dependencies": { "any-promise": "^1.0.0" } @@ -15368,6 +16718,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "peer": true, "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -15496,7 +16847,8 @@ "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "peer": true }, "node_modules/ts-pnp": { "version": "1.2.0", @@ -15964,6 +17316,26 @@ "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", "dev": true }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/use-composed-ref": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz", @@ -16013,6 +17385,27 @@ } } }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", @@ -16472,6 +17865,7 @@ "version": "2.4.5", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "peer": true, "bin": { "yaml": "bin.mjs" }, diff --git a/package.json b/package.json index a355c73..26bffae 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,9 @@ "@mdx-js/react": "^3.1.0", "@next/mdx": "^14.2.5", "@next/third-parties": "^14.2.13", + "@radix-ui/react-collapsible": "^1.1.2", + "@radix-ui/react-icons": "^1.3.2", + "@radix-ui/themes": "^3.1.6", "@tailwindcss/typography": "^0.5.13", "@types/lodash-es": "^4.17.12", "@types/mdx": "^2.0.13", @@ -27,13 +30,13 @@ "mixpanel-browser": "^2.55.1", "next": "14.2.4", "next-intl": "^3.24.0", + "next-themes": "^0.4.4", "react": "^18", "react-dom": "^18", "react-error-boundary": "^4.1.2", "react-icons": "^5.3.0", "react-simple-maps": "^3.0.0", - "react-textarea-autosize": "^8.5.4", - "tailwind-variants": "^0.2.1" + "react-textarea-autosize": "^8.5.4" }, "devDependencies": { "@chromatic-com/storybook": "^1.6.1", @@ -58,10 +61,8 @@ "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-simple-import-sort": "^12.1.0", "eslint-plugin-storybook": "^0.8.0", - "postcss": "^8.4.47", "prettier": "^3.3.3", "storybook": "^8.4.1", - "tailwindcss": "^3.4.14", "tailwindcss-hero-patterns": "^0.1.2", "typescript": "^5.6.3" } diff --git a/postcss.config.mjs b/postcss.config.mjs deleted file mode 100644 index 1a69fd2..0000000 --- a/postcss.config.mjs +++ /dev/null @@ -1,8 +0,0 @@ -/** @type {import('postcss-load-config').Config} */ -const config = { - plugins: { - tailwindcss: {}, - }, -}; - -export default config; diff --git a/src/app/[locale]/about/ain-Kana.mdx b/src/app/[locale]/about/ain-Kana.mdx index babea9a..ed75c12 100644 --- a/src/app/[locale]/about/ain-Kana.mdx +++ b/src/app/[locale]/about/ain-Kana.mdx @@ -2,6 +2,6 @@ エポソカネ、 シンナ イタㇰ、 ウェン イタㇰ アカㇻ ヒ カ オカアン ナンコㇿ。 クス、 タネ オカ アイヌ イタㇰ エランペウテㇰ ウタㇻ アナㇰネ イテキ オピッタ エイソコㇿ ヤン。 アイヌイタㇰ ピㇼカノ イェ クㇽ エチコピシ ヤㇰ ピㇼカ ナンコㇿ。 -オラ、 タン サイッ モトホ コード アナㇰネ、 [GitHub](https://github.com/neet/tunci) オッタ アヌカㇻ エアㇱカイ ルウェ ネ。 NLP エアㇱカイ クニ クカㇻ モデル アナㇰネ [Hugging Face Hub](https://huggingface.co/aynumosir) オッタ アヌカㇻ エアㇱカイ ルウェ ネ。 +オラ、 タン サイト モトホ コード アナㇰネ、 [GitHub](https://github.com/neet/tunci) オッタ アヌカㇻ エアㇱカイ ルウェ ネ。 NLP エアㇱカイ クニ クカㇻ モデル アナㇰネ [Hugging Face Hub](https://huggingface.co/aynumosir) オッタ アヌカㇻ エアㇱカイ ルウェ ネ。 -タン ウェブ サイッ カㇻ クㇽ エチコイタㇰ ルスイ ヤクン、 X エイワンケ ヤン。 [@TheGodOfNeet](https://x.com/TheGodOfNeet) +タン ウェブ サイト カㇻ クㇽ エチコイタㇰ ルスイ ヤクン、 X エイワンケ ヤン。 [@TheGodOfNeet](https://x.com/TheGodOfNeet) diff --git a/src/app/[locale]/about/ain-Latn.mdx b/src/app/[locale]/about/ain-Latn.mdx index e0b8127..3658ea4 100644 --- a/src/app/[locale]/about/ain-Latn.mdx +++ b/src/app/[locale]/about/ain-Latn.mdx @@ -1,7 +1,7 @@ -_tunci_ anakne Aynuitak or wa Sisam’itak a=nuye p ne yakka, Sisam’itak or wa Aynuitak a=nuye p ne yakka easkay aeywankep ne ruwe ne. Aynuitak eyaypakasnu wa oka utar ku=kasuy rusuy kusu, ku=kar pe ne ruwe ne. +_tunci_ anakne Aynu itak or wa Sisam itak a=nuye p ne yakka, Sisam itak or wa Aynu itak a=nuye p ne yakka easkay aeywankep ne ruwe ne. Aynuitak eyaypakasnu wa oka utar ku=kasuy rusuy kusu, ku=kar pe ne ruwe ne. eposokane, sinna itak, wen itak a=kar hi ka oka=an nankor. kusu, tane oka Aynuitak erampewtek utar anakne **iteki opitta eysokor** yan. Aynuitak pirkano ye kur eci=kopisi yak pirka nankor. -ora, tan sait motoho CODE anakne, [GitHub](https://github.com/neet/tunci) or ta a=nukar easkay ruwe ne. NLP easkay kuni ku=kar MODEL anakne [Hugging Face Hub](https://huggingface.co/aynumosir) or ta a=nukar easkay ruwe ne. +ora, tan SAITO motoho CODE anakne, [GitHub](https://github.com/neet/tunci) or ta a=nukar easkay ruwe ne. NLP easkay kuni ku=kar MODEL anakne [Hugging Face Hub](https://huggingface.co/aynumosir) or ta a=nukar easkay ruwe ne. -tan web sait kar kur eci=koytak rusuy yakun, X eywanke yan. [@TheGodOfNeet](https://x.com/TheGodOfNeet) +tan web SAITO kar kur eci=koytak rusuy yakun, X eywanke yan. [@TheGodOfNeet](https://x.com/TheGodOfNeet) diff --git a/src/app/[locale]/about/ja.mdx b/src/app/[locale]/about/ja.mdx index 0a7a03b..e0e2b57 100644 --- a/src/app/[locale]/about/ja.mdx +++ b/src/app/[locale]/about/ja.mdx @@ -1,3 +1,5 @@ +import { Table } from "@radix-ui/themes"; + tunciは、アイヌ語↔日本語の双方向翻訳を行うWebアプリです。現在、アイヌ語学習者に向けて試験的に公開しています。 当然ながら、誤った翻訳を生成することがあります。アイヌ語初学者の方は、**結果を鵜呑みにせず、かならず講師や上級者に確認**してください。 @@ -10,30 +12,30 @@ tunciは、アイヌ語↔日本語の双方向翻訳を行うWebアプリです 2024年7月時点で、アイヌ語↔日本語の翻訳において以下のBLEUスコアを達成しています。 - - - - - - - - + + + + 翻訳元 + 翻訳先 + BLEUスコア + + - - - - - - - - - - - + + 日本語 + アイヌ語 + 39.06 + + + + アイヌ語 + 日本語 + 31.83 + -
翻訳元翻訳先BLEUスコア
日本語アイヌ語39.06
アイヌ語日本語31.83
+ ### AI活用について @@ -53,102 +55,112 @@ tunciの翻訳は機械学習によって実現されており、アイヌ語お tunciの翻訳モデルは、以下のデータを利用して訓練されています。 - - - - - - - - - + + + + データ名 + 形式 + 単語数 + 文字数 + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + アイヌ語アーカイブ + Web + 600,770 + 2,107,984 + + + アイヌタイムズ + 書籍 + 148,843 + 519,040 + + + アイヌ語口承文芸コーパス + PDF + 135,649 + 492,484 + + + + AA研アイヌ語資料公開プロジェクト + + Web + 95,379 + 299,630 + + + アイヌ語口承文芸コーパス + Web + 76,550 + 243,696 + + + + アイヌ語鵡川方言 日本語-アイヌ語辞典 + + Web + 66,386 + 247,637 + + + アイヌ語テキスト + PDF + 25,067 + 84,905 + + + + 北海道立アイヌ文化研究センター研究紀要 + + PDF + 14,724 + 48,092 + + + アイヌ語会話辞典 + Web + 13,831 + 49,776 + + + アイヌ神謡集 + 書籍 + 10,364 + 38,153 + + + + ニューエクスプレスプラス アイヌ語 + + 書籍 + 4,418 + 14,812 + + + + カムイユカㇻを聞いてアイヌ語を学ぶ + + 書籍 + 3,028 + 11,177 + + + アコㇿイタㇰ + 書籍 + 2,005 + 5,903 + + + その他論文など + - + - + - + -
データ名形式単語数文字数
アイヌ語アーカイブWeb600,7702,107,984
アイヌタイムズ書籍148,843519,040
アイヌ語口承文芸コーパスPDF135,649492,484
AA研アイヌ語資料公開プロジェクトWeb95,379299,630
アイヌ語口承文芸コーパスWeb76,550243,696
アイヌ語鵡川方言 日本語-アイヌ語辞典Web66,386247,637
アイヌ語テキストPDF25,06784,905
北海道立アイヌ文化研究センター研究紀要PDF14,72448,092
アイヌ語会話辞典Web13,83149,776
アイヌ神謡集書籍10,36438,153
ニューエクスプレスプラス アイヌ語書籍4,41814,812
カムイユカㇻを聞いてアイヌ語を学ぶ書籍3,02811,177
アコㇿイタㇰ書籍2,0055,903
その他論文など---
+ ### 関連プロジェクト diff --git a/src/app/[locale]/about/page.tsx b/src/app/[locale]/about/page.tsx index 62e09cf..66712b4 100644 --- a/src/app/[locale]/about/page.tsx +++ b/src/app/[locale]/about/page.tsx @@ -1,4 +1,4 @@ -import clsx from "clsx"; +import { Card, Container, Heading, Section } from "@radix-ui/themes"; import { Metadata } from "next"; import { getTranslations, setRequestLocale } from "next-intl/server"; @@ -26,14 +26,20 @@ export default async function AboutPage({ params }: AboutPageProps) { const Content = (await import(`./${params.locale}.mdx`)).default; return ( -
-
-

{t("title")}

-
+ +
+
+ + {t("title")} + +
-
- -
-
+ +
+ +
+
+
+ ); } diff --git a/src/app/[locale]/globals.css b/src/app/[locale]/globals.css index 0c40fee..6915890 100644 --- a/src/app/[locale]/globals.css +++ b/src/app/[locale]/globals.css @@ -1,9 +1,37 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - @media (prefers-color-scheme: dark) { :root { color-scheme: dark; } } + +.radix-themes { + --default-font-family: var(--font-roboto), "Hiragino Kaku Gothic ProN", + "Hiragino Sans", "Meiryo", "ui-sans-serif", "system-ui"; +} + +html, +body { + margin: 0; +} + +body > div:first-of-type { + background-size: 100% 1000px; + background-repeat: no-repeat; + background-image: linear-gradient( + 12deg, + rgba(0, 0, 0, 0) 50%, + var(--accent-4) 100% + ); +} + +fieldset { + border: 0; + padding: 0; + margin: 0; +} + +legend { + padding: 0; + margin: 0; + line-height: 1; +} diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index e6afc4d..1c95815 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -1,11 +1,14 @@ import "./globals.css"; +import "@radix-ui/themes/styles.css"; import { GoogleAnalytics } from "@next/third-parties/google"; +import { Grid, Theme } from "@radix-ui/themes"; import clsx from "clsx"; import type { Metadata } from "next"; import { Roboto, Yeseva_One } from "next/font/google"; import { NextIntlClientProvider } from "next-intl"; import { getMessages, setRequestLocale } from "next-intl/server"; +import { ThemeProvider } from "next-themes"; import { routing } from "@/i18n/routing"; @@ -63,22 +66,26 @@ export default async function RootLayout(props: RootLayoutProps) { const messages = await getMessages(); return ( - - - - - {children} - - + + + + + + + + {children} + + + + + + diff --git a/src/app/[locale]/page.tsx b/src/app/[locale]/page.tsx index f55e3f4..647499b 100644 --- a/src/app/[locale]/page.tsx +++ b/src/app/[locale]/page.tsx @@ -1,3 +1,4 @@ +import { Container } from "@radix-ui/themes"; import { tokenize } from "ainu-utils"; import { SearchResponse } from "algoliasearch"; import { Metadata } from "next"; @@ -89,28 +90,32 @@ export default async function Home(props: HomeProps) { } return ( -
- -
+ +
+ +
+
); } diff --git a/src/components/Banner/Banner.css b/src/components/Banner/Banner.css new file mode 100644 index 0000000..ac1c891 --- /dev/null +++ b/src/components/Banner/Banner.css @@ -0,0 +1,16 @@ +.Banner { + .logo-link { + color: var(--gray-12); + text-decoration: none; + } + + .title { + font-family: var(--font-yeseva-one); + text-decoration: none; + } + + .logo { + width: 28px; + height: 28px; + } +} diff --git a/src/components/Banner/Banner.tsx b/src/components/Banner/Banner.tsx index d822858..b2cc68a 100644 --- a/src/components/Banner/Banner.tsx +++ b/src/components/Banner/Banner.tsx @@ -1,8 +1,10 @@ -import clsx from "clsx"; +import "./Banner.css"; + +import { Container, Flex, Heading, Link } from "@radix-ui/themes"; import { getTranslations } from "next-intl/server"; import { FC } from "react"; -import { Link } from "@/i18n/routing"; +import { Link as NextLink } from "@/i18n/routing"; import { Logo } from "./Logo"; @@ -10,42 +12,23 @@ export const Banner: FC = async () => { const t = await getTranslations("components.Banner"); return ( -
-
-
- - -

- tunci -

- -
+ +
+ + + + + + tunci + + + - - {t("about")} - -
-
+ + {t("about")} + + + + ); }; diff --git a/src/components/Button/Button.stories.tsx b/src/components/Button/Button.stories.tsx deleted file mode 100644 index 8d330f6..0000000 --- a/src/components/Button/Button.stories.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import type { Meta, StoryObj } from "@storybook/react"; -import { fn } from "@storybook/test"; - -import { Button } from "./Button"; - -const meta = { - title: "Components/Button", - component: Button, - parameters: { - layout: "centered", - }, - tags: ["autodocs"], - argTypes: {}, - args: { onClick: fn() }, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Primary: Story = { - args: { - children: "Button", - }, -}; - -export const Disabled: Story = { - args: { - children: "Button", - disabled: true, - }, -}; diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx deleted file mode 100644 index 8229502..0000000 --- a/src/components/Button/Button.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import clsx from "clsx"; -import { ComponentProps, FC } from "react"; -import { tv } from "tailwind-variants"; - -const button = tv({ - base: [ - "px-3 py-1.5 rounded-lg", - "outline-indigo-400 outline-2 focus:outline outline-offset-4", - "transition", - ], - variants: { - variant: { - primary: [ - // light - "bg-indigo-600 text-white", - "hover:bg-indigo-700", - "disabled:bg-indigo-400 disabled:hover:bg-indigo-500", - // dark - "dark:bg-indigo-400 dark:text-black", - "dark:hover:bg-indigo-500", - "dark:disabled:bg-indigo-300 dark:disabled:hover:bg-indigo-400", - // contrast - "forced-colors:border forced-colors:border-[ButtonBorder]", - ], - - secondary: [ - "border", - // light - "border-indigo-600 text-indigo-600", - "hover:bg-indigo-100", - // "disabled:bg-indigo-200 disabled:hover:bg-indigo-300", - // dark - "dark:border-indigo-400 dark:text-indigo-400", - "dark:hover:bg-indigo-900", - // "dark:disabled:bg-indigo-800 dark:disabled:hover:bg-indigo-700", - // contrast - "forced-colors:border forced-colors:border-[ButtonBorder]", - ], - }, - size: { - md: "", - lg: "text-lg", - }, - }, - - defaultVariants: { - variant: "primary", - size: "md", - }, -}); - -export type ButtonVariant = "primary" | "secondary"; - -export type ButtonProps = ComponentProps<"button"> & { - variant?: ButtonVariant; - size?: "lg"; -}; - -export const Button: FC = (props) => { - const { children, className, size, variant, ...rest } = props; - - return ( - - ); -}; diff --git a/src/components/Button/index.ts b/src/components/Button/index.ts deleted file mode 100644 index e22c29a..0000000 --- a/src/components/Button/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./Button"; diff --git a/src/components/Composer/AdvancedSettingsDialog/AdvancedSettingsDialog.tsx b/src/components/Composer/AdvancedSettingsDialog/AdvancedSettingsDialog.tsx index 150e1fe..1c900a2 100644 --- a/src/components/Composer/AdvancedSettingsDialog/AdvancedSettingsDialog.tsx +++ b/src/components/Composer/AdvancedSettingsDialog/AdvancedSettingsDialog.tsx @@ -1,43 +1,50 @@ -import clsx from "clsx"; -import { forwardRef, ForwardRefRenderFunction } from "react"; +import { Dialog } from "@radix-ui/themes"; +import { FC, ReactNode, useRef } from "react"; import { AdvancedSettingsDialogContent } from "./AdvancedSettingsDialogContent"; +import { AdvancedSettings } from "./models"; export type AdvancedSettingsDialogProps = { - defaultValues?: { - pronoun?: string; - dialect?: string; - }; - onClose(): void; + opener: ReactNode; + defaultValues: AdvancedSettings; + onClose?: (values: Partial) => void; }; -const AdvancedSettingsDialogRenderFn: ForwardRefRenderFunction< - HTMLDialogElement, - AdvancedSettingsDialogProps -> = (props, ref) => { - const { defaultValues = {}, onClose } = props; +export const AdvancedSettingsDialog: FC = ( + props, +) => { + const { defaultValues, onClose } = props; + + const ref = useRef(null); + + const handleOpenChange = (open: boolean) => { + if (open) { + return; + } + + const form = ref.current?.querySelector("form"); + + if (!(form instanceof HTMLFormElement)) { + return; + } + + const fd = new FormData(form); + + onClose?.({ + pronoun: fd.get("pronoun") as string, + dialect: fd.get("dialect") as string, + }); + }; return ( - - - + + {props.opener} + + +
+ + +
+
); }; - -export const AdvancedSettingsDialog = forwardRef( - AdvancedSettingsDialogRenderFn, -); diff --git a/src/components/Composer/AdvancedSettingsDialog/AdvancedSettingsDialogContent.tsx b/src/components/Composer/AdvancedSettingsDialog/AdvancedSettingsDialogContent.tsx index 40dba8a..c837323 100644 --- a/src/components/Composer/AdvancedSettingsDialog/AdvancedSettingsDialogContent.tsx +++ b/src/components/Composer/AdvancedSettingsDialog/AdvancedSettingsDialogContent.tsx @@ -1,74 +1,45 @@ -"use client"; - -import clsx from "clsx"; +import { Box, Button, Dialog, Flex, Text } from "@radix-ui/themes"; import { useTranslations } from "next-intl"; import { FC } from "react"; -import { FiX } from "react-icons/fi"; - -import { Button } from "@/components/Button"; import { DialectSelector } from "./DialectSelector"; +import { AdvancedSettings } from "./models"; import { PronounSelector } from "./PronounSelector"; export interface AdvancedSettingsDialogContentProps { - defaultValues?: { - pronoun?: string; - dialect?: string; - }; - onClose(): void; + defaultValues: AdvancedSettings; } export const AdvancedSettingsDialogContent: FC< AdvancedSettingsDialogContentProps > = (props) => { - const { defaultValues, onClose } = props; + const { defaultValues } = props; - const t = useTranslations("components.Composer"); + const t = useTranslations( + "components.Composer.AdvancedSettingsDialog.AdvancedSettingsDialogContent", + ); return ( -
-
-

- {t("advanced_settings")} -

- - -
- -
- - - -
- -
-
-
+ + + ); }; diff --git a/src/components/Composer/AdvancedSettingsDialog/AdvancedSettingsSection.tsx b/src/components/Composer/AdvancedSettingsDialog/AdvancedSettingsSection.tsx deleted file mode 100644 index b353089..0000000 --- a/src/components/Composer/AdvancedSettingsDialog/AdvancedSettingsSection.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { FC, ReactNode } from "react"; - -export type AdvancedSettingsSectionProps = { - legend: string; - description: string; - children: ReactNode; -}; - -export const AdvancedSettingsSection: FC = ( - props, -) => { - const { legend, description, children } = props; - - return ( -
-
{legend}
- -

{description}

- -
{children}
-
- ); -}; diff --git a/src/components/Composer/AdvancedSettingsDialog/DialectSelector/DialectSelector.tsx b/src/components/Composer/AdvancedSettingsDialog/DialectSelector/DialectSelector.tsx index 09ba4c0..c5a32e1 100644 --- a/src/components/Composer/AdvancedSettingsDialog/DialectSelector/DialectSelector.tsx +++ b/src/components/Composer/AdvancedSettingsDialog/DialectSelector/DialectSelector.tsx @@ -1,10 +1,9 @@ -import clsx from "clsx"; +import { Box, Flex, Grid, RadioGroup, Text, Tooltip } from "@radix-ui/themes"; +import { useTranslations } from "next-intl"; import { FC, useState } from "react"; -import { useTranslations } from "use-intl"; +import { IoFlask } from "react-icons/io5"; -import { AdvancedSettingsSection } from "../AdvancedSettingsSection"; import { DialectSelectorMap } from "./DialectSelectorMap"; -import { DialectSelectorOption } from "./DialectSelectorOption"; import { Dialect } from "./model"; export type DialectSelectorProps = { @@ -14,7 +13,9 @@ export type DialectSelectorProps = { export const DialectSelector: FC = (props) => { const [value, setValue] = useState(props.defaultValue); - const t = useTranslations("components.Composer.DialectSelector"); + const t = useTranslations( + "components.Composer.AdvancedSettingsDialog.DialectSelector", + ); const dialects: Dialect[] = [ { @@ -70,49 +71,63 @@ export const DialectSelector: FC = (props) => { ]; return ( - -
-
- -
+
+ + {t("title")} + + + + {t("description")} + -
+ - {dialects.map((dialect) => ( - + + + + + - {dialect.name} - - ))} -
-
-
+ {dialects.map((dialect) => ( + + + {dialect.name} + + {dialect.experimental && ( + + + + )} + + + ))} + + + + + ); }; diff --git a/src/components/Composer/AdvancedSettingsDialog/DialectSelector/DialectSelectorMap.css b/src/components/Composer/AdvancedSettingsDialog/DialectSelector/DialectSelectorMap.css new file mode 100644 index 0000000..bffb448 --- /dev/null +++ b/src/components/Composer/AdvancedSettingsDialog/DialectSelector/DialectSelectorMap.css @@ -0,0 +1,25 @@ +#DialectSelectorMap { + .geographies { + fill: var(--gray-surface); + stroke: var(--gray-track); + stroke-width: 1px; + } + + .circle { + fill: var(--gray-9); + } + + .circle--selected { + fill: var(--accent-9); + } + + .caption { + font-weight: bold; + font-size: 1.3em; + fill: var(--gray-11); + } + + .caption--selected { + fill: var(--accent-11); + } +} diff --git a/src/components/Composer/AdvancedSettingsDialog/DialectSelector/DialectSelectorMap.tsx b/src/components/Composer/AdvancedSettingsDialog/DialectSelector/DialectSelectorMap.tsx index af52d05..59e2aa4 100644 --- a/src/components/Composer/AdvancedSettingsDialog/DialectSelector/DialectSelectorMap.tsx +++ b/src/components/Composer/AdvancedSettingsDialog/DialectSelector/DialectSelectorMap.tsx @@ -1,4 +1,4 @@ -"use client"; +import "./DialectSelectorMap.css"; import clsx from "clsx"; import { FC } from "react"; @@ -24,6 +24,7 @@ export const DialectSelectorMap: FC = (props) => { return ( = (props) => { 北海道の方言の地図。マウスを使うと、各地をクリックすることで方言を選べます。 - + {({ geographies }) => geographies.map((geo) => ( @@ -55,48 +49,26 @@ export const DialectSelectorMap: FC = (props) => { { onChange?.(dialect.value); }} > - {dialect.value === value ? ( - - ) : ( - - )} + - {dialect.value === value ? ( - - {dialect.name} - - ) : ( - - {dialect.name} - - )} + + {dialect.name} + ))} diff --git a/src/components/Composer/AdvancedSettingsDialog/DialectSelector/DialectSelectorOption.tsx b/src/components/Composer/AdvancedSettingsDialog/DialectSelector/DialectSelectorOption.tsx deleted file mode 100644 index e463e72..0000000 --- a/src/components/Composer/AdvancedSettingsDialog/DialectSelector/DialectSelectorOption.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import clsx from "clsx"; -import { useTranslations } from "next-intl"; -import { FC } from "react"; -import { IoFlask } from "react-icons/io5"; - -type DialectSelectorOptionProps = { - children: React.ReactNode; - value: string; - checked?: boolean; - experimental?: boolean; - onChange?(value: string): void; -}; - -export const DialectSelectorOption: FC = ( - props, -) => { - const { value, checked, children, experimental, onChange } = props; - - const t = useTranslations("components.Composer.DialectSelector"); - - return ( - - ); -}; diff --git a/src/components/Composer/AdvancedSettingsDialog/PronounSelector.tsx b/src/components/Composer/AdvancedSettingsDialog/PronounSelector.tsx new file mode 100644 index 0000000..9419009 --- /dev/null +++ b/src/components/Composer/AdvancedSettingsDialog/PronounSelector.tsx @@ -0,0 +1,41 @@ +import { Flex, RadioCards, Text } from "@radix-ui/themes"; +import { useTranslations } from "next-intl"; +import { FC } from "react"; + +export type PronounSelectorProps = { + defaultValue: string; +}; + +export const PronounSelector: FC = (props) => { + const t = useTranslations( + "components.Composer.AdvancedSettingsDialog.PronounSelector", + ); + + return ( +
+ + {t("title")} + + + + {t("description")} + + + + + + {t("first")} + {t("firstDescription")} + + + + + + {t("fourth")} + {t("fourthDescription")} + + + +
+ ); +}; diff --git a/src/components/Composer/AdvancedSettingsDialog/PronounSelector/PronounSelector.tsx b/src/components/Composer/AdvancedSettingsDialog/PronounSelector/PronounSelector.tsx deleted file mode 100644 index 4712bd1..0000000 --- a/src/components/Composer/AdvancedSettingsDialog/PronounSelector/PronounSelector.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { FC } from "react"; -import { useTranslations } from "use-intl"; - -import { AdvancedSettingsSection } from "../AdvancedSettingsSection"; -import { PronounSelectorOption } from "./PronounSelectorOption"; - -export type PronounSelectorProps = { - defaultValue?: string; -}; - -export const PronounSelector: FC = (props) => { - const { defaultValue } = props; - - const t = useTranslations("components.Composer.PronounSelector"); - - return ( - -
- - - -
-
- ); -}; diff --git a/src/components/Composer/AdvancedSettingsDialog/PronounSelector/PronounSelectorOption.tsx b/src/components/Composer/AdvancedSettingsDialog/PronounSelector/PronounSelectorOption.tsx deleted file mode 100644 index 5c8fab2..0000000 --- a/src/components/Composer/AdvancedSettingsDialog/PronounSelector/PronounSelectorOption.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import clsx from "clsx"; -import { FC } from "react"; - -export type PronounSelectorOptionProps = { - title: string; - description: string; - value: string; - defaultChecked: boolean; - className?: string; -}; - -export const PronounSelectorOption: FC = ( - props, -) => { - const { title, description, value, defaultChecked, className } = props; - - return ( - - ); -}; diff --git a/src/components/Composer/AdvancedSettingsDialog/PronounSelector/index.ts b/src/components/Composer/AdvancedSettingsDialog/PronounSelector/index.ts deleted file mode 100644 index 9b61c6e..0000000 --- a/src/components/Composer/AdvancedSettingsDialog/PronounSelector/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./PronounSelector"; diff --git a/src/components/Composer/AdvancedSettingsDialog/index.ts b/src/components/Composer/AdvancedSettingsDialog/index.ts index b830287..dcf70db 100644 --- a/src/components/Composer/AdvancedSettingsDialog/index.ts +++ b/src/components/Composer/AdvancedSettingsDialog/index.ts @@ -1 +1,2 @@ export * from "./AdvancedSettingsDialog"; +export * from "./models"; diff --git a/src/components/Composer/AdvancedSettingsDialog/models.ts b/src/components/Composer/AdvancedSettingsDialog/models.ts new file mode 100644 index 0000000..b6c4b65 --- /dev/null +++ b/src/components/Composer/AdvancedSettingsDialog/models.ts @@ -0,0 +1,4 @@ +export type AdvancedSettings = { + pronoun: string; + dialect: string; +}; diff --git a/src/components/Composer/AlternativeTranslations/AlternativeTranslations.css b/src/components/Composer/AlternativeTranslations/AlternativeTranslations.css new file mode 100644 index 0000000..d94302e --- /dev/null +++ b/src/components/Composer/AlternativeTranslations/AlternativeTranslations.css @@ -0,0 +1,5 @@ +.AlternativeTranslationsContent { + li::marker { + color: var(--gray-6); + } +} diff --git a/src/components/Composer/AlternativeTranslations/AlternativeTranslations.tsx b/src/components/Composer/AlternativeTranslations/AlternativeTranslations.tsx index 4ee037a..7ca8fed 100644 --- a/src/components/Composer/AlternativeTranslations/AlternativeTranslations.tsx +++ b/src/components/Composer/AlternativeTranslations/AlternativeTranslations.tsx @@ -1,10 +1,12 @@ +import "./AlternativeTranslations.css"; + import { useSearchParams } from "next/navigation"; import { FC, Suspense } from "react"; import { ErrorBoundary } from "react-error-boundary"; import { AlternativeTranslationsContent } from "./AlternativeTranslationsContent"; +import { AlternativeTranslationsError } from "./AlternativeTranslationsError"; import { AlternativeTranslationsSkeleton } from "./AlternativeTranslationsSkeleton"; -import { AlternativeTranslationsError } from "./AlternativeTrasnlationsError"; export type AlternativeTranslationsProps = { alternativeTranslationsPromise?: Promise; diff --git a/src/components/Composer/AlternativeTranslations/AlternativeTranslationsContent.tsx b/src/components/Composer/AlternativeTranslations/AlternativeTranslationsContent.tsx index 455e586..a7d65cf 100644 --- a/src/components/Composer/AlternativeTranslations/AlternativeTranslationsContent.tsx +++ b/src/components/Composer/AlternativeTranslations/AlternativeTranslationsContent.tsx @@ -1,3 +1,4 @@ +import { Box, Text } from "@radix-ui/themes"; import { useTranslations } from "next-intl"; import { FC, use } from "react"; @@ -13,7 +14,9 @@ export const AlternativeTranslationsContent: FC< const { alternativeTranslationsPromise } = props; const alternativeTranslations = use(alternativeTranslationsPromise); - const t = useTranslations("components.AlternativeTranslations"); + const t = useTranslations( + "components.Composer.AlternativeTranslations.AlternativeTranslationsContent", + ); if (alternativeTranslations.length <= 0) { return null; @@ -21,15 +24,17 @@ export const AlternativeTranslationsContent: FC< return ( -

+ {t("description")} -

+ -
    - {alternativeTranslations.map((alternativeTranslation, index) => ( -
  • {alternativeTranslation}
  • - ))} -
+ +
    + {alternativeTranslations.map((alternativeTranslation, index) => ( +
  • {alternativeTranslation}
  • + ))} +
+
); }; diff --git a/src/components/Composer/AlternativeTranslations/AlternativeTrasnlationsError.tsx b/src/components/Composer/AlternativeTranslations/AlternativeTranslationsError.tsx similarity index 51% rename from src/components/Composer/AlternativeTranslations/AlternativeTrasnlationsError.tsx rename to src/components/Composer/AlternativeTranslations/AlternativeTranslationsError.tsx index 1345a4f..cb1d4dd 100644 --- a/src/components/Composer/AlternativeTranslations/AlternativeTrasnlationsError.tsx +++ b/src/components/Composer/AlternativeTranslations/AlternativeTranslationsError.tsx @@ -1,13 +1,17 @@ +import { Text } from "@radix-ui/themes"; +import { useTranslations } from "next-intl"; import { FC } from "react"; import { AlternativeTranslationsWrapper } from "./AlternativeTranslationsWrapper"; export const AlternativeTranslationsError: FC = () => { + const t = useTranslations( + "components.Composer.AlternativeTranslations.AlternativeTranslationsError", + ); + return ( -

- データ取得中にエラーが発生しました。時間をおいて再度お試しください。 -

+ {t("description")}
); }; diff --git a/src/components/Composer/AlternativeTranslations/AlternativeTranslationsSkeleton.tsx b/src/components/Composer/AlternativeTranslations/AlternativeTranslationsSkeleton.tsx index 0663231..76fc9af 100644 --- a/src/components/Composer/AlternativeTranslations/AlternativeTranslationsSkeleton.tsx +++ b/src/components/Composer/AlternativeTranslations/AlternativeTranslationsSkeleton.tsx @@ -1,3 +1,4 @@ +import { Skeleton, Text } from "@radix-ui/themes"; import { FC } from "react"; import { AlternativeTranslationsWrapper } from "./AlternativeTranslationsWrapper"; @@ -6,9 +7,11 @@ export const AlternativeTranslationsSkeleton: FC = () => { return (
-
-
-
+ + irankarapte. tanto sirpirka wa. + irankarapte. tanto sirpirka wa. + irankarapte. tanto sirpirka wa. +
); diff --git a/src/components/Composer/AlternativeTranslations/AlternativeTranslationsWrapper.tsx b/src/components/Composer/AlternativeTranslations/AlternativeTranslationsWrapper.tsx index 3bde63a..7fa8a7f 100644 --- a/src/components/Composer/AlternativeTranslations/AlternativeTranslationsWrapper.tsx +++ b/src/components/Composer/AlternativeTranslations/AlternativeTranslationsWrapper.tsx @@ -1,7 +1,7 @@ import { useTranslations } from "next-intl"; import { FC, ReactNode } from "react"; -import { Disclosure } from "../Disclosure"; +import { ComposerCollapsible } from "../ComposerCollapsible"; export type AlternativeTranslationsWrapperProps = { children: ReactNode; @@ -10,12 +10,13 @@ export type AlternativeTranslationsWrapperProps = { export const AlternativeTranslationsWrapper: FC< AlternativeTranslationsWrapperProps > = (props) => { - const { children } = props; - const t = useTranslations("components.Composer"); + const t = useTranslations( + "components.Composer.AlternativeTranslations.AlternativeTranslationsWrapper", + ); return ( - {t("alternativeTranslations")}}> - {children} - + + {props.children} + ); }; diff --git a/src/components/Composer/CharCount.tsx b/src/components/Composer/CharCount.tsx index 2e704aa..c463b51 100644 --- a/src/components/Composer/CharCount.tsx +++ b/src/components/Composer/CharCount.tsx @@ -1,4 +1,4 @@ -import clsx from "clsx"; +import { Box, Text, VisuallyHidden } from "@radix-ui/themes"; import { useTranslations } from "next-intl"; import { FC } from "react"; @@ -10,23 +10,19 @@ export type CharCountProps = { export const CharCount: FC = (props) => { const { count, limit } = props; - const t = useTranslations("components.Composer"); + const t = useTranslations("components.Composer.CharCount"); return ( -
limit - ? "text-red-600 dark:text-red-400" - : "text-gray-600 dark:text-zinc-400", - )} - > - - {count}/{limit} - - - {t("char_max", { current: count, max: 200 })} - -
+ + + {t("charMax", { current: count, max: 200 })} + + + limit ? "red" : "gray"}> + + {count}/{limit} + + + ); }; diff --git a/src/components/Composer/Composer.css b/src/components/Composer/Composer.css new file mode 100644 index 0000000..618138b --- /dev/null +++ b/src/components/Composer/Composer.css @@ -0,0 +1,15 @@ +textarea#text { + display: block; + border: none; + background-color: transparent; + width: 100%; + padding: 0; + min-height: 4lh; + font-family: var(--default-font-family); + resize: none; + outline: none; + + &::placeholder { + color: var(--gray-11); + } +} diff --git a/src/components/Composer/Composer.tsx b/src/components/Composer/Composer.tsx index 0283c8b..4aad63b 100644 --- a/src/components/Composer/Composer.tsx +++ b/src/components/Composer/Composer.tsx @@ -1,7 +1,9 @@ "use client"; +import "./Composer.css"; + +import { Grid, Heading, VisuallyHidden } from "@radix-ui/themes"; import { SearchResponse } from "algoliasearch"; -import clsx from "clsx"; import debounce from "lodash-es/debounce"; import mixpanel from "mixpanel-browser"; import { useRouter } from "next/navigation"; @@ -15,25 +17,12 @@ import { useState, useTransition, } from "react"; -import { FiClipboard, FiCopy, FiMic, FiShare, FiVolume2 } from "react-icons/fi"; -import TextareaAutosize from "react-textarea-autosize"; import { SearchEntry } from "@/models/entry"; import * as t from "@/models/transcription"; -import { Alert } from "../Alert"; -import { Button } from "../Button"; -import { AdvancedSettingsDialog } from "./AdvancedSettingsDialog"; -import { AlternativeTranslations } from "./AlternativeTranslations"; -import { CharCount } from "./CharCount"; -import { Disclaimer } from "./Disclaimer"; -import { ExampleSentences } from "./ExampleSentences"; -import { HeaderGroup } from "./HeaderGroup"; -import { IconButton } from "./IconButton"; -import { IconButtonGroup } from "./IconButtonGroup"; -import { LanguageSelector } from "./LanguageSelector"; -import { Transcription } from "./Transcription"; -import { Translation } from "./Translation"; +import { ComposerInput } from "./ComposerInput"; +import { ComposerOutput } from "./ComposerOutput"; export type ComposerProps = { method: string; @@ -73,7 +62,6 @@ export const Composer: FC = (props) => { const [pending, startTransition] = useTransition(); const textareaRef = useRef(null); - const dialogRef = useRef(null); const submitted = useRef(false); const headingId = useId(); @@ -102,19 +90,15 @@ export const Composer: FC = (props) => { [], ); - const handleChangeText = ( - e: React.ChangeEvent, - ): void => { + const handleChangeText = (text: string): void => { setDirty(true); - setCountDebounced(e.target.value.length); + setCountDebounced(text.length); }; - const handleChangeSource = ( - event: React.ChangeEvent, - ): void => { + const handleChangeSource = (source: string): void => { startTransition(() => { - setSource(event.target.value); - setTarget(event.target.value === "ja" ? "ain" : "ja"); + setSource(source); + setTarget(source === "ja" ? "ain" : "ja"); if (translation && textareaRef.current && !dirty) { textareaRef.current.value = translation; @@ -123,12 +107,10 @@ export const Composer: FC = (props) => { }); }; - const handleChangeTarget = ( - event: React.ChangeEvent, - ): void => { + const handleChangeTarget = (target: string): void => { startTransition(() => { - setTarget(event.target.value); - setSource(event.target.value === "ja" ? "ain" : "ja"); + setTarget(target); + setSource(target === "ja" ? "ain" : "ja"); if (translation && textareaRef.current && !dirty) { textareaRef.current.value = translation; @@ -189,14 +171,6 @@ export const Composer: FC = (props) => { }); }; - const handleOpen = (): void => { - dialogRef.current?.showModal(); - }; - - const handleClose = (): void => { - dialogRef.current?.close(); - }; - const handleSubmit = (event: React.FormEvent): void => { startTransition(() => { event.preventDefault(); @@ -231,198 +205,48 @@ export const Composer: FC = (props) => {
-

- {t("translateForm")} -

- - {errorMessage && ( - - {errorMessage} - - )} - -
- - - - -
-
- - - - - {ready && textTranscription && ( - - {textTranscription.text} - - )} -
- - - - - - - 0} - title={t("play")} - onClick={handlePlayInput} - > - - - - } - end={ - <> - - - - - - - } - /> -
- -
- - - -
-
- -
-
- - - {dirty && ( -
-

- {t("not_translated")} -

-
- )} -
- -
-
-

- {t("translationResult")} -

- -
-

- -

- - {ready && translationTranscription && ( - - {translationTranscription.text} - - )} -
- - - - - } - end={ - <> - - - - - - - - - } - /> -
- - {ready && } - - {ready && ( - - )} - - {ready && ( - - )} -
-
-
- - + + + {t("translateForm")} + + + + + + + + ); }; diff --git a/src/components/Composer/ComposerCollapsible.tsx b/src/components/Composer/ComposerCollapsible.tsx new file mode 100644 index 0000000..7a7f9d3 --- /dev/null +++ b/src/components/Composer/ComposerCollapsible.tsx @@ -0,0 +1,43 @@ +import * as Collapsible from "@radix-ui/react-collapsible"; +import { Card, ChevronDownIcon, Flex, Heading, Reset } from "@radix-ui/themes"; +import { FC, ReactNode, useId, useState } from "react"; + +export type ComposerCollapsibleProps = { + title: string; + children: ReactNode; +}; + +export const ComposerCollapsible: FC = (props) => { + const { title, children } = props; + + const [open, setOpen] = useState(true); + const id = useId(); + + return ( + + + + + + + + + + + + {children} + + + + ); +}; diff --git a/src/components/Composer/ComposerInput.tsx b/src/components/Composer/ComposerInput.tsx new file mode 100644 index 0000000..12d700c --- /dev/null +++ b/src/components/Composer/ComposerInput.tsx @@ -0,0 +1,196 @@ +import { + Box, + Button, + Card, + Flex, + IconButton, + Spinner, + Text, + Tooltip, + VisuallyHidden, +} from "@radix-ui/themes"; +import { useTranslations } from "next-intl"; +import { ComponentProps, FC, RefObject, useMemo, useState } from "react"; +import { FiClipboard, FiMic, FiVolume2 } from "react-icons/fi"; +import TextareaAutosize from "react-textarea-autosize"; + +import * as t from "../../models/transcription"; +import { + AdvancedSettings, + AdvancedSettingsDialog, +} from "./AdvancedSettingsDialog"; +import { CharCount } from "./CharCount"; +import { LanguageSelector } from "./LanguageSelector"; +import { Transcription } from "./Transcription"; + +export type ComposerInputProps = { + source: string; + defaultValues: { + text: string; + pronoun?: string; + dialect?: string; + }; + pending: boolean; + ready: boolean; + dirty: boolean; + textTranscription?: t.Transcription; + count: number; + textareaRef: RefObject; + onChangeSource: (source: string) => void; + onChangeText: (text: string) => void; + onRecognize: () => void; + onPlayInput: () => void; + onPaste: () => void; +}; + +export const ComposerInput: FC = (props) => { + const { + source, + defaultValues, + ready, + dirty, + pending, + textTranscription, + textareaRef, + count, + onChangeSource, + onChangeText, + onRecognize, + onPlayInput, + onPaste, + } = props; + + const t = useTranslations("components.Composer.ComposerInput"); + + const [advancedSettings, setAdvancedSettings] = useState({ + pronoun: defaultValues.pronoun ?? "first", + dialect: defaultValues.dialect ?? "沙流", + }); + + const textareaLanguageRelatedAttributes: ComponentProps< + typeof TextareaAutosize + > = useMemo(() => { + if (source === "ja") { + return { + lang: "ja", + }; + } + + if (source === "ain") { + return { + lang: "ain", + spellCheck: false, + autoComplete: "off", + autoCorrect: "off", + autoCapitalize: "off", + }; + } + + return {}; + }, [source]); + + const handleCloseDialog = (advancedSettings: Partial) => { + setAdvancedSettings((prev) => ({ ...prev, ...advancedSettings })); + }; + + return ( + + + onChangeSource(source)} + /> + + + + + + + + + + onChangeText(e.target.value)} + {...textareaLanguageRelatedAttributes} + /> + + + + {!dirty && ready && textTranscription + ? textTranscription.text + : undefined} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {t("advancedSettings")}} + onClose={handleCloseDialog} + /> + + + + + + + + ); +}; diff --git a/src/components/Composer/ComposerOutput.tsx b/src/components/Composer/ComposerOutput.tsx new file mode 100644 index 0000000..2b84247 --- /dev/null +++ b/src/components/Composer/ComposerOutput.tsx @@ -0,0 +1,177 @@ +import { ExclamationTriangleIcon } from "@radix-ui/react-icons"; +import { + Box, + Callout, + Card, + Flex, + Heading, + IconButton, + Text, + Tooltip, + VisuallyHidden, +} from "@radix-ui/themes"; +import { SearchResponse } from "algoliasearch"; +import { useTranslations } from "next-intl"; +import { FC } from "react"; +import { FiCopy, FiShare, FiVolume2 } from "react-icons/fi"; + +import { SearchEntry } from "@/models/entry"; + +import * as t from "../../models/transcription"; +import { AlternativeTranslations } from "./AlternativeTranslations"; +import { Disclaimer } from "./Disclaimer"; +import { ExampleSentences } from "./ExampleSentences"; +import { LanguageSelector } from "./LanguageSelector"; +import { Transcription } from "./Transcription"; +import { Translation } from "./Translation"; + +export type ComposerOutputProps = { + ready: boolean; + dirty: boolean; + target: string; + pending: boolean; + translation?: string; + translationTranscription?: t.Transcription; + errorMessage?: string; + onChangeTarget: (target: string) => void; + onPlayOutput: () => void; + onShare: () => void; + onCopy: () => void; + exampleSentencesPromise?: Promise>; + alternativeTranslationsPromise?: Promise; +}; + +export const ComposerOutput: FC = (props) => { + const { + ready, + dirty, + pending, + target, + translationTranscription, + translation, + errorMessage, + onChangeTarget, + onPlayOutput, + onShare, + onCopy, + } = props; + + const t = useTranslations("components.Composer.ComposerOutput"); + + return ( + + {errorMessage && ( + + + + + {errorMessage} + + )} + + + + onChangeTarget(target)} + /> + {dirty && ( +
+ + {t("untranslated")} + +
+ )} +
+ + + + + + {t("translationResult")} + + + + + + + + + {ready && translationTranscription + ? translationTranscription.text + : undefined} + + + + + + + + + + + + + + + + + + + + + {ready && ( + + + + )} +
+ + {ready && ( + + )} + + {ready && ( + + )} +
+ ); +}; diff --git a/src/components/Composer/Disclaimer.tsx b/src/components/Composer/Disclaimer.tsx index 13f55d7..f73205c 100644 --- a/src/components/Composer/Disclaimer.tsx +++ b/src/components/Composer/Disclaimer.tsx @@ -1,18 +1,16 @@ +import { ExclamationTriangleIcon } from "@radix-ui/react-icons"; +import { Callout } from "@radix-ui/themes"; import { useTranslations } from "next-intl"; import { FC } from "react"; -import { FiAlertCircle } from "react-icons/fi"; export const Disclaimer: FC = () => { const t = useTranslations("components.Composer.Disclaimer"); return ( -
- -

- {t("disclaimer")} -

-
+ + + + + {t("disclaimer")} + ); }; diff --git a/src/components/Composer/Disclosure.tsx b/src/components/Composer/Disclosure.tsx deleted file mode 100644 index 82b4198..0000000 --- a/src/components/Composer/Disclosure.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { FC, ReactNode } from "react"; -import { FiChevronDown, FiChevronUp } from "react-icons/fi"; - -export type DisclosureProps = { - open: boolean; - summary: ReactNode; - children: ReactNode; -}; - -export const Disclosure: FC = (props) => { - const { open, summary, children } = props; - - return ( -
- -
- {summary} -
- -
- - -
-
- - {children} -
- ); -}; diff --git a/src/components/Composer/ExampleSentences/ExampleSentencesContent.tsx b/src/components/Composer/ExampleSentences/ExampleSentencesContent.tsx index 58247a3..41b5c23 100644 --- a/src/components/Composer/ExampleSentences/ExampleSentencesContent.tsx +++ b/src/components/Composer/ExampleSentences/ExampleSentencesContent.tsx @@ -1,9 +1,11 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { Box, Reset, Separator } from "@radix-ui/themes"; import { SearchResponse } from "algoliasearch"; import { FC, use } from "react"; +import { Entry } from "@/components/Entry"; import { SearchEntry } from "@/models/entry"; -import { ExampleSentencesEntry } from "./ExampleSentencesEntry"; import { ExampleSentencesWrapper } from "./ExampleSentencesWrapper"; export type ExampleSentencesContentProps = { @@ -23,22 +25,35 @@ export const ExampleSentencesContent: FC = ( return ( -
    - {exampleSentences.hits.map((hit) => ( -
  • - -
  • - ))} -
+ +
    + {exampleSentences.hits.map((hit, i) => ( + + +
  • + + + {i !== exampleSentences.hits.length - 1 && ( + + )} +
  • +
    +
    + ))} +
+
); }; diff --git a/src/components/Composer/ExampleSentences/ExampleSentencesEntry.tsx b/src/components/Composer/ExampleSentences/ExampleSentencesEntry.tsx deleted file mode 100644 index 7ed264d..0000000 --- a/src/components/Composer/ExampleSentences/ExampleSentencesEntry.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import clsx from "clsx"; -import { - default as _parse, - DOMNode, - domToReact, - Element, -} from "html-react-parser"; -import { useTranslations } from "next-intl"; -import { FC, ReactNode } from "react"; -import { FiExternalLink, FiMapPin } from "react-icons/fi"; - -const isElement = (node: DOMNode): node is Element => "name" in node; - -export function parse(html: string) { - return _parse(html, { - replace: (domNode) => { - if (isElement(domNode) && domNode.name === "em") { - return ( - - {domToReact(domNode.children as DOMNode[])} - - ); - } - }, - }); -} - -export type ExampleSentencesEntryProps = { - textHTML: string; - translationHTML: string; - book: string; - title: string; - url: string; - dialect: string | null; -}; - -export const ExampleSentencesEntry: React.FC = ( - props, -) => { - const { textHTML, translationHTML, book, title, url, dialect } = props; - - const t = useTranslations("components.ExampleSentences"); - - return ( -
-
-
{parse(textHTML)}
-
{parse(translationHTML)}
-
- -
- - -
- {dialect && ( - }>{dialect} - )} -
-
-
- ); -}; - -export type TagProps = { - children: ReactNode; - icon?: ReactNode; -}; - -export const Tag: FC = (props) => { - const { icon, children } = props; - - return ( -
- {icon &&
{icon}
} - {children} -
- ); -}; diff --git a/src/components/Composer/ExampleSentences/ExampleSentencesError.tsx b/src/components/Composer/ExampleSentences/ExampleSentencesError.tsx index bd051e3..79af119 100644 --- a/src/components/Composer/ExampleSentences/ExampleSentencesError.tsx +++ b/src/components/Composer/ExampleSentences/ExampleSentencesError.tsx @@ -1,13 +1,17 @@ +import { Text } from "@radix-ui/themes"; +import { useTranslations } from "next-intl"; import { FC } from "react"; import { ExampleSentencesWrapper } from "./ExampleSentencesWrapper"; export const ExampleSentencesError: FC = () => { + const t = useTranslations( + "components.Composer.ExampleSentences.ExampleSentencesError", + ); + return ( -

- データ取得中にエラーが発生しました。時間をおいて再度お試しください。 -

+ {t("description")}
); }; diff --git a/src/components/Composer/ExampleSentences/ExampleSentencesSkeleton.tsx b/src/components/Composer/ExampleSentences/ExampleSentencesSkeleton.tsx index 03e0112..1f736c7 100644 --- a/src/components/Composer/ExampleSentences/ExampleSentencesSkeleton.tsx +++ b/src/components/Composer/ExampleSentences/ExampleSentencesSkeleton.tsx @@ -1,21 +1,15 @@ import { FC } from "react"; +import { Entry } from "@/components/Entry"; + import { ExampleSentencesWrapper } from "./ExampleSentencesWrapper"; export const ExampleSentencesSkeleton: FC = () => { return ( -
-
-
-
-
- -
-
-
-
-
+ {Array.from({ length: 3 }, (_, i) => ( + + ))} ); }; diff --git a/src/components/Composer/ExampleSentences/ExampleSentencesWrapper.tsx b/src/components/Composer/ExampleSentences/ExampleSentencesWrapper.tsx index a2814dd..d35daee 100644 --- a/src/components/Composer/ExampleSentences/ExampleSentencesWrapper.tsx +++ b/src/components/Composer/ExampleSentences/ExampleSentencesWrapper.tsx @@ -1,21 +1,22 @@ import { useTranslations } from "next-intl"; -import { FC } from "react"; +import { FC, ReactNode } from "react"; -import { Disclosure } from "../Disclosure"; +import { ComposerCollapsible } from "../ComposerCollapsible"; export type ExampleSentencesWrapperProps = { - children: React.ReactNode; + children: ReactNode; }; export const ExampleSentencesWrapper: FC = ( props, ) => { const { children } = props; - const t = useTranslations("components.ExampleSentences"); + + const t = useTranslations( + "components.Composer.ExampleSentences.ExampleSentencesWrapper", + ); return ( - {t("exampleSentences")}}> - {children} - + {children} ); }; diff --git a/src/components/Composer/HeaderGroup.tsx b/src/components/Composer/HeaderGroup.tsx deleted file mode 100644 index 2ab6b7c..0000000 --- a/src/components/Composer/HeaderGroup.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import clsx from "clsx"; -import { FC, ReactNode } from "react"; - -export type HeaderGroupProps = { - children: ReactNode; -}; - -export const HeaderGroup: FC = (props) => { - const { children } = props; - - return ( -
- {children} -
- ); -}; diff --git a/src/components/Composer/IconButton.tsx b/src/components/Composer/IconButton.tsx deleted file mode 100644 index 916577b..0000000 --- a/src/components/Composer/IconButton.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import clsx from "clsx"; -import { FC, ReactNode } from "react"; - -export type IconButtonProps = { - children: ReactNode; - title: string; - show?: boolean; - className?: string; - onClick: () => void | Promise; -}; - -export const IconButton: FC = (props) => { - const { children, className, title, show = true, onClick } = props; - - return ( - - ); -}; diff --git a/src/components/Composer/IconButtonGroup.tsx b/src/components/Composer/IconButtonGroup.tsx deleted file mode 100644 index 354207c..0000000 --- a/src/components/Composer/IconButtonGroup.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import clsx from "clsx"; -import { FC, ReactNode } from "react"; - -export type IconButtonGroupProps = { - className?: string; - start: ReactNode; - end?: ReactNode; -}; - -export const IconButtonGroup: FC = (props) => { - const { className, start, end } = props; - - return ( -
-
{start}
-
{end}
-
- ); -}; diff --git a/src/components/Composer/LanguageSelector.tsx b/src/components/Composer/LanguageSelector.tsx new file mode 100644 index 0000000..6823eda --- /dev/null +++ b/src/components/Composer/LanguageSelector.tsx @@ -0,0 +1,30 @@ +import { SegmentedControl } from "@radix-ui/themes"; +import { useTranslations } from "next-intl"; +import { FC, ReactNode } from "react"; + +type LanguageSelectorProps = { + name: string; + value: string; + legend: ReactNode; + className?: string; + onChange: (value: string) => void; +}; + +export const LanguageSelector: FC = (props) => { + const { name, value, onChange } = props; + + const t = useTranslations("components.Composer.LanguageSelector"); + + return ( + <> + + + {t("japanese")} + + {t("ainu")} + + + + + ); +}; diff --git a/src/components/Composer/LanguageSelector/LanguageSelector.tsx b/src/components/Composer/LanguageSelector/LanguageSelector.tsx deleted file mode 100644 index b64a009..0000000 --- a/src/components/Composer/LanguageSelector/LanguageSelector.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import clsx from "clsx"; -import { useTranslations } from "next-intl"; -import { ChangeEventHandler, FC, ReactNode } from "react"; - -import { LanguageSelectorOption } from "./LanguageSelectorOption"; - -type LanguageSelectorProps = { - name: string; - value: string; - legend: ReactNode; - className?: string; - onChange: ChangeEventHandler; -}; - -export const LanguageSelector: FC = (props) => { - const { name, value, legend, className, onChange } = props; - - const t = useTranslations("components.LanguageSelector"); - - return ( -
- {legend} - - - {t("japanese")} - - - - {t("ainu")} - -
- ); -}; diff --git a/src/components/Composer/LanguageSelector/LanguageSelectorOption.tsx b/src/components/Composer/LanguageSelector/LanguageSelectorOption.tsx deleted file mode 100644 index 9e9a1a0..0000000 --- a/src/components/Composer/LanguageSelector/LanguageSelectorOption.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import clsx from "clsx"; -import { ChangeEventHandler, FC, ReactNode } from "react"; - -export type LanguageSelectorOptionProps = { - name: string; - value: string; - checked: boolean; - defaultChecked?: boolean; - children: ReactNode; - onChange: ChangeEventHandler; -}; - -export const LanguageSelectorOption: FC = ( - props, -) => { - const { name, value, checked, defaultChecked, children, onChange } = props; - - return ( - - ); -}; diff --git a/src/components/Composer/LanguageSelector/index.ts b/src/components/Composer/LanguageSelector/index.ts deleted file mode 100644 index feb9f32..0000000 --- a/src/components/Composer/LanguageSelector/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./LanguageSelector"; diff --git a/src/components/Composer/Transcription.tsx b/src/components/Composer/Transcription.tsx index ad7d742..4987ad7 100644 --- a/src/components/Composer/Transcription.tsx +++ b/src/components/Composer/Transcription.tsx @@ -1,17 +1,16 @@ -import clsx from "clsx"; +import { Text } from "@radix-ui/themes"; import { ReactNode } from "react"; export type TranscriptionProps = { - children: ReactNode; - className?: string; + children?: ReactNode; }; export const Transcription = (props: TranscriptionProps) => { - const { children, className } = props; + const { children } = props; return ( -

- {children} -

+ + {children ?? "\u00A0"} + ); }; diff --git a/src/components/Composer/Translation.tsx b/src/components/Composer/Translation.tsx index 50a9694..14bdb6d 100644 --- a/src/components/Composer/Translation.tsx +++ b/src/components/Composer/Translation.tsx @@ -1,3 +1,4 @@ +import { Text } from "@radix-ui/themes"; import { useTranslations } from "next-intl"; import { FC } from "react"; @@ -9,22 +10,14 @@ export type TranslationProps = { export const Translation: FC = (props) => { const { value, pending } = props; - const t = useTranslations("components.Composer"); + const t = useTranslations("components.Composer.Translation"); if (pending) { - return ( - - {t("translation.loading")} - - ); + return {t("loading")}; } if (!value) { - return ( - - {t("translation.empty")} - - ); + return {t("empty")}; } return value; diff --git a/src/components/ContentInfo/ContentInfo.tsx b/src/components/ContentInfo/ContentInfo.tsx index a73af8e..1c187fa 100644 --- a/src/components/ContentInfo/ContentInfo.tsx +++ b/src/components/ContentInfo/ContentInfo.tsx @@ -1,4 +1,13 @@ -import Link from "next/link"; +import { + Flex, + Link, + Reset, + Section, + Separator, + Text, + VisuallyHidden, +} from "@radix-ui/themes"; +import NextLink from "next/link"; import { getTranslations } from "next-intl/server"; import { FC } from "react"; @@ -7,53 +16,62 @@ export const ContentInfo: FC = async () => { const titleId = "contentinfo-title"; return ( -
-

- {t("title")} -

- -
    -
  • - - Aynuitak - -
  • - -
  • - - アイヌイタㇰ - -
  • - -
  • - - 日本語 - -
  • -
- -

- Copyright - - © - - 2024 Ryō Igarashi, All rights reserved. -

-
+
+
+ +

{t("title")}

+
+ + + +
    +
  • + + + Aynu itak + + +
  • + + + +
  • + + + アイヌイタㇰ + + +
  • + + + +
  • + + + 日本語 + + +
  • +
+
+
+ + + Copyright + + © + + 2025 Ryō Igarashi, All rights reserved. + +
+
); }; diff --git a/src/components/Entry/Entry.tsx b/src/components/Entry/Entry.tsx new file mode 100644 index 0000000..32fdcfb --- /dev/null +++ b/src/components/Entry/Entry.tsx @@ -0,0 +1,129 @@ +import "./style.css"; + +import { + ExternalLinkIcon, + PersonIcon, + SewingPinIcon, +} from "@radix-ui/react-icons"; +import { + Box, + Flex, + Link, + Skeleton, + Text, + VisuallyHidden, +} from "@radix-ui/themes"; +import { useTranslations } from "next-intl"; +import { FC } from "react"; + +import { parse } from "@/utils/parse"; + +import { EntryDetailsDialog } from "./EntryDetailsDialog"; +import { Tag } from "./Tag"; + +export type EntryRootProps = { + text: string; + textHTML: string; + translation: string; + translationHTML: string; + book: string; + title: string; + url: string; + author: string | null; + dialect: string | null; +}; + +const EntryRoot: React.FC = (props) => { + const { textHTML, translationHTML, book, title, url, author, dialect } = + props; + + const t = useTranslations("components.Entry.Entry"); + + return ( +
+ + +
{parse(textHTML)}
+
+ +
{parse(translationHTML)}
+
+
+ + + + + {t("source")} + {book} + + + + + + + + {author && ( + + }>{author} + + )} + + {dialect && ( + + }> + {dialect} + + + )} + + + + +
+ ); +}; + +const EntrySkeleton: FC = () => { + return ( +
+ + + + irankarapte tanto sirpirka wa! + + + + + こんにちは。今日は天気がいいですね! + + + + + +
+ + アイヌ語アーカイブ + +
+
+
+ ); +}; + +export const Entry = { + Root: EntryRoot, + Skeleton: EntrySkeleton, +}; diff --git a/src/components/Entry/EntryDetailsDialog.tsx b/src/components/Entry/EntryDetailsDialog.tsx new file mode 100644 index 0000000..6fda39e --- /dev/null +++ b/src/components/Entry/EntryDetailsDialog.tsx @@ -0,0 +1,77 @@ +import { DotsHorizontalIcon } from "@radix-ui/react-icons"; +import { + Badge, + DataList, + Dialog, + IconButton, + Link, + Text, + VisuallyHidden, +} from "@radix-ui/themes"; +import { useTranslations } from "next-intl"; +import { FC } from "react"; + +export type EntryDetailsDialogProps = { + book: string; + title: string; + author: string | null; + dialect: string | null; + url: string; +}; + +export const EntryDetailsDialog: FC = (props) => { + const { book, title, author, dialect, url } = props; + + const t = useTranslations("components.Entry.EntryDetailsDialog"); + + return ( + + + + + {t("title")} + + + + + {t("title")} + + {t("description")} + + + + + {t("book")} + {book} + + + + {t("entryTitle")} + {title} + + + + {t("author")} + {author} + + + + {t("dialect")} + + {dialect} + + + + + {t("url")} + + + {url} + + + + + + + ); +}; diff --git a/src/components/Entry/Tag.tsx b/src/components/Entry/Tag.tsx new file mode 100644 index 0000000..f7a7cdd --- /dev/null +++ b/src/components/Entry/Tag.tsx @@ -0,0 +1,21 @@ +import { Flex, Text } from "@radix-ui/themes"; +import { FC, ReactNode } from "react"; + +export type TagProps = { + children: ReactNode; + icon?: ReactNode; + className?: string; +}; + +export const Tag: FC = (props) => { + const { icon, children } = props; + + return ( + + + {icon} + {children} + + + ); +}; diff --git a/src/components/Entry/index.ts b/src/components/Entry/index.ts new file mode 100644 index 0000000..402a1c3 --- /dev/null +++ b/src/components/Entry/index.ts @@ -0,0 +1 @@ +export * from "./Entry"; diff --git a/src/components/Entry/style.css b/src/components/Entry/style.css new file mode 100644 index 0000000..375d468 --- /dev/null +++ b/src/components/Entry/style.css @@ -0,0 +1,9 @@ +.entry em { + font-style: normal; + color: var(--accent-11); + background-color: var(--accent-4); +} + +.entry cite { + font-style: normal; +} diff --git a/src/mdx-components.tsx b/src/mdx-components.tsx index 9851ff6..834dc5b 100644 --- a/src/mdx-components.tsx +++ b/src/mdx-components.tsx @@ -1,3 +1,4 @@ +import { Heading, Link } from "@radix-ui/themes"; import type { MDXComponents } from "mdx/types"; // This file is required to use MDX in `app` directory. @@ -6,5 +7,14 @@ export function useMDXComponents(components: MDXComponents): MDXComponents { // Allows customizing built-in components, e.g. to add styling. // h1: ({ children }) =>

{children}

, ...components, + h1: ({ children }) => {children}, + h2: ({ children }) => {children}, + h3: ({ children }) => {children}, + h4: ({ children }) => {children}, + h5: ({ children }) => {children}, + h6: ({ children }) => {children}, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + a: ({ children, ...rest }) => {children}, }; } diff --git a/src/utils/parse.tsx b/src/utils/parse.tsx new file mode 100644 index 0000000..ce2196e --- /dev/null +++ b/src/utils/parse.tsx @@ -0,0 +1,18 @@ +import { + default as _parse, + DOMNode, + domToReact, + Element, +} from "html-react-parser"; + +const isElement = (node: DOMNode): node is Element => "name" in node; + +export function parse(html: string) { + return _parse(html, { + replace: (domNode) => { + if (isElement(domNode) && domNode.name === "em") { + return {domToReact(domNode.children as DOMNode[])}; + } + }, + }); +} diff --git a/tailwind.config.ts b/tailwind.config.ts deleted file mode 100644 index 68a1ba5..0000000 --- a/tailwind.config.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { Config } from "tailwindcss"; - -const config: Config = { - content: [ - "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", - "./src/components/**/*.{js,ts,jsx,tsx,mdx}", - "./src/app/**/*.{js,ts,jsx,tsx,mdx}", - "./.storybook/decorator.tsx", - ], - theme: { - extend: { - // https://nextjs.org/docs/pages/building-your-application/optimizing/fonts#with-tailwind-css - fontFamily: { - sans: [ - "var(--font-roboto)", - "Hiragino Kaku Gothic ProN", - "Hiragino Sans", - "Meiryo", - "ui-sans-serif", - "system-ui", - ], - yeseva: ["var(--font-yeseva-one)"], - }, - }, - }, - plugins: [ - require("tailwindcss-hero-patterns"), - require("@tailwindcss/typography"), - ], -}; -export default config;