diff --git a/app/about/ai/content.md b/app/about/ai/content.md new file mode 100644 index 00000000..7cdd249b --- /dev/null +++ b/app/about/ai/content.md @@ -0,0 +1,29 @@ +# AI質問機能について + +my.code(); では、学習をサポートするための AI アシスタント機能を提供しています。 +ご利用前に以下の事項をご確認ください。 + +## AIの回答の正確性について + +**AIの回答は誤りを含む場合があります。** + +AIは非常に自信を持って誤った情報を回答することがあります。 +AIの回答を鵜呑みにせず、必ず自分自身で内容を確認するようにしてください。 + +## 免責事項 + +AI質問機能の利用によって生じたいかなる損害についても、ut.code(); は責任を負いません。 + +## 使用しているAIモデルについて + +AIモデルへのアクセスには [OpenRouter](https://openrouter.ai/) を使用しています。 +使用するモデルは ut.code(); が選択しており、ユーザーが変更することはできません。 +また、使用するモデルは予告なく変更される場合があります。 + +## データの取り扱いについて + +**入力データの利用について** + +- AIへの質問内容やこのサイトで実行したコードのデータは、AIモデルのプロバイダーによって学習データとして利用される可能性があります。 +- また、サービス品質の向上等を目的として、ut.code(); のメンバーが閲覧可能な形でサイトに保存されます。 +- **個人情報や機密情報は入力しないようにしてください。** diff --git a/app/about/ai/page.tsx b/app/about/ai/page.tsx new file mode 100644 index 00000000..d335a252 --- /dev/null +++ b/app/about/ai/page.tsx @@ -0,0 +1,16 @@ +import { Metadata } from "next"; +import { StyledMarkdown } from "@/markdown/markdown"; +import content from "./content.md?raw"; + +export const metadata: Metadata = { + title: "AI質問機能について", + description: "my.code(); のAI質問機能の詳細と利用上の注意事項について説明します。", +}; + +export default function AiPage() { + return ( +
+ +
+ ); +} diff --git a/app/about/license/ThirdPartyLicenses.tsx b/app/about/license/ThirdPartyLicenses.tsx new file mode 100644 index 00000000..8269abb0 --- /dev/null +++ b/app/about/license/ThirdPartyLicenses.tsx @@ -0,0 +1,96 @@ +"use client"; + +import { StyledSyntaxHighlighter } from "@/markdown/styledSyntaxHighlighter"; +import { langConstants } from "@my-code/runtime/languages"; +import { useState } from "react"; + +export interface LicenseEntry { + name: string; + version: string; + author?: string; + repository?: string; + source?: string; + license: string; + licenseText?: string; +} + +export function ThirdPartyLicenses({ licenses }: { licenses: LicenseEntry[] }) { + const [expanded, setExpanded] = useState(null); + + return ( +
+ {licenses.map((pkg) => { + const key = `${pkg.name}@${pkg.version}`; + const isOpen = expanded === key; + let repositoryURL: string | undefined = undefined; + if (pkg.repository?.startsWith("http")) { + repositoryURL = pkg.repository; + } else if (pkg.repository?.startsWith("git+http")) { + repositoryURL = pkg.repository?.slice(4); + } else if (pkg.repository?.startsWith("git@")) { + repositoryURL = + "https://" + + pkg.repository + .slice(4) + .replace(":", "/") + .replace(/\.git$/, ""); + } else if ( + pkg.repository && + /github:[\w-]+\/[\w-]+/.test(pkg.repository) + ) { + repositoryURL = `https://github.com/${pkg.repository.slice(7)}`; + } else if (pkg.repository && /[\w-]+\/[\w-]+/.test(pkg.repository)) { + // assume github username/repository + repositoryURL = `https://github.com/${pkg.repository}`; + } else { + // fallback to source url + // repositoryURL = pkg.source ?? ""; + } + return ( +
+ setExpanded(isOpen ? null : key)} + /> +
+ {pkg.name} + v{pkg.version} + + {pkg.license} + +
+
+ {pkg.author && ( +

+ Author: + {pkg.author} +

+ )} + {repositoryURL && ( +

+ Repository: + + {repositoryURL} + +

+ )} + {pkg.licenseText && ( + + {pkg.licenseText} + + )} +
+
+ ); + })} +
+ ); +} diff --git a/app/about/license/page.tsx b/app/about/license/page.tsx new file mode 100644 index 00000000..5d5515f5 --- /dev/null +++ b/app/about/license/page.tsx @@ -0,0 +1,60 @@ +import { Metadata } from "next"; +import licenseText from "@/../LICENSE?raw"; +import { LicenseEntry, ThirdPartyLicenses } from "./ThirdPartyLicenses"; +import { isCloudflare } from "@/lib/detectCloudflare"; +import { getCloudflareContext } from "@opennextjs/cloudflare"; +import { readFile } from "node:fs/promises"; +import { join } from "node:path"; +import { StyledMarkdown } from "@/markdown/markdown"; + +export const metadata: Metadata = { + title: "ライセンス", + description: + "my.code(); のライセンスおよび使用しているサードパーティライブラリのライセンス情報です。", +}; + +const content = ` +# ライセンス + +## my.code(); のライセンス + +my.code(); のソースコードは MIT ライセンスのもとで公開されています。 + +\`\`\` +${licenseText} +\`\`\` + +## サードパーティライブラリのライセンス + +my.code(); は以下のオープンソースライブラリを使用しています。 +`; + +export default async function LicensePage() { + let licenses: LicenseEntry[]; + if (isCloudflare()) { + const cfAssets = getCloudflareContext().env.ASSETS; + const res = await cfAssets!.fetch( + `https://assets.local/_next/static/oss-licenses.json` + ); + licenses = await res.json(); + } else { + licenses = JSON.parse( + await readFile( + join( + process.cwd(), + process.env.NODE_ENV === "development" + ? ".next/dev/static/oss-licenses.json" + : ".next/static/oss-licenses.json" + ), + "utf-8" + ) + ); + } + + return ( +
+ + +
+ ); +} diff --git a/app/about/runtime/content.md b/app/about/runtime/content.md new file mode 100644 index 00000000..fadafdb0 --- /dev/null +++ b/app/about/runtime/content.md @@ -0,0 +1,53 @@ +# コード実行環境について + +my.code(); では、プログラミング言語ごとに異なる仕組みでコードを実行しています。 +以下にそれぞれの言語の実行環境について説明します。 + +## ブラウザ内で実行される言語 + +以下の言語は、サーバーへの通信を行わず、すべてお使いのブラウザ内で実行されます。 +そのため、インターネット接続が不安定な環境でも、一度ページが読み込まれれば実行可能です。 + +### Python + +Python は [Pyodide](https://pyodide.org/) を使用して実行されます。 +Pyodide は CPython(Python の公式実装)を WebAssembly にコンパイルしたものです。 +Python コードはブラウザ内の Web Worker 上で動作するため、ページの描画をブロックせずに実行できます。 + +### Ruby + +Ruby は [ruby.wasm](https://ruby.github.io/ruby.wasm/) を使用して実行されます。 +ruby.wasm は公式の CRuby を WebAssembly にコンパイルしたものです。 +Python と同様に Web Worker 上で動作します。 + +### JavaScript + +JavaScript はブラウザ自身の JavaScript エンジンを利用して実行されます。 +コードは安全なサンドボックス環境内で評価されます。 + +### TypeScript + +TypeScript は [@typescript/vfs](https://www.npmjs.com/package/@typescript/vfs) を使用してブラウザ内でコンパイルされ、その後 JavaScript と同じ仕組みで実行されます。 + +## 外部サービスを利用して実行される言語 + +以下の言語は、外部のコンパイル・実行サービス([Wandbox](https://wandbox.org/))の API を通じて実行されます。 +コードはサーバーに送信されてコンパイル・実行され、結果がブラウザに返されます。 +そのため、実行にはインターネット接続が必要です。 +また、入力したコードが Wandbox のサーバーに送信されることをご了承ください。 + +### C++ + +Wandbox の g++ (GNU C++ Compiler) を使用してコンパイル・実行されます。 +最新の安定版コンパイラが使用され、Boost ライブラリも利用可能です。 +実行時にエラーが発生した場合は、スタックトレースが表示されます。 + +### Rust + +Wandbox の rustc (Rust コンパイラ) を使用してコンパイル・実行されます。 +最新版のコンパイラが使用されます。 + +--- + +外部サービスを利用して実行される言語(C++・Rust)では、入力したコードが外部サーバーに送信されます。 +個人情報や機密情報を含むコードは入力しないようにしてください。 diff --git a/app/about/runtime/page.tsx b/app/about/runtime/page.tsx new file mode 100644 index 00000000..4e9f8507 --- /dev/null +++ b/app/about/runtime/page.tsx @@ -0,0 +1,16 @@ +import { Metadata } from "next"; +import { StyledMarkdown } from "@/markdown/markdown"; +import content from "./content.md?raw"; + +export const metadata: Metadata = { + title: "コード実行環境について", + description: "my.code(); で使用しているコード実行環境の仕組みを説明します。", +}; + +export default function RuntimePage() { + return ( +
+ +
+ ); +} diff --git a/app/footer.tsx b/app/footer.tsx index 1227d5fd..234d9858 100644 --- a/app/footer.tsx +++ b/app/footer.tsx @@ -1,3 +1,5 @@ +import Link from "next/link"; + export function Footer() { return (