diff --git a/.github/workflows/release-pr-automerge.yml b/.github/workflows/release-pr-automerge.yml new file mode 100644 index 0000000..7613d9d --- /dev/null +++ b/.github/workflows/release-pr-automerge.yml @@ -0,0 +1,78 @@ +name: Release PR Auto-merge + +on: + pull_request: + branches: + - main + types: + - opened + - synchronize + - reopened + - ready_for_review + +permissions: + contents: write + pull-requests: write + +jobs: + verify-and-enable-auto-merge: + name: Verify release version and changelog + if: >- + github.event.pull_request.user.login == 'nm-actions[bot]' && + github.event.pull_request.head.repo.full_name == github.repository && + github.event.pull_request.head.ref == 'release-please--branches--main--components--numeric-methods' && + !github.event.pull_request.draft + runs-on: ubuntu-latest + steps: + - name: Check out release PR + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + + - name: Set up Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Verify synchronized version bump and changelog + env: + BASE_SHA: ${{ github.event.pull_request.base.sha }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + run: | + set -euo pipefail + + release_version="$(bun run check:version --print)" + bun run check:version --changelog > /dev/null + base_version="$(git show "${BASE_SHA}:package.json" | jq -r '.version')" + + if [[ "${base_version}" == "${release_version}" ]]; then + echo "::error::Release PR did not change the version (still ${release_version})." + exit 1 + fi + + for file in package.json src-tauri/tauri.conf.json src-tauri/Cargo.toml; do + if git diff --quiet "${BASE_SHA}" "${HEAD_SHA}" -- "${file}"; then + echo "::error::Release PR did not update ${file}." + exit 1 + fi + done + + BASE_VERSION="${base_version}" RELEASE_VERSION="${release_version}" node <<'NODE' + const parse = (value) => { + const match = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.exec(value); + if (!match) throw new Error(`Invalid semantic version: ${value}`); + return match.slice(1, 4).map(Number); + }; + const [base, release] = [parse(process.env.BASE_VERSION), parse(process.env.RELEASE_VERSION)]; + const comparison = release.findIndex((part, index) => part !== base[index]); + if (comparison === -1 || release[comparison] < base[comparison]) { + throw new Error(`Release version ${process.env.RELEASE_VERSION} must be greater than ${process.env.BASE_VERSION}.`); + } + NODE + + - name: Enable auto-merge after required checks pass + env: + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ github.event.pull_request.number }} + run: gh pr merge "${PR_NUMBER}" --auto --squash --repo "${GITHUB_REPOSITORY}" diff --git a/app/(workspace)/learn/[slug]/page.tsx b/app/(workspace)/learn/[slug]/page.tsx index 5a172e4..c946e0b 100644 --- a/app/(workspace)/learn/[slug]/page.tsx +++ b/app/(workspace)/learn/[slug]/page.tsx @@ -1,7 +1,21 @@ import type { Metadata } from 'next'; import Link from 'next/link'; import { notFound } from 'next/navigation'; -import { ArrowLeft, ArrowUpRight } from 'lucide-react'; +import { + ArrowLeft, + ArrowUpRight, + BookOpen, + BookOpenText, + Calculator, + CheckCircle2, + HelpCircle, + Library, + Lightbulb, + ShieldAlert, + Sparkles, +} from 'lucide-react'; +import katex from 'katex'; +import 'katex/dist/katex.min.css'; import { LearningGuideJsonLd } from '@/components/seo/json-ld'; import { getLearningGuide, learningGuides } from '@/lib/learning-guides'; import { siteConfig } from '@/lib/config'; @@ -49,6 +63,17 @@ export async function generateMetadata({ }; } +function renderKatex(tex: string, displayMode = false): string { + try { + return katex.renderToString(tex, { + throwOnError: false, + displayMode, + }); + } catch { + return tex; + } +} + export default async function LearningGuidePage({ params }: LearningGuidePageProps) { const { slug } = await params; const guide = getLearningGuide(slug); @@ -59,111 +84,341 @@ export default async function LearningGuidePage({ params }: LearningGuidePagePro .slice(0, 3); return ( -
+
-
); } diff --git a/app/(workspace)/learn/page.tsx b/app/(workspace)/learn/page.tsx index e42f5ef..af6f128 100644 --- a/app/(workspace)/learn/page.tsx +++ b/app/(workspace)/learn/page.tsx @@ -1,117 +1,381 @@ import type { Metadata } from 'next'; import Link from 'next/link'; -import { ArrowRight, BookOpenText } from 'lucide-react'; -import { learningGuides } from '@/lib/learning-guides'; +import { + ArrowRight, + ArrowUpRight, + BookOpen, + BookOpenText, + Calculator, + CheckCircle2, + GraduationCap, + Library, + Lightbulb, + Sparkles, +} from 'lucide-react'; +import katex from 'katex'; +import 'katex/dist/katex.min.css'; +import { academicBibliography, learningGuides } from '@/lib/learning-guides'; export const metadata: Metadata = { - title: 'Sonli usullar qo‘llanmasi: formulalar va misollar', + title: 'Sonli usullar akademik qo‘llanmasi: formulalar, manbalar va misollar', description: - 'Sonli usullarni o‘zbek tilida o‘rganing: biseksiya, Nyuton, integrallash, interpolyatsiya va differensial tenglamalar bo‘yicha formulalar, ishlangan misollar va kalkulyatorlar.', + 'O‘zbekiston darsliklari va ilmiy adabiyotlar asosida sonli usullarni o‘rganing: biseksiya, Nyuton, Simpson, trapetsiya, Lagranj, Eyler, RK4 va haydash usuli bo‘yicha nazariya, formulalar va interaktiv kalkulyatorlar.', keywords: [ 'sonli usullar qo‘llanmasi', - 'sonli usullar misollar bilan', + 'hisoblash usullari kitoblar', + 'sonli usullar darsliklari', 'hisoblash matematikasi', - 'sonli usullar darslari', + 'sonli usullar formulalari', + 'sonli usullar adabiyotlar', ], alternates: { canonical: '/learn', }, openGraph: { type: 'website', - title: 'Sonli usullar qo‘llanmasi | Sonli Usullar', + title: 'Sonli usullar akademik qo‘llanmasi | Sonli Usullar', description: - 'O‘zbek tilidagi sonli usullar qo‘llanmasi: formulalar, ishlangan misollar va interaktiv hisoblash vositalari.', + 'O‘zbekiston oliy ta’lim darsliklari asosidagi sonli usullar nazariyasi, formulalari, ishlangan misollari va interaktiv hisoblash vositalari.', url: '/learn', siteName: 'Sonli Usullar', }, }; +function renderKatex(tex: string, displayMode = false): string { + try { + return katex.renderToString(tex, { + throwOnError: false, + displayMode, + }); + } catch { + return tex; + } +} + export default function LearningGuideIndexPage() { const guideGroups = [...new Set(learningGuides.map((guide) => guide.area))]; return ( -
-
-

- O‘zbekcha nazariya / formulalar / misollar -

+
+ {/* Hero Header */} +
+
+ + + + +
+

Sonli usullar qo‘llanmasi

-

- Sonli usullar matematik masalalarni kompyuterda taqribiy yechishga - yordam beradi. Quyidagi qo‘llanmalarda algoritmning g‘oyasi, formulasi, - qadam-baqadam misoli va qachon ishlatish mumkinligi sodda o‘zbek tilida - tushuntiriladi. -

-

- Mavzuni o‘qib bo‘lgach, shu sahifadagi interaktiv kalkulyatorda - parametrlarni o‘zgartirib natijaga ta’sirini tekshirishingiz mumkin. + +

+ Ushbu bo‘limda hisoblash matematikasining asosiy usullari O‘zbekiston oliy o‘quv yurtlari + darsliklari va ilmiy o‘quv qo‘llanmalari (Ismoilov, Irisqulov, Ismatullayev, Isroilov) + asosida tizimlashtirilgan. Har bir usul uchun nazariy teoremalar, formulalar, qadam-baqadam + algoritmlar va platformamizdagi hisoblash standartlari keltirilgan.

+ +
-
-

- Masalangizga mos usulni tanlang -

-

- Avval masala turini aniqlang: tenglama ildizini qidiryapsizmi, - integralni hisoblaysizmi yoki differensial tenglama yechyapsizmi? + {/* Masalangizga mos usulni tanlang */} +

+
+
+

+ Avval masala turini aniqlang: algebraik tenglama ildizini qidiryapsizmi, aniq integralni + hisoblaysizmi, matritsali sistemani yechasizmi yoki Koshi masalasini diskretlashtirasizmi?

-
    -
  • - Tenglama ildizi: ishonchli - oraliq uchun biseksiya, - hosila va yaxshi boshlang‘ich taxmin bo‘lsa Nyuton usuli. -
  • -
  • - Aniq integral: sodda baho - uchun trapetsiyalar, - silliq funksiya va juft bo‘linish uchun Simpson usuli. -
  • -
  • - Differensial tenglama:{' '} - boshlang‘ich va sodda qadamlar uchun Eyler, - yuqoriroq tartibli baho uchun RK4. -
  • -
  • - Jadval nuqtalari yoki sistema:{' '} - qiymatlar orasini to‘ldirish uchun Lagranj, - uch diagonalli sistemalar uchun haydash usuli. -
  • -
+ +
+
+ 1. Tenglama ildizlari +

Biseksiya va Nyuton usullari

+

+ Ishonchli va kafolatlangan oraliq uchun{' '} + biseksiya, + hosila mavjud bo‘lib tezkor kvadratik yaqinlashish kerak bo‘lsa{' '} + Nyuton (urinmalar) usuli. +

+
+ +
+ 2. Aniq integrallar +

Kvadraturalar (Trapetsiya va Simpson)

+

+ Tezkor va barqaror baho uchun{' '} + trapetsiyalar yoki{' '} + to‘g‘ri to‘rtburchaklar, + silliq funksiyalar va 4-tartibli yuqori aniqlik uchun{' '} + Simpson usuli. +

+
+ +
+ 3. Differensial tenglamalar +

Koshi masalasi (Eyler va RK4)

+

+ Birinchi tartibli qadamlar uchun{' '} + Eyler usuli, + muhandislik va ilmiy hisoblashlardagi standart yuqori aniqlik uchun esa{' '} + Runge-Kutta 4 (RK4). +

+
+ +
+ 4. Interpolyatsiya & Matritsalar +

Lagranj va Progonka usullari

+

+ Jadval nuqtalari orasini silliq to‘ldirish uchun{' '} + Lagranj ko‘phadi, + uch diagonalli katta sistemalarni O(n) da yechish uchun{' '} + haydash (progonka) usuli. +

+
+
- {guideGroups.map((area, groupIndex) => ( -
-
-
+
+ ))} +
+ ); } diff --git a/app/(workspace)/methods/newton-interpolation/page.tsx b/app/(workspace)/methods/newton-interpolation/page.tsx new file mode 100644 index 0000000..477e221 --- /dev/null +++ b/app/(workspace)/methods/newton-interpolation/page.tsx @@ -0,0 +1,68 @@ +import type { Metadata } from 'next'; +import { NewtonInterpolationMethod } from '@/components/newton-interpolation-method'; +import { MethodJsonLd } from '@/components/seo/json-ld'; +import { siteConfig } from '@/lib/config'; + +const route = '/methods/newton-interpolation'; +const pageTitle = 'Nyuton interpolyatsiyasi — bo‘lingan ayirmalar | Newton'; +const pageDescription = + 'Nyuton ko‘phadini hisoblang: bo‘lingan yoki chekli ayirmalar va P(x*) qiymati. Har bir formula hamda sonli qo‘yish qadam-baqadam ko‘rsatiladi.'; +const image = '/images/og/newton-interpolation.png'; + +export const metadata: Metadata = { + title: pageTitle, + description: pageDescription, + keywords: [ + 'Nyuton interpolyatsiyasi', + 'bo‘lingan ayirmalar', + 'Nyuton interpolyatsion ko‘phadi', + 'chekli ayirmalar usuli', + 'интерполяция Ньютона', + 'разделённые разности онлайн', + 'Newton interpolation calculator', + 'divided differences polynomial', + ], + alternates: { canonical: route }, + openGraph: { + type: 'article', + title: 'Newton Interpolation Calculator | Nyuton interpolyatsiyasi', + description: pageDescription, + url: `${siteConfig.url}${route}`, + siteName: siteConfig.name, + images: [{ url: image, width: 1200, height: 630, alt: 'Newton divided differences interpolation calculator' }], + }, + twitter: { + card: 'summary_large_image', + title: 'Newton Interpolation Calculator | Nyuton interpolyatsiyasi', + description: pageDescription, + images: [image], + }, +}; + +const breadcrumbSchema = { + '@context': 'https://schema.org', + '@type': 'BreadcrumbList', + itemListElement: [ + { '@type': 'ListItem', position: 1, name: siteConfig.name, item: siteConfig.url }, + { '@type': 'ListItem', position: 2, name: 'Nyuton interpolyatsiyasi', item: `${siteConfig.url}${route}` }, + ], +}; + +export default function NewtonInterpolationPage() { + return ( + <> + +