Skip to content
Merged
Show file tree
Hide file tree
Changes from 93 commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
75c286d
init!: cleanup everything
satnaing Apr 25, 2026
430bcad
chore: add Prettier configuration and dependencies
satnaing Apr 25, 2026
4901ca3
chore: add and configure eslint
satnaing Apr 25, 2026
40b4f33
chore: integrate TailwindCSS
satnaing Apr 25, 2026
5b3ecd3
feat: add initial configuration and social icons for AstroPaper theme
satnaing Apr 26, 2026
84dc9b3
feat: add theme styles and design tokens
satnaing Apr 26, 2026
81c1c5e
chore: configure Astro with sitemap, i18n, fonts, and tooling
satnaing Apr 26, 2026
503deec
feat: add base styles, dark variant, and typography
satnaing Apr 26, 2026
b5512e5
feat: add i18n types, English strings, and useTranslations helper
satnaing Apr 26, 2026
9942d61
feat: add client-side theme toggle script
satnaing Apr 26, 2026
b7f0fbe
feat: add BaseLayout and PostLayout
satnaing Apr 26, 2026
7e0e2a9
chore: replace scaffold index page with BaseLayout placeholder
satnaing Apr 26, 2026
2844b3d
feat: add Header component
satnaing Apr 26, 2026
dd3a781
feat: add Footer and Socials component
satnaing Apr 26, 2026
1004fbb
chore: install dayjs, slugify, zod, @astrojs/mdx and add MDX integration
satnaing May 1, 2026
00c6c0f
feat: add resolved config that applies defaults in one place
satnaing May 1, 2026
4bc06e1
feat: add content schema, blog path, and post utilities
satnaing May 1, 2026
9ae3a65
feat: add Datetime and Card components
satnaing May 1, 2026
b6ee929
refactor: switch layouts and components to resolved config
satnaing May 1, 2026
63cc1e1
feat: add home and footer i18n strings
satnaing May 1, 2026
3e41f58
feat: implement home page with hero, featured, and recent posts
satnaing May 1, 2026
5fe7403
feat: add pagination component
satnaing May 1, 2026
28e7b29
feat: add Breadcrumb component with locale support
satnaing May 1, 2026
04b4c46
feat: add Main component
satnaing May 1, 2026
cd3461b
refactor: update code formatting in Card.astro
satnaing May 1, 2026
cc620b8
feat: add posts page
satnaing May 1, 2026
5405686
fix: add missing @astrojs/mdx dependency
satnaing May 1, 2026
aba02e8
refactor: rename meta to pages in i18n
satnaing May 1, 2026
6ee0558
refactor: improve code formatting in Breadcrumb
satnaing May 1, 2026
86dd67d
refactor: destructure props in Main component for clarity
satnaing May 1, 2026
b030104
feat: add tag pages
satnaing May 1, 2026
6487427
feat: add About page
satnaing May 1, 2026
475a253
chore: update i18n configuration to use site language from config
satnaing May 1, 2026
de5fd93
feat: add Archives page
satnaing May 1, 2026
f455f67
feat: integrate Pagefind search functionality
satnaing May 1, 2026
2470564
feat: add dynamic Open Graph image generation for posts
satnaing May 2, 2026
eea6227
feat: add post detail page
satnaing May 2, 2026
9c84771
feat: add Shiki transformers
satnaing May 2, 2026
3d69abe
chore: remove unused edit link text
satnaing May 2, 2026
4c9046c
chore: update .gitignore to include generated Pagefind directory
satnaing May 2, 2026
8709e38
chore: update site URL in configuration to production link
satnaing May 2, 2026
dc7720d
chore: replace favicon and remove unused SVG assets, add new Open Gra…
satnaing May 2, 2026
4893629
feat: update site config with default values
satnaing May 2, 2026
edc8a24
feat: add default OG image path resolution
satnaing May 2, 2026
44876f0
fix: ensure edit post feature checks for enabled status correctly
satnaing May 2, 2026
dcfd2c4
feat: implement dynamic Open Graph image generation
satnaing May 2, 2026
b14a4fc
feat: add RSS feed generation functionality
satnaing May 2, 2026
10c338b
feat: add 404 Not Found page
satnaing May 2, 2026
e7c5e08
feat: add robots.txt generation for SEO optimization
satnaing May 2, 2026
cdf3fc5
refactor: change getSortedPosts to a named export
satnaing May 2, 2026
3eedeac
refactor: change postFilter to a named export
satnaing May 2, 2026
a610c20
refactor: rename BaseLayout to Layout
satnaing May 2, 2026
4bceb34
refactor: standardize locale handling across components
satnaing May 2, 2026
fc31855
refactor: update getPostsByGroupCondition location
satnaing May 2, 2026
5da6329
chore: remove unused Welcome component
satnaing May 2, 2026
af9109f
refactor(i18n): update links using getRelativeLocaleUrl
satnaing May 2, 2026
d5f1a58
refactor(i18n): add dynamic locale loading
satnaing May 2, 2026
dfcb885
fix: update language attribute to use current locale
satnaing May 2, 2026
ab891b5
fix: correct wording for updatedAt in post translations
satnaing May 2, 2026
210341f
fix: update layout titles to use correct translation keys for tags pages
satnaing May 2, 2026
4c15a7d
chore: use new colors for better DX and a11y
satnaing May 2, 2026
918c09c
feat: add underline icon for active icon nav
satnaing May 2, 2026
8671ba5
feat: add toc for markdown contents
satnaing May 3, 2026
ccc914c
refactor: remove unused feature flags in config
satnaing May 3, 2026
70b0c54
refactor(i18n): enhance locale handling and path management
satnaing May 3, 2026
9c59c51
fix: ts unused variable hint
satnaing May 3, 2026
51489f7
refactor: extract locale stripping logic into a util func
satnaing May 4, 2026
4947680
refactor(i18n): improve locale handling in tag pages
satnaing May 4, 2026
04afe2a
refactor: update post URL helper functions
satnaing May 4, 2026
ad4a091
refactor(i18n): replace pathWithBase with getRelativeLocaleUrl for lo…
satnaing May 4, 2026
e1bd3f4
refactor: rename fileWithBase to getAssetPath
satnaing May 4, 2026
36989c4
refactor: use runtime agnostic APIs for file paths
satnaing May 4, 2026
b73ab1b
refactor: use transition directive for heading transition
satnaing May 4, 2026
b3365ee
refactor: remove unused title element from tag page
satnaing May 4, 2026
0c66f89
fix: decouple ClientRouter from lightAndDarkMode flag
satnaing May 4, 2026
d37cc48
refactor: rename `postPaths.ts` to `getPostPaths.ts`
satnaing May 4, 2026
2e99e45
refactor: remove unused `minutesRead` string from post translations
satnaing May 4, 2026
1858f59
refactor: simplify AdjacentPostNav component by passing prevPost and …
satnaing May 4, 2026
468ecd8
refactor: remove unused code declaration
satnaing May 4, 2026
c50317e
docs: add existing blog posts
satnaing May 4, 2026
cf7be80
chore: update astro and @astrojs/check dependencies to latest versions
satnaing May 4, 2026
5366df3
build: use experimental svg optimizer
satnaing May 4, 2026
dcd5bd8
chore(repo): restore project meta files and Docker configs
satnaing May 4, 2026
ef4657e
refactor: update code formatting with Prettier
satnaing May 4, 2026
8ac7faa
docs: update README and docs
satnaing May 4, 2026
5b32e33
docs: add JSDoc comments to utility functions
satnaing May 4, 2026
8bbcae8
docs: add JSDoc comments to resolved config file
satnaing May 4, 2026
cff2493
fix(og): avoid double slashes when appending index.png
satnaing May 4, 2026
e7f6bbe
chore(ci): update Node.js version to 22.12.0 in CI workflow
satnaing May 4, 2026
434890d
feat: improve og image generation with Astro's getFontFileURL API (#632)
satnaing May 4, 2026
92c8a1a
fix(header): adjust icon button alignment in mobile
satnaing May 4, 2026
f119fbb
feat(docs): add ResponsiveTable to use it in MDX posts (#634)
satnaing May 10, 2026
660f07c
chore(ci): update Node.js version to 24 in CI workflow
satnaing May 16, 2026
1b12848
bump: upgrade Astro and dependencies
satnaing May 16, 2026
70f22e3
fix: remove redundant backUrl script bug
satnaing May 16, 2026
72e7555
fix(header): adjust button and icon alignment
satnaing May 16, 2026
25f168c
fix(a11y): improve muted-foreground color contrast
satnaing May 17, 2026
97fd240
docs: update predefined color schemes
satnaing May 17, 2026
d7f9a36
chore: support site verification env as fallback for googleVerification
satnaing May 17, 2026
cec5372
docs: add astro paper v6 updates in docs
satnaing May 17, 2026
8b92607
docs: add AstroPaper-v6.png in astro-paper-6 blog post
satnaing May 17, 2026
d564fd8
fix: update back-to-top button DOM placement (#641)
satnaing May 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:

strategy:
matrix:
node-version: [20]
node-version: ["24"]

steps:
- name: "☁️ Checkout repository"
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,4 @@ pnpm-debug.log*
.idea/

# pagefind

public/pagefind
6 changes: 4 additions & 2 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
!/.github
!tsconfig.json
!astro.config.ts
!.prettierrc.mjs
!package.json
!.prettierrc
!eslint.config.js
!README.md
!README.md

# Ignore MDX files
*.mdx
20 changes: 20 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"arrowParens": "avoid",
"semi": true,
"tabWidth": 2,
"printWidth": 80,
"singleQuote": false,
"jsxSingleQuote": false,
"trailingComma": "es5",
"bracketSpacing": true,
"endOfLine": "lf",
"plugins": ["prettier-plugin-astro", "prettier-plugin-tailwindcss"],
"overrides": [
{
"files": "*.astro",
"options": {
"parser": "astro"
}
}
]
}
22 changes: 0 additions & 22 deletions .prettierrc.mjs

This file was deleted.

102 changes: 44 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# AstroPaper 📄

![AstroPaper](public/astropaper-og.jpg)
![AstroPaper](public/default-og.jpg)
[![Figma](https://img.shields.io/badge/Figma-F24E1E?style=for-the-badge&logo=figma&logoColor=white)](https://www.figma.com/community/file/1356898632249991861)
![Typescript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white)
![GitHub](https://img.shields.io/github/license/satnaing/astro-paper?color=%232F3741&style=for-the-badge)
Expand All @@ -19,12 +19,15 @@ Read [the blog posts](https://astro-paper.pages.dev/posts/) or check [the README
- [x] responsive (mobile ~ desktops)
- [x] SEO-friendly
- [x] light & dark mode
- [x] fuzzy search
- [x] static search ([Pagefind](https://pagefind.app/))
- [x] draft posts & pagination
- [x] sitemap & rss feed
- [x] MDX support
- [x] collapsible table of contents
- [x] followed best practices
- [x] highly customizable
- [x] dynamic OG image generation for blog posts [#15](https://github.com/satnaing/astro-paper/pull/15) ([Blog Post](https://astro-paper.pages.dev/posts/dynamic-og-image-generation-in-astropaper-blog-posts/))
- [x] dynamic OG image generation for blog posts ([Blog Post](https://astro-paper.pages.dev/posts/dynamic-og-image-generation-in-astropaper-blog-posts/))
- [x] i18n ready

_Note: I've tested screen-reader accessibility of AstroPaper using **VoiceOver** on Mac and **TalkBack** on Android. I couldn't test all other screen-readers out there. However, accessibility enhancements in AstroPaper should be working fine on others as well._

Expand All @@ -43,57 +46,55 @@ Inside of AstroPaper, you'll see the following folders and files:
```bash
/
├── public/
│ ├── pagefind/ # auto-generated when build
│ ├── pagefind/ # auto-generated on build
│ ├── favicon.svg
│ └── astropaper-og.jpg
│ └── default-og.jpg
├── src/
│ ├── assets/
│ │ ├── icons/
│ │ └── images/
│ ├── components/
│ ├── data/
│ │ └── blog/
│ ├── content/
│ │ ├── pages/
│ │ │ └── about.md
│ │ └── posts/
│ │ └── some-blog-posts.md
│ ├── i18n/
│ ├── layouts/
│ ├── pages/
│ ├── scripts/
│ ├── styles/
│ ├── types/
│ ├── utils/
│ ├── config.ts
│ ├── constants.ts
│ ├── content.config.ts
│ ├── env.d.ts
│ └── remark-collapse.d.ts
│ └── content.config.ts
├── astro-paper.config.ts # user-defined configurations
└── astro.config.ts
```

Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.

Any static assets, like images, can be placed in the `public/` directory.

All blog posts are stored in `src/data/blog` directory.
All blog posts are stored in the `src/content/posts/` directory. You can organise posts into subdirectories — the subdirectory name becomes part of the post URL.

## 📖 Documentation

Documentation can be read in two formats\_ _markdown_ & _blog post_.

- Configuration - [markdown](src/data/blog/how-to-configure-astropaper-theme.md) | [blog post](https://astro-paper.pages.dev/posts/how-to-configure-astropaper-theme/)
- Add Posts - [markdown](src/data/blog/adding-new-post.md) | [blog post](https://astro-paper.pages.dev/posts/adding-new-posts-in-astropaper-theme/)
- Customize Color Schemes - [markdown](src/data/blog/customizing-astropaper-theme-color-schemes.md) | [blog post](https://astro-paper.pages.dev/posts/customizing-astropaper-theme-color-schemes/)
- Predefined Color Schemes - [markdown](src/data/blog/predefined-color-schemes.md) | [blog post](https://astro-paper.pages.dev/posts/predefined-color-schemes/)
- Configuration - [markdown](src/content/posts/how-to-configure-astropaper-theme.md) | [blog post](https://astro-paper.pages.dev/posts/how-to-configure-astropaper-theme/)
- Add Posts - [markdown](src/content/posts/adding-new-post.md) | [blog post](https://astro-paper.pages.dev/posts/adding-new-posts-in-astropaper-theme/)
- Customize Color Schemes - [markdown](src/content/posts/customizing-astropaper-theme-color-schemes.md) | [blog post](https://astro-paper.pages.dev/posts/customizing-astropaper-theme-color-schemes/)
- Predefined Color Schemes - [markdown](src/content/posts/predefined-color-schemes.md) | [blog post](https://astro-paper.pages.dev/posts/predefined-color-schemes/)

## 💻 Tech Stack

**Main Framework** - [Astro](https://astro.build/)
**Type Checking** - [TypeScript](https://www.typescriptlang.org/)
**Styling** - [TailwindCSS](https://tailwindcss.com/)
**UI/UX** - [Figma Design File](https://www.figma.com/community/file/1356898632249991861)
**Static Search** - [FuseJS](https://pagefind.app/)
**Static Search** - [Pagefind](https://pagefind.app/)
**Icons** - [Tablers](https://tabler-icons.io/)
**Code Formatting** - [Prettier](https://prettier.io/)
**Deployment** - [Cloudflare Pages](https://pages.cloudflare.com/)
**Illustration in About Page** - [https://freesvgillustration.com](https://freesvgillustration.com/)
**Linting** - [ESLint](https://eslint.org)
**Linting** - [ESLint](https://eslint.org)
**Dynamic OG images** - [Satori](https://github.com/vercel/satori) + [Sharp](https://sharp.pixelplumbing.com/) + [Astro Fonts](https://docs.astro.build/en/guides/fonts/)

## 👨🏻‍💻 Running Locally

Expand All @@ -120,26 +121,21 @@ Then start the project by running the following commands:
pnpm install

# start running the project
pnpm run dev
```

As an alternative approach, if you have Docker installed, you can use Docker to run this project locally. Here's how:

```bash
# Build the Docker image
docker build -t astropaper .

# Run the Docker container
docker run -p 4321:80 astropaper
pnpm dev
```

## Google Site Verification (optional)

You can easily add your [Google Site Verification HTML tag](https://support.google.com/webmasters/answer/9008080#meta_tag_verification&zippy=%2Chtml-tag) in AstroPaper using an environment variable. This step is optional. If you don't add the following environment variable, the google-site-verification tag won't appear in the HTML `<head>` section.
You can add your [Google Site Verification HTML tag](https://support.google.com/webmasters/answer/9008080#meta_tag_verification&zippy=%2Chtml-tag) by setting `site.googleVerification` in `astro-paper.config.ts`:

```bash
# in your environment variable file (.env)
PUBLIC_GOOGLE_SITE_VERIFICATION=your-google-site-verification-value
```ts file="astro-paper.config.ts"
export default defineAstroPaperConfig({
site: {
// ...
googleVerification: "your-google-site-verification-value",
},
// ...
});
```

> See [this discussion](https://github.com/satnaing/astro-paper/discussions/334#discussioncomment-10139247) for adding AstroPaper to the Google Search Console.
Expand All @@ -148,32 +144,22 @@ PUBLIC_GOOGLE_SITE_VERIFICATION=your-google-site-verification-value

All commands are run from the root of the project, from a terminal:

> **_Note!_** For `Docker` commands we must have it [installed](https://docs.docker.com/engine/install/) in your machine.

| Command | Action |
| :----------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- |
| `pnpm install` | Installs dependencies |
| `pnpm run dev` | Starts local dev server at `localhost:4321` |
| `pnpm run build` | Build your production site to `./dist/` |
| `pnpm run preview` | Preview your build locally, before deploying |
| `pnpm run format:check` | Check code format with Prettier |
| `pnpm run format` | Format codes with Prettier |
| `pnpm run sync` | Generates TypeScript types for all Astro modules. [Learn more](https://docs.astro.build/en/reference/cli-reference/#astro-sync). |
| `pnpm run lint` | Lint with ESLint |
| `docker compose up -d` | Run AstroPaper on docker, You can access with the same hostname and port informed on `dev` command. |
| `docker compose run app npm install` | You can run any command above into the docker container. |
| `docker build -t astropaper .` | Build Docker image for AstroPaper. |
| `docker run -p 4321:80 astropaper` | Run AstroPaper on Docker. The website will be accessible at `http://localhost:4321`. |

> **_Warning!_** Windows PowerShell users may need to install the [concurrently package](https://www.npmjs.com/package/concurrently) if they want to [run diagnostics](https://docs.astro.build/en/reference/cli-reference/#astro-check) during development (`astro check --watch & astro dev`). For more info, see [this issue](https://github.com/satnaing/astro-paper/issues/113).
| Command | Action |
| :--------------- | :------------------------------------------------------------------------------------------------------------------------------- |
| `pnpm install` | Installs dependencies |
| `pnpm dev` | Starts local dev server at `localhost:4321` |
| `pnpm build` | Type-checks, builds the site, runs Pagefind indexing, and copies the index to `public/pagefind/` |
| `pnpm preview` | Preview your build locally, before deploying |
| `pnpm sync` | Generates TypeScript types for all Astro modules. [Learn more](https://docs.astro.build/en/reference/cli-reference/#astro-sync). |
| `pnpm astro ...` | Run CLI commands like `astro add`, `astro check` |

## ✨ Feedback & Suggestions

If you have any suggestions/feedback, you can contact me via [my email](mailto:contact@satnaing.dev). Alternatively, feel free to open an issue if you find bugs or want to request new features.
If you have any suggestions/feedback, you can contact me via [my email](mailto:satnaingdev+astropaper@gmail.com). Alternatively, feel free to open an issue if you find bugs or want to request new features.

## 📜 License

Licensed under the MIT License, Copyright © 2025
Licensed under the MIT License, Copyright © 2026

---

Expand Down
45 changes: 45 additions & 0 deletions astro-paper.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { defineAstroPaperConfig } from "./src/types/config";

export default defineAstroPaperConfig({
site: {
url: "https://astro-paper.pages.dev/",
title: "AstroPaper",
description: "A minimal, responsive and SEO-friendly Astro blog theme.",
author: "Sat Naing",
profile: "https://satna.ing",
ogImage: "default-og.jpg",
lang: "en",
timezone: "Asia/Bangkok",
dir: "ltr",
},
posts: {
perPage: 4,
perIndex: 4,
scheduledPostMargin: 15 * 60 * 1000,
},
features: {
lightAndDarkMode: true,
dynamicOgImage: true,
showArchives: true,
showBackButton: true,
editPost: {
enabled: true,
url: "https://github.com/satnaing/astro-paper/edit/main/",
},
search: "pagefind",
},
socials: [
{ name: "github", url: "https://github.com/satnaing/astro-paper" },
{ name: "x", url: "https://x.com/username" },
{ name: "linkedin", url: "https://www.linkedin.com/in/username/" },
{ name: "mail", url: "mailto:yourmail@gmail.com" },
],
shareLinks: [
{ name: "whatsapp", url: "https://wa.me/?text=" },
{ name: "facebook", url: "https://www.facebook.com/sharer.php?u=" },
{ name: "x", url: "https://x.com/intent/post?url=" },
{ name: "telegram", url: "https://t.me/share/url?url=" },
{ name: "pinterest", url: "https://pinterest.com/pin/create/button/?url=" },
{ name: "mail", url: "mailto:?subject=See%20this%20post&body=" },
],
});
61 changes: 25 additions & 36 deletions astro.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { defineConfig, envField, fontProviders } from "astro/config";
import { defineConfig, fontProviders, svgoOptimizer } from "astro/config";
import tailwindcss from "@tailwindcss/vite";
import mdx from "@astrojs/mdx";
import sitemap from "@astrojs/sitemap";
import remarkToc from "remark-toc";
import remarkCollapse from "remark-collapse";
Expand All @@ -9,20 +10,27 @@ import {
transformerNotationWordHighlight,
} from "@shikijs/transformers";
import { transformerFileName } from "./src/utils/transformers/fileName";
import { SITE } from "./src/config";
import config from "./astro-paper.config";

// https://astro.build/config
export default defineConfig({
site: SITE.website,
site: config.site.url,
integrations: [
mdx(),
sitemap({
filter: page => SITE.showArchives || !page.endsWith("/archives"),
filter: page =>
config.features?.showArchives !== false || !page.endsWith("/archives/"),
}),
],
i18n: {
locales: ["en"],
defaultLocale: "en",
routing: {
prefixDefaultLocale: false,
},
},
markdown: {
remarkPlugins: [remarkToc, [remarkCollapse, { test: "Table of contents" }]],
shikiConfig: {
// For more themes, visit https://shiki.style/themes
themes: { light: "min-light", dark: "night-owl" },
defaultColor: false,
wrap: false,
Expand All @@ -35,39 +43,20 @@ export default defineConfig({
},
},
vite: {
// eslint-disable-next-line
// @ts-ignore
// This will be fixed in Astro 6 with Vite 7 support
// See: https://github.com/withastro/astro/issues/14030
plugins: [tailwindcss()],
optimizeDeps: {
exclude: ["@resvg/resvg-js"],
},
},
image: {
responsiveStyles: true,
layout: "constrained",
},
env: {
schema: {
PUBLIC_GOOGLE_SITE_VERIFICATION: envField.string({
access: "public",
context: "client",
optional: true,
}),
fonts: [
{
name: "Google Sans Code",
cssVariable: "--font-google-sans-code",
provider: fontProviders.google(),
fallbacks: ["monospace"],
weights: [300, 400, 500, 600, 700],
styles: ["normal", "italic"],
formats: ["woff", "ttf"],
},
},
],
experimental: {
preserveScriptOrder: true,
fonts: [
{
name: "Google Sans Code",
cssVariable: "--font-google-sans-code",
provider: fontProviders.google(),
fallbacks: ["monospace"],
weights: [300, 400, 500, 600, 700],
styles: ["normal", "italic"],
},
],
svgOptimizer: svgoOptimizer(),
},
});
Loading
Loading