Repository: any-tdf/stdf
Files analyzed: 825

Estimated tokens: 755.0k

Directory structure:
└── any-tdf-stdf/
    ├── README.md
    ├── CODE_OF_CONDUCT.md
    ├── LICENSE
    ├── README_CN.md
    ├── SECURITY.md
    ├── docs/
    │   ├── mds/
    │   │   ├── components/
    │   │   │   ├── actionSheet/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── asyncPicker/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── avatar/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── badge/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── bottomSheet/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── button/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── calendar/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── cell/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── checkbox/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── dialog/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── divider/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── grids/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── icon/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── indexBar/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── input/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── loading/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── mask/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── modal/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── navBar/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── noticeBar/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── numKeyboard/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── pagination/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── picker/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── placeholder/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── popup/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── progress/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── progressLoop/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── radio/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── rate/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── skeleton/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── slider/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── stepper/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── steps/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── swiper/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── switch/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── tabBar/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── tabs/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   ├── timePicker/
    │   │   │   │   ├── api.md
    │   │   │   │   ├── api_en.md
    │   │   │   │   ├── FAQ.md
    │   │   │   │   ├── FAQ_en.md
    │   │   │   │   ├── guide.md
    │   │   │   │   ├── guide_en.md
    │   │   │   │   ├── version.md
    │   │   │   │   └── version_en.md
    │   │   │   └── toast/
    │   │   │       ├── api.md
    │   │   │       ├── api_en.md
    │   │   │       ├── FAQ.md
    │   │   │       ├── FAQ_en.md
    │   │   │       ├── guide.md
    │   │   │       ├── guide_en.md
    │   │   │       ├── version.md
    │   │   │       └── version_en.md
    │   │   └── guide/
    │   │       ├── about.md
    │   │       ├── about_en.md
    │   │       ├── changelog.md
    │   │       ├── changelog_en.md
    │   │       ├── compatibility.md
    │   │       ├── compatibility_en.md
    │   │       ├── contribution.md
    │   │       ├── contribution_en.md
    │   │       ├── faq.md
    │   │       ├── faq_en.md
    │   │       ├── future.md
    │   │       ├── future_en.md
    │   │       ├── icon.md
    │   │       ├── icon_en.md
    │   │       ├── internation.md
    │   │       ├── internation_en.md
    │   │       ├── milestone.md
    │   │       ├── milestone_en.md
    │   │       ├── quickStart.md
    │   │       ├── quickStart_en.md
    │   │       ├── theme.md
    │   │       ├── theme_en.md
    │   │       ├── vscode.md
    │   │       └── vscode_en.md
    │   └── site/
    │       ├── eslint.config.js
    │       ├── package.json
    │       ├── svelte.config.js
    │       ├── tsconfig.json
    │       ├── vite.config.ts
    │       ├── .prettierignore
    │       ├── .prettierrc
    │       ├── scripts/
    │       │   └── env.js
    │       ├── src/
    │       │   ├── app.css
    │       │   ├── app.d.ts
    │       │   ├── app.html
    │       │   ├── global.d.ts
    │       │   ├── store.ts
    │       │   ├── data/
    │       │   │   ├── color.ts
    │       │   │   ├── menuList.ts
    │       │   │   └── themes/
    │       │   │       ├── aqua.ts
    │       │   │       ├── azuper.ts
    │       │   │       ├── azurePink.ts
    │       │   │       ├── camelliaRed.ts
    │       │   │       ├── chameleon.ts
    │       │   │       ├── citrus.ts
    │       │   │       ├── greenJade.ts
    │       │   │       ├── index.ts
    │       │   │       ├── kleinH.ts
    │       │   │       ├── lavender.ts
    │       │   │       ├── nintendo.ts
    │       │   │       ├── skybloom.ts
    │       │   │       ├── smartLive.ts
    │       │   │       └── tealMedley.ts
    │       │   ├── lib/
    │       │   │   ├── index.ts
    │       │   │   ├── clis/
    │       │   │   │   └── Clis.svelte
    │       │   │   ├── cmdk/
    │       │   │   │   └── CmdK.svelte
    │       │   │   ├── colorCard/
    │       │   │   │   └── ColorCard.svelte
    │       │   │   ├── fund/
    │       │   │   │   └── Fund.svelte
    │       │   │   ├── header/
    │       │   │   │   └── Header.svelte
    │       │   │   ├── menu/
    │       │   │   │   └── Menu.svelte
    │       │   │   ├── modeSwitch/
    │       │   │   │   ├── darkMode.ts
    │       │   │   │   └── ModeSwitch.svelte
    │       │   │   ├── symbol/
    │       │   │   ├── tab/
    │       │   │   │   └── Tab.svelte
    │       │   │   └── themeSwitch/
    │       │   │       └── ThemeSwitch.svelte
    │       │   ├── routes/
    │       │   │   ├── +error.svelte
    │       │   │   ├── +layout.svelte
    │       │   │   ├── +layout.ts
    │       │   │   ├── +page.svelte
    │       │   │   ├── components/
    │       │   │   │   ├── +page.svelte
    │       │   │   │   ├── Api.svelte
    │       │   │   │   ├── Component.svelte
    │       │   │   │   ├── FAQ.svelte
    │       │   │   │   ├── Guide.svelte
    │       │   │   │   └── Version.svelte
    │       │   │   └── guide/
    │       │   │       ├── +layout.svelte
    │       │   │       ├── +page.svelte
    │       │   │       ├── Create.svelte
    │       │   │       ├── about/
    │       │   │       │   └── +page.svelte
    │       │   │       ├── changelog/
    │       │   │       │   └── +page.svelte
    │       │   │       ├── color/
    │       │   │       │   ├── +page.svelte
    │       │   │       │   └── Color.svelte
    │       │   │       ├── compatibility/
    │       │   │       │   └── +page.svelte
    │       │   │       ├── contribution/
    │       │   │       │   └── +page.svelte
    │       │   │       ├── create/
    │       │   │       │   └── +page.svelte
    │       │   │       ├── faq/
    │       │   │       │   └── +page.svelte
    │       │   │       ├── future/
    │       │   │       │   └── +page.svelte
    │       │   │       ├── generator/
    │       │   │       │   ├── +page.svelte
    │       │   │       │   ├── Calendar.svelte
    │       │   │       │   └── GeneratorPreview.svelte
    │       │   │       ├── icon/
    │       │   │       │   └── +page.svelte
    │       │   │       ├── icon-plugin/
    │       │   │       │   └── +page.svelte
    │       │   │       ├── internation/
    │       │   │       │   └── +page.svelte
    │       │   │       ├── logo/
    │       │   │       │   └── +page.svelte
    │       │   │       ├── md/
    │       │   │       │   └── +page.svelte
    │       │   │       ├── milestone/
    │       │   │       │   └── +page.svelte
    │       │   │       ├── shortkey/
    │       │   │       │   └── +page.svelte
    │       │   │       ├── theme/
    │       │   │       │   └── +page.svelte
    │       │   │       └── vscode/
    │       │   │           └── +page.svelte
    │       │   └── utils/
    │       │       ├── code-group-svg-data.js
    │       │       └── index.ts
    │       └── static/
    │           ├── assets/
    │           │   ├── favicon_logo/
    │           │   │   └── site.webmanifest
    │           │   ├── favicon_logo_dark/
    │           │   │   └── site.webmanifest
    │           │   ├── fonts/
    │           │   │   └── JetBrainsMono-Regular.woff2
    │           │   ├── fund/
    │           │   ├── images/
    │           │   │   ├── guide/
    │           │   │   └── home/
    │           │   ├── qr/
    │           │   ├── svg/
    │           │   └── vscode/
    │           └── logo/
    ├── packages/
    │   ├── create-stdf/
    │   │   ├── README.md
    │   │   ├── index.js
    │   │   ├── package.json
    │   │   ├── README_CN.md
    │   │   ├── rollup.config.js
    │   │   ├── scripts/
    │   │   │   └── update.js
    │   │   ├── src/
    │   │   │   ├── index.js
    │   │   │   └── lang.js
    │   │   └── templates/
    │   │       ├── skt/
    │   │       │   ├── README.md
    │   │       │   ├── eslint.config.js
    │   │       │   ├── jsconfig.json
    │   │       │   ├── package.json
    │   │       │   ├── svelte.config.js
    │   │       │   ├── vite.config.js
    │   │       │   ├── .npmrc
    │   │       │   ├── .prettierignore
    │   │       │   ├── .prettierrc
    │   │       │   ├── src/
    │   │       │   │   ├── app.css
    │   │       │   │   ├── app.d.ts
    │   │       │   │   ├── app.html
    │   │       │   │   ├── data/
    │   │       │   │   │   └── nintendo.ts
    │   │       │   │   ├── lib/
    │   │       │   │   │   ├── svgs/
    │   │       │   │   │   │   ├── Heroicons/
    │   │       │   │   │   │   ├── IconPark/
    │   │       │   │   │   │   └── Remix/
    │   │       │   │   │   └── symbol/
    │   │       │   │   └── routes/
    │   │       │   │       ├── +layout.js
    │   │       │   │       ├── +layout.svelte
    │   │       │   │       ├── +page.svelte
    │   │       │   │       ├── Counter.svelte
    │   │       │   │       └── about/
    │   │       │   │           └── +page.svelte
    │   │       │   └── static/
    │   │       └── sktt/
    │   │           ├── README.md
    │   │           ├── eslint.config.js
    │   │           ├── package.json
    │   │           ├── svelte.config.js
    │   │           ├── tsconfig.json
    │   │           ├── vite.config.ts
    │   │           ├── .npmrc
    │   │           ├── .prettierignore
    │   │           ├── .prettierrc
    │   │           ├── src/
    │   │           │   ├── app.css
    │   │           │   ├── app.d.ts
    │   │           │   ├── app.html
    │   │           │   ├── data/
    │   │           │   │   └── nintendo.ts
    │   │           │   ├── lib/
    │   │           │   │   ├── svgs/
    │   │           │   │   │   ├── Heroicons/
    │   │           │   │   │   ├── IconPark/
    │   │           │   │   │   └── Remix/
    │   │           │   │   └── symbol/
    │   │           │   └── routes/
    │   │           │       ├── +layout.js
    │   │           │       ├── +layout.svelte
    │   │           │       ├── +page.svelte
    │   │           │       ├── Counter.svelte
    │   │           │       └── about/
    │   │           │           └── +page.svelte
    │   │           └── static/
    │   ├── rollup-plugin-md-ts/
    │   │   ├── README.md
    │   │   ├── eslint.config.js
    │   │   ├── package.json
    │   │   ├── README_CN.md
    │   │   ├── rollup.config.ts
    │   │   ├── tsconfig.json
    │   │   ├── .prettierrc
    │   │   └── src/
    │   │       └── index.ts
    │   ├── rollup-plugin-stdf-icon/
    │   │   ├── README.md
    │   │   ├── package.json
    │   │   ├── README_CN.md
    │   │   ├── rollup.config.js
    │   │   ├── tsconfig.json
    │   │   ├── src/
    │   │   │   └── index.ts
    │   │   └── test/
    │   │       ├── index.js
    │   │       └── icons/
    │   ├── stdf/
    │   │   ├── eslint.config.js
    │   │   ├── package.json
    │   │   ├── svelte.config.js
    │   │   ├── tsconfig.json
    │   │   ├── vite.config.ts
    │   │   ├── .prettierignore
    │   │   ├── .prettierrc
    │   │   ├── src/
    │   │   │   ├── app.css
    │   │   │   ├── app.d.ts
    │   │   │   ├── app.html
    │   │   │   ├── assets/
    │   │   │   │   └── svgs/
    │   │   │   ├── data/
    │   │   │   │   ├── aphorisms.ts
    │   │   │   │   ├── menuList.ts
    │   │   │   │   └── themes/
    │   │   │   │       ├── aqua.ts
    │   │   │   │       ├── azuper.ts
    │   │   │   │       ├── azurePink.ts
    │   │   │   │       ├── camelliaRed.ts
    │   │   │   │       ├── chameleon.ts
    │   │   │   │       ├── citrus.ts
    │   │   │   │       ├── greenJade.ts
    │   │   │   │       ├── index.ts
    │   │   │   │       ├── kleinH.ts
    │   │   │   │       ├── lavender.ts
    │   │   │   │       ├── nintendo.ts
    │   │   │   │       ├── skybloom.ts
    │   │   │   │       ├── smartLive.ts
    │   │   │   │       └── tealMedley.ts
    │   │   │   ├── lib/
    │   │   │   │   ├── index.ts
    │   │   │   │   ├── assets/
    │   │   │   │   │   └── svg_base/
    │   │   │   │   ├── components/
    │   │   │   │   │   ├── actionSheet/
    │   │   │   │   │   │   └── ActionSheet.svelte
    │   │   │   │   │   ├── asyncPicker/
    │   │   │   │   │   │   └── AsyncPicker.svelte
    │   │   │   │   │   ├── avatar/
    │   │   │   │   │   │   ├── Avatar.svelte
    │   │   │   │   │   │   └── Avatars.svelte
    │   │   │   │   │   ├── badge/
    │   │   │   │   │   │   └── Badge.svelte
    │   │   │   │   │   ├── bottomSheet/
    │   │   │   │   │   │   └── BottomSheet.svelte
    │   │   │   │   │   ├── button/
    │   │   │   │   │   │   └── Button.svelte
    │   │   │   │   │   ├── calendar/
    │   │   │   │   │   │   └── Calendar.svelte
    │   │   │   │   │   ├── cell/
    │   │   │   │   │   │   ├── Cell.svelte
    │   │   │   │   │   │   └── CellGroup.svelte
    │   │   │   │   │   ├── checkbox/
    │   │   │   │   │   │   ├── Checkbox.svelte
    │   │   │   │   │   │   └── CheckboxItem.svelte
    │   │   │   │   │   ├── dialog/
    │   │   │   │   │   │   └── Dialog.svelte
    │   │   │   │   │   ├── divider/
    │   │   │   │   │   │   └── Divider.svelte
    │   │   │   │   │   ├── grids/
    │   │   │   │   │   │   ├── Grid.svelte
    │   │   │   │   │   │   └── Grids.svelte
    │   │   │   │   │   ├── icon/
    │   │   │   │   │   │   └── Icon.svelte
    │   │   │   │   │   ├── indexBar/
    │   │   │   │   │   │   └── IndexBar.svelte
    │   │   │   │   │   ├── input/
    │   │   │   │   │   │   └── Input.svelte
    │   │   │   │   │   ├── loading/
    │   │   │   │   │   │   ├── Loading.svelte
    │   │   │   │   │   │   └── loadings/
    │   │   │   │   │   │       ├── fourColor/
    │   │   │   │   │   │       │   ├── 4_0.svelte
    │   │   │   │   │   │       │   ├── 4_1.svelte
    │   │   │   │   │   │       │   ├── 4_2.svelte
    │   │   │   │   │   │       │   ├── 4_3.svelte
    │   │   │   │   │   │       │   └── index.ts
    │   │   │   │   │   │       ├── oneColor/
    │   │   │   │   │   │       │   ├── 1_0.svelte
    │   │   │   │   │   │       │   ├── 1_1.svelte
    │   │   │   │   │   │       │   ├── 1_10.svelte
    │   │   │   │   │   │       │   ├── 1_11.svelte
    │   │   │   │   │   │       │   ├── 1_12.svelte
    │   │   │   │   │   │       │   ├── 1_13.svelte
    │   │   │   │   │   │       │   ├── 1_14.svelte
    │   │   │   │   │   │       │   ├── 1_15.svelte
    │   │   │   │   │   │       │   ├── 1_16.svelte
    │   │   │   │   │   │       │   ├── 1_17.svelte
    │   │   │   │   │   │       │   ├── 1_18.svelte
    │   │   │   │   │   │       │   ├── 1_19.svelte
    │   │   │   │   │   │       │   ├── 1_2.svelte
    │   │   │   │   │   │       │   ├── 1_20.svelte
    │   │   │   │   │   │       │   ├── 1_21.svelte
    │   │   │   │   │   │       │   ├── 1_22.svelte
    │   │   │   │   │   │       │   ├── 1_23.svelte
    │   │   │   │   │   │       │   ├── 1_24.svelte
    │   │   │   │   │   │       │   ├── 1_25.svelte
    │   │   │   │   │   │       │   ├── 1_26.svelte
    │   │   │   │   │   │       │   ├── 1_27.svelte
    │   │   │   │   │   │       │   ├── 1_28.svelte
    │   │   │   │   │   │       │   ├── 1_29.svelte
    │   │   │   │   │   │       │   ├── 1_3.svelte
    │   │   │   │   │   │       │   ├── 1_30.svelte
    │   │   │   │   │   │       │   ├── 1_31.svelte
    │   │   │   │   │   │       │   ├── 1_32.svelte
    │   │   │   │   │   │       │   ├── 1_33.svelte
    │   │   │   │   │   │       │   ├── 1_34.svelte
    │   │   │   │   │   │       │   ├── 1_35.svelte
    │   │   │   │   │   │       │   ├── 1_36.svelte
    │   │   │   │   │   │       │   ├── 1_37.svelte
    │   │   │   │   │   │       │   ├── 1_38.svelte
    │   │   │   │   │   │       │   ├── 1_39.svelte
    │   │   │   │   │   │       │   ├── 1_4.svelte
    │   │   │   │   │   │       │   ├── 1_40.svelte
    │   │   │   │   │   │       │   ├── 1_41.svelte
    │   │   │   │   │   │       │   ├── 1_42.svelte
    │   │   │   │   │   │       │   ├── 1_43.svelte
    │   │   │   │   │   │       │   ├── 1_44.svelte
    │   │   │   │   │   │       │   ├── 1_45.svelte
    │   │   │   │   │   │       │   ├── 1_46.svelte
    │   │   │   │   │   │       │   ├── 1_47.svelte
    │   │   │   │   │   │       │   ├── 1_48.svelte
    │   │   │   │   │   │       │   ├── 1_49.svelte
    │   │   │   │   │   │       │   ├── 1_5.svelte
    │   │   │   │   │   │       │   ├── 1_50.svelte
    │   │   │   │   │   │       │   ├── 1_51.svelte
    │   │   │   │   │   │       │   ├── 1_52.svelte
    │   │   │   │   │   │       │   ├── 1_53.svelte
    │   │   │   │   │   │       │   ├── 1_6.svelte
    │   │   │   │   │   │       │   ├── 1_7.svelte
    │   │   │   │   │   │       │   ├── 1_8.svelte
    │   │   │   │   │   │       │   ├── 1_9.svelte
    │   │   │   │   │   │       │   └── index.ts
    │   │   │   │   │   │       └── twoColor/
    │   │   │   │   │   │           ├── 2_0.svelte
    │   │   │   │   │   │           ├── 2_1.svelte
    │   │   │   │   │   │           ├── 2_2.svelte
    │   │   │   │   │   │           ├── 2_3.svelte
    │   │   │   │   │   │           ├── 2_4.svelte
    │   │   │   │   │   │           ├── 2_5.svelte
    │   │   │   │   │   │           └── index.ts
    │   │   │   │   │   ├── mask/
    │   │   │   │   │   │   └── Mask.svelte
    │   │   │   │   │   ├── modal/
    │   │   │   │   │   │   └── Modal.svelte
    │   │   │   │   │   ├── navBar/
    │   │   │   │   │   │   └── NavBar.svelte
    │   │   │   │   │   ├── noticeBar/
    │   │   │   │   │   │   └── NoticeBar.svelte
    │   │   │   │   │   ├── numKeyboard/
    │   │   │   │   │   │   └── NumKeyboard.svelte
    │   │   │   │   │   ├── pagination/
    │   │   │   │   │   │   ├── Page.svelte
    │   │   │   │   │   │   ├── Pagination.svelte
    │   │   │   │   │   │   ├── SecondPageNext.svelte
    │   │   │   │   │   │   └── SecondPagePre.svelte
    │   │   │   │   │   ├── picker/
    │   │   │   │   │   │   └── Picker.svelte
    │   │   │   │   │   ├── placeholder/
    │   │   │   │   │   │   └── Placeholder.svelte
    │   │   │   │   │   ├── popup/
    │   │   │   │   │   │   ├── Popup.svelte
    │   │   │   │   │   │   └── Transition.svelte
    │   │   │   │   │   ├── progress/
    │   │   │   │   │   │   └── Progress.svelte
    │   │   │   │   │   ├── progressLoop/
    │   │   │   │   │   │   └── ProgressLoop.svelte
    │   │   │   │   │   ├── radio/
    │   │   │   │   │   │   ├── Radio.svelte
    │   │   │   │   │   │   └── RadioItem.svelte
    │   │   │   │   │   ├── rate/
    │   │   │   │   │   │   └── Rate.svelte
    │   │   │   │   │   ├── scrollRadio/
    │   │   │   │   │   │   └── ScrollRadio.svelte
    │   │   │   │   │   ├── skeleton/
    │   │   │   │   │   │   └── Skeleton.svelte
    │   │   │   │   │   ├── slider/
    │   │   │   │   │   │   └── Slider.svelte
    │   │   │   │   │   ├── stepper/
    │   │   │   │   │   │   └── Stepper.svelte
    │   │   │   │   │   ├── steps/
    │   │   │   │   │   │   └── Steps.svelte
    │   │   │   │   │   ├── swiper/
    │   │   │   │   │   │   └── Swiper.svelte
    │   │   │   │   │   ├── switch/
    │   │   │   │   │   │   └── Switch.svelte
    │   │   │   │   │   ├── tabBar/
    │   │   │   │   │   │   └── TabBar.svelte
    │   │   │   │   │   ├── tabs/
    │   │   │   │   │   │   ├── Tab.svelte
    │   │   │   │   │   │   ├── TabContent.svelte
    │   │   │   │   │   │   └── Tabs.svelte
    │   │   │   │   │   ├── timePicker/
    │   │   │   │   │   │   └── TimePicker.svelte
    │   │   │   │   │   ├── toast/
    │   │   │   │   │   │   ├── Toast.svelte
    │   │   │   │   │   │   └── Transition.svelte
    │   │   │   │   │   └── utils/
    │   │   │   │   │       └── index.ts
    │   │   │   │   ├── lang/
    │   │   │   │   │   ├── ar_EG.ts
    │   │   │   │   │   ├── az_AZ.ts
    │   │   │   │   │   ├── bg_BG.ts
    │   │   │   │   │   ├── bn_BD.ts
    │   │   │   │   │   ├── ca_ES.ts
    │   │   │   │   │   ├── cs_CZ.ts
    │   │   │   │   │   ├── da_DK.ts
    │   │   │   │   │   ├── de_DE.ts
    │   │   │   │   │   ├── el_GR.ts
    │   │   │   │   │   ├── en_GB.ts
    │   │   │   │   │   ├── en_US.ts
    │   │   │   │   │   ├── es_ES.ts
    │   │   │   │   │   ├── et_EE.ts
    │   │   │   │   │   ├── eu_ES.ts
    │   │   │   │   │   ├── fa_IR.ts
    │   │   │   │   │   ├── fi_FI.ts
    │   │   │   │   │   ├── fr_BE.ts
    │   │   │   │   │   ├── fr_CA.ts
    │   │   │   │   │   ├── fr_FR.ts
    │   │   │   │   │   ├── ga_IE.ts
    │   │   │   │   │   ├── gl_ES.ts
    │   │   │   │   │   ├── he_IL.ts
    │   │   │   │   │   ├── hi_IN.ts
    │   │   │   │   │   ├── hr_HR.ts
    │   │   │   │   │   ├── hu_HU.ts
    │   │   │   │   │   ├── hy_AM.ts
    │   │   │   │   │   ├── id_ID.ts
    │   │   │   │   │   ├── index.ts
    │   │   │   │   │   ├── is_IS.ts
    │   │   │   │   │   ├── it_IT.ts
    │   │   │   │   │   ├── ja_JP.ts
    │   │   │   │   │   ├── ka_GE.ts
    │   │   │   │   │   ├── kk_KZ.ts
    │   │   │   │   │   ├── km_KH.ts
    │   │   │   │   │   ├── kmr_IQ.ts
    │   │   │   │   │   ├── kn_IN.ts
    │   │   │   │   │   ├── ko_KR.ts
    │   │   │   │   │   ├── lt_LT.ts
    │   │   │   │   │   ├── lv_LV.ts
    │   │   │   │   │   ├── mk_MK.ts
    │   │   │   │   │   ├── ml_IN.ts
    │   │   │   │   │   ├── mn_MN.ts
    │   │   │   │   │   ├── ms_MY.ts
    │   │   │   │   │   ├── nb_NO.ts
    │   │   │   │   │   ├── ne_NP.ts
    │   │   │   │   │   ├── nl_BE.ts
    │   │   │   │   │   ├── nl_NL.ts
    │   │   │   │   │   ├── pl_PL.ts
    │   │   │   │   │   ├── pt_BR.ts
    │   │   │   │   │   ├── pt_PT.ts
    │   │   │   │   │   ├── ro_RO.ts
    │   │   │   │   │   ├── ru_RU.ts
    │   │   │   │   │   ├── si_LK.ts
    │   │   │   │   │   ├── sk_SK.ts
    │   │   │   │   │   ├── sl_SI.ts
    │   │   │   │   │   ├── sr_RS.ts
    │   │   │   │   │   ├── sv_SE.ts
    │   │   │   │   │   ├── ta_IN.ts
    │   │   │   │   │   ├── th_TH.ts
    │   │   │   │   │   ├── tk_TK.ts
    │   │   │   │   │   ├── tr_TR.ts
    │   │   │   │   │   ├── uk_UA.ts
    │   │   │   │   │   ├── ur_PK.ts
    │   │   │   │   │   ├── vi_VN.ts
    │   │   │   │   │   ├── zh_CN.ts
    │   │   │   │   │   ├── zh_HK.ts
    │   │   │   │   │   └── zh_TW.ts
    │   │   │   │   ├── theme/
    │   │   │   │   │   ├── darkMode.ts
    │   │   │   │   │   ├── index.ts
    │   │   │   │   │   ├── stdf.ts
    │   │   │   │   │   ├── switchTheme.ts
    │   │   │   │   │   └── types.ts
    │   │   │   │   └── types/
    │   │   │   │       └── index.ts
    │   │   │   └── routes/
    │   │   │       ├── +layout.svelte
    │   │   │       ├── +layout.ts
    │   │   │       ├── +page.svelte
    │   │   │       ├── actionSheet/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── asyncPicker/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   ├── +page.svelte
    │   │   │       │   │   └── data_en.js
    │   │   │       │   └── zh_CN/
    │   │   │       │       ├── +page.svelte
    │   │   │       │       └── data.js
    │   │   │       ├── avatar/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── badge/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── bottomSheet/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── button/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── calendar/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── cell/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── checkbox/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── components/
    │   │   │       │   ├── Aphorism.svelte
    │   │   │       │   └── ThemeSwitch.svelte
    │   │   │       ├── dialog/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── divider/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── grids/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── icon/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── indexBar/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── input/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── loading/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── mask/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── modal/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── navBar/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── noticeBar/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── numKeyboard/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── pagination/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── picker/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   ├── +page.svelte
    │   │   │       │   │   └── data_en.js
    │   │   │       │   └── zh_CN/
    │   │   │       │       ├── +page.svelte
    │   │   │       │       └── data.js
    │   │   │       ├── placeholder/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── popup/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── progress/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── progressLoop/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── radio/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── rate/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── skeleton/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── slider/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── stepper/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── steps/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   ├── +page.svelte
    │   │   │       │   │   ├── injCom1_en.svelte
    │   │   │       │   │   └── injCom2_en.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       ├── +page.svelte
    │   │   │       │       ├── injCom1.svelte
    │   │   │       │       └── injCom2.svelte
    │   │   │       ├── swiper/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   ├── +page.svelte
    │   │   │       │   │   └── Item_en.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       ├── +page.svelte
    │   │   │       │       └── Item.svelte
    │   │   │       ├── switch/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── tabBar/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── tabs/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       ├── timePicker/
    │   │   │       │   ├── en_US/
    │   │   │       │   │   └── +page.svelte
    │   │   │       │   └── zh_CN/
    │   │   │       │       └── +page.svelte
    │   │   │       └── toast/
    │   │   │           ├── en_US/
    │   │   │           │   └── +page.svelte
    │   │   │           └── zh_CN/
    │   │   │               └── +page.svelte
    │   │   ├── static/
    │   │   │   ├── 404.html
    │   │   │   ├── .nojekyll
    │   │   │   ├── assets/
    │   │   │   │   ├── images/
    │   │   │   │   └── logos/
    │   │   │   └── fonts/
    │   │   │       └── Trueno.otf
    │   │   └── .github/
    │   │       └── workflows/
    │   │           └── releases-demo.yml
    │   └── vscode-extension/
    │       ├── README.md
    │       ├── CHANGELOG.md
    │       ├── CHANGELOG_CN.md
    │       ├── package.json
    │       ├── README_CN.md
    │       ├── scripts/
    │       │   └── files.js
    │       └── src/
    │           ├── extension.js
    │           └── assets/
    └── .github/
        ├── CONTRIBUTING.md
        ├── FUNDING.yml
        ├── PULL_REQUEST_TEMPLATE.md
        ├── ISSUE_TEMPLATE/
        │   ├── bug_report.yml
        │   ├── bug_report_CN.yml
        │   ├── feature_request.yml
        │   └── feature_request_CN.yml
        └── workflows/
            ├── publish-create.yml
            ├── publish-icon-0.x.yml
            ├── publish-icon.yml
            ├── publish-md-0.x.yml
            ├── publish-md.yml
            ├── publish-stdf-0.x.yml
            ├── publish-stdf.yml
            ├── publish-vscode-0.x.yml
            ├── publish-vscode.yml
            ├── releases-0.x.yml
            ├── releases-site.yml
            ├── releases-stdf.yml
            ├── sync-demo-0.x.yml
            ├── sync-demo.yml
            └── sync-gitee.yml


================================================
FILE: README.md
================================================
<div align="center">

[![Public STDF Status](https://github.com/any-tdf/stdf/actions/workflows/publish-stdf.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/publish-stdf.yml)
[![Releases STDF Status](https://github.com/any-tdf/stdf/actions/workflows/releases-stdf.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/releases-stdf.yml)
[![Sync Demo Status](https://github.com/any-tdf/stdf/actions/workflows/sync-demo.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/sync-demo.yml)
[![Releases Demo](https://github.com/any-tdf/demo-stdf/actions/workflows/releases-demo.yml/badge.svg)](https://github.com/any-tdf/demo-stdf/actions/workflows/releases-demo.yml)
[![Public Create Status](https://github.com/any-tdf/stdf/actions/workflows/publish-create.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/publish-create.yml)
[![Public Icon Status](https://github.com/any-tdf/stdf/actions/workflows/publish-icon.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/publish-icon.yml)
[![Public MD Status](https://github.com/any-tdf/stdf/actions/workflows/publish-md.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/publish-md.yml)
[![Public VS Code Extension Status](https://github.com/any-tdf/stdf/actions/workflows/publish-vscode.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/publish-vscode.yml)
[![Sync Gitee Status](https://github.com/any-tdf/stdf/actions/workflows/sync-gitee.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/sync-gitee.yml)
[![Releases Site](https://github.com/any-tdf/stdf/actions/workflows/releases-site.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/releases-site.yml)

  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://stdf.design/assets/favicon_logo_dark/android-chrome-512x512.png">
    <img src="https://stdf.design/assets/favicon_logo/android-chrome-512x512.png" alt="logo" width="120" height="auto" />
  </picture>
  
  <h1>STDF</h1>

![](https://img.shields.io/badge/-Svelte%205-%23ff3e00?logo=svelte&logoColor=ffffff)
![](https://img.shields.io/badge/-Tailwind%204-%2300a6f4?logo=tailwindcss&logoColor=ffffff)
![](https://img.shields.io/badge/-TypeScript-%233178c6?logo=typescript&logoColor=ffffff)

[![npm](https://img.shields.io/npm/v/stdf?logo=npm&label=stdf&style=for-the-badge&color=aeb5f4&logoColor=DCE4FD&labelColor=010319)](https://www.npmjs.com/package/stdf)
[![npm](https://img.shields.io/npm/v/create-stdf?logo=npm&label=create&style=for-the-badge&color=ebb2ba&logoColor=FBDDDD&labelColor=190104)](https://www.npmjs.com/package/create-stdf)
[![npm](https://img.shields.io/npm/v/rollup-plugin-stdf-icon?logo=npm&label=icon&style=for-the-badge&color=8cf2be&logoColor=D5FCE3&labelColor=01190C)](https://www.npmjs.com/package/rollup-plugin-stdf-icon)
[![npm](https://img.shields.io/npm/v/rollup-plugin-md-ts?logo=npm&label=md&style=for-the-badge&color=fda0f0&logoColor=fda0f0&labelColor=12020f)](https://www.npmjs.com/package/rollup-plugin-md-ts)
[![Visual Studio Marketplace Version (including pre-releases)](https://img.shields.io/visual-studio-marketplace/v/STDF.stdf-vscode-extension?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgMzIgMzIiPgogICAgPHBhdGgKICAgICAgICBmaWxsPSIjRjBGQ0Q2IgogICAgICAgIGQ9Ik0zMC44NjUgMy40NDhMMjQuMjgyLjI4MWExLjk5IDEuOTkgMCAwIDAtMi4yNzYuMzg1TDkuMzk3IDEyLjE3MUwzLjkwMiA4LjAwNGExLjMzIDEuMzMgMCAwIDAtMS43MDMuMDczTC40MzkgOS42ODFhMS4zMyAxLjMzIDAgMCAwLS4wMDUgMS45NjlMNS4yIDE1Ljk5OUwuNDM0IDIwLjM0OGExLjMzIDEuMzMgMCAwIDAgLjAwNSAxLjk2OWwxLjc2IDEuNjA0YTEuMzMgMS4zMyAwIDAgMCAxLjcwMy4wNzNsNS40OTUtNC4xNzJsMTIuNjE1IDExLjUxYTEuOTgyIDEuOTgyIDAgMCAwIDIuMjcxLjM4NWw2LjU4OS0zLjE3MmExLjk5MyAxLjk5MyAwIDAgMCAxLjEzLTEuODAyVjUuMjQ4YzAtLjc2Ni0uNDQzLTEuNDY5LTEuMTM1LTEuODAyem0tNi44NiAxOS44MThMMTQuNDMyIDE2bDkuNTczLTcuMjY2eiIKICAgIC8+Cjwvc3ZnPgo=&label=extension&style=for-the-badge&color=c7f292&logoColor=F0FCD6&labelColor=0E1901)](https://marketplace.visualstudio.com/items?itemName=STDF.stdf-vscode-extension)
[![GitHub stars](https://img.shields.io/github/stars/any-tdf/stdf?logo=github&label=star&style=for-the-badge&color=A1DAD7&logoColor=D9F8F2&labelColor=011918)](https://github.com/any-tdf/stdf)
[![GitHub license](https://img.shields.io/github/license/any-tdf/stdf?logo=github&style=for-the-badge&color=B9C46A&logoColor=F3F3CB&labelColor=161901)](https://github.com/any-tdf/stdf)

  <h3>
    <a href="https://github.com/any-tdf/stdf/blob/main/README_CN.md" target="_blank">简体中文</a>
    <span> • </span>
    <a href="https://stdf.design?lang=en_US" target="_blank">Website</a>
  </h3>
</div>

# Introduction

Mobile web component library based on [Svelte](https://svelte.dev) and [Tailwind](https://www.tailwindcss.com) .

> **S**imple • **T**iny • **D**esign • **F**ast

# Features

- 🔥 Full support for Svelte v5, Tailwind CSS v4, and TypeScript.
- 🚀 No runtime, no virtual DOM — runs faster online.
- 🧰 Rich API — easily configure component styles to meet your needs.
- 🍭 Supports dark mode and multiple theme configuration.
- 📖 Provides extensive Chinese and English documentation and component examples.
- 🌍 Supports internationalization, with 60+ built-in language packages.
- 🫰 User-friendly interaction, animation parameters can be configured, and custom themes are supported.
- 🤝 Supports Tailwind libraries such as UnoCSS.
- 🫡 No third-party dependencies — no need to worry about library versions or security issues.
- 📦 Supports on-demand import to reduce bundle size.
- 🪜 Comes with a scaffolding tool for quick project creation.
- 🔗 Comes with an SVG merging plugin for quickly merging SVG files.
- 🍺 IDE plugin for quickly viewing component APIs.

# Getting Started

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm create stdf
```
<!-- :: -->
<!-- npm -->
```sh
npm create stdf
# or
npm init stdf
# or
npx create-stdf
```
<!-- :: -->
<!-- bun -->
```sh
bun create stdf
```
<!-- :: -->
<!-- yarn -->
```sh
yarn create stdf
```
<!-- ::: -->

# Preview Demo

Please scan the QR code to access the mobile demo:

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://stdf.design/assets/qr/demo_en_dark.png">
  <img src="https://stdf.design/assets/qr/demo_en.png" width="220" height="220" >
</picture>

# Quick Try

You can quickly try STDF on StackBlitz's [STDF Demo](https://stackblitz.com/github/any-tdf/demo-stdf?startScript=dev_en).

# Feedback and Communication

We recommend using [GitHub Issues](https://github.com/any-tdf/stdf/issues) for direct and effective feedback and communication. Contributions of code are also highly appreciated. You can also choose from the following options:

- [QQ Group](https://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=U8ZlXJ3KVpTI9oZzs1jBnyWc3gVA0h6Y&authKey=ScWu0nU9g8BqNsC7o2eYkESwgVDVz9vzGNZEb17MrEAay9%2F7bTkXDiLJRIzo2vrg&noverify=0&group_code=581073686)
- [QQ Discord](https://pd.qq.com/s/fdd8incyr)
- [Discord](https://discord.gg/DMkHu8GGre)
- [Discussions](https://github.com/any-tdf/stdf/discussions)

# Contributors

<a href="https://github.com/any-tdf/stdf/graphs/contributors">
  <img src="https://contrib.nn.ci/api?repo=any-tdf/stdf" />
</a>

# Sponsors

<a href="https://github.com/sbscan" target="_blank">
  <img src="https://avatars.githubusercontent.com/sbscan" width="60" height="auto" style="border-radius:100%" >
</a>
<a href="https://github.com/MuGuiLin" target="_blank">
  <img src="https://avatars.githubusercontent.com/MuGuiLin" width="60" height="auto" style='border-radius:100%' >
</a>
<a href="https://github.com/yuedanlabs" target="_blank">
  <img src="https://avatars.githubusercontent.com/yuedanlabs" width="60" height="auto" style='border-radius:100%' >
</a>

# License

This project is licensed under the [MIT License](https://github.com/any-tdf/stdf/blob/main/LICENSE). Feel free to enjoy and contribute to this open-source project.

# Star History

<a href="https://github.com/any-tdf/stdf">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=any-tdf/stdf&type=Timeline&theme=dark" />
    <img alt="Star History Chart" width="100%" src="https://api.star-history.com/svg?repos=any-tdf/stdf&type=Timeline" />
  </picture>
</a>



================================================
FILE: CODE_OF_CONDUCT.md
================================================
# STDF Code of Conduct

Like the technical community as a whole, the STDF team and community is made up of a mixture of professionals and volunteers from all over the world, working on every aspect of the mission - including mentorship, teaching, and connecting people.

Diversity is one of our huge strengths, but it can also lead to communication issues and unhappiness. To that end, we have a few ground rules that we ask people to adhere to. This code applies equally to founders, mentors and those seeking help and guidance.

This isn’t an exhaustive list of things that you can’t do. Rather, take it in the spirit in which it’s intended - a guide to make it easier to enrich all of us and the technical communities in which we participate.

This code of conduct applies to all spaces managed by the STDF project or any-tdf. This includes IRC, the mailing lists, the issue tracker, DSF events, and any other forums created by the project team which the community uses for communication. In addition, violations of this code outside these spaces may affect a person's ability to participate within them.

If you believe someone is violating the code of conduct, we ask that you report it by emailing [any_tdf@163.com](mailto:any_tdf@163.com). For more details please see our 

- **Be friendly and patient.**
- **Be welcoming.** We strive to be a community that welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, colour, immigration status, social and economic class, educational level, sex, sexual orientation, gender identity and expression, age, size, family status, political belief, religion, and mental and physical ability.
- **Be considerate.** Your work will be used by other people, and you in turn will depend on the work of others. Any decision you take will affect users and colleagues, and you should take those consequences into account when making decisions. Remember that we're a world-wide community, so you might not be communicating in someone else's primary language.
- **Be respectful.** Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners. We might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack. It’s important to remember that a community where people feel uncomfortable or threatened is not a productive one. Members of the STDF community should be respectful when dealing with other members as well as with people outside the STDF community.
- **Be careful in the words that you choose.** We are a community of professionals, and we conduct ourselves professionally. Be kind to others. Do not insult or put down other participants. Harassment and other exclusionary behavior aren't acceptable. This includes, but is not limited to: 
 - Violent threats or language directed against another person.
 - Discriminatory jokes and language.
 - Posting sexually explicit or violent material.
 - Posting (or threatening to post) other people's personally identifying information ("doxing").
 - Personal insults, especially those using racist or sexist terms.
 - Unwelcome sexual attention.
 - Advocating for, or encouraging, any of the above behavior.
 - Repeated harassment of others. In general, if someone asks you to stop, then stop.
- **When we disagree, try to understand why.** Disagreements, both social and technical, happen all the time and STDF is no exception. It is important that we resolve disagreements and differing views constructively. Remember that we’re different. The strength of STDF comes from its varied community, people from a wide range of backgrounds. Different people have different perspectives on issues. Being unable to understand why someone holds a viewpoint doesn’t mean that they’re wrong. Don’t forget that it is human to err and blaming each other doesn’t get us anywhere. Instead, focus on helping to resolve issues and learning from mistakes.

Original text courtesy of the [Speak Up! project](http://web.archive.org/web/20141109123859/http://speakup.io/coc.html).

## Questions?

If you have questions, please see . If that doesn't answer your questions, feel free to [contact us](mailto:any_tdf@163.com).



================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2023 dufu1991

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.



================================================
FILE: README_CN.md
================================================
<div align="center">

[![Public STDF Status](https://github.com/any-tdf/stdf/actions/workflows/publish-stdf.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/publish-stdf.yml)
[![Releases STDF Status](https://github.com/any-tdf/stdf/actions/workflows/releases-stdf.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/releases-stdf.yml)
[![Sync Demo Status](https://github.com/any-tdf/stdf/actions/workflows/sync-demo.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/sync-demo.yml)
[![Releases Demo](https://github.com/any-tdf/demo-stdf/actions/workflows/releases-demo.yml/badge.svg)](https://github.com/any-tdf/demo-stdf/actions/workflows/releases-demo.yml)
[![Public Create Status](https://github.com/any-tdf/stdf/actions/workflows/publish-create.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/publish-create.yml)
[![Public Icon Status](https://github.com/any-tdf/stdf/actions/workflows/publish-icon.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/publish-icon.yml)
[![Public MD Status](https://github.com/any-tdf/stdf/actions/workflows/publish-md.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/publish-md.yml)
[![Public VS Code Extension Status](https://github.com/any-tdf/stdf/actions/workflows/publish-vscode.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/publish-vscode.yml)
[![Sync Gitee Status](https://github.com/any-tdf/stdf/actions/workflows/sync-gitee.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/sync-gitee.yml)
[![Releases Site](https://github.com/any-tdf/stdf/actions/workflows/releases-site.yml/badge.svg)](https://github.com/any-tdf/stdf/actions/workflows/releases-site.yml)

  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://stdf.design/assets/favicon_logo_dark/android-chrome-512x512.png">
    <img src="https://stdf.design/assets/favicon_logo/android-chrome-512x512.png" alt="logo" width="120" height="auto" />
  </picture>

  <h1>STDF</h1>

![](https://img.shields.io/badge/-Svelte%205-%23ff3e00?logo=svelte&logoColor=ffffff)
![](https://img.shields.io/badge/-Tailwind%204-%2300a6f4?logo=tailwindcss&logoColor=ffffff)
![](https://img.shields.io/badge/-TypeScript-%233178c6?logo=typescript&logoColor=ffffff)

[![npm](https://img.shields.io/npm/v/stdf?logo=npm&label=stdf&style=for-the-badge&color=aeb5f4&logoColor=DCE4FD&labelColor=010319)](https://www.npmjs.com/package/stdf)
[![npm](https://img.shields.io/npm/v/create-stdf?logo=npm&label=create&style=for-the-badge&color=ebb2ba&logoColor=FBDDDD&labelColor=190104)](https://www.npmjs.com/package/create-stdf)
[![npm](https://img.shields.io/npm/v/rollup-plugin-stdf-icon?logo=npm&label=icon&style=for-the-badge&color=8cf2be&logoColor=D5FCE3&labelColor=01190C)](https://www.npmjs.com/package/rollup-plugin-stdf-icon)
[![npm](https://img.shields.io/npm/v/rollup-plugin-md-ts?logo=npm&label=md&style=for-the-badge&color=fda0f0&logoColor=fda0f0&labelColor=12020f)](https://www.npmjs.com/package/rollup-plugin-md-ts)
[![Visual Studio Marketplace Version (including pre-releases)](https://img.shields.io/visual-studio-marketplace/v/STDF.stdf-vscode-extension?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgMzIgMzIiPgogICAgPHBhdGgKICAgICAgICBmaWxsPSIjRjBGQ0Q2IgogICAgICAgIGQ9Ik0zMC44NjUgMy40NDhMMjQuMjgyLjI4MWExLjk5IDEuOTkgMCAwIDAtMi4yNzYuMzg1TDkuMzk3IDEyLjE3MUwzLjkwMiA4LjAwNGExLjMzIDEuMzMgMCAwIDAtMS43MDMuMDczTC40MzkgOS42ODFhMS4zMyAxLjMzIDAgMCAwLS4wMDUgMS45NjlMNS4yIDE1Ljk5OUwuNDM0IDIwLjM0OGExLjMzIDEuMzMgMCAwIDAgLjAwNSAxLjk2OWwxLjc2IDEuNjA0YTEuMzMgMS4zMyAwIDAgMCAxLjcwMy4wNzNsNS40OTUtNC4xNzJsMTIuNjE1IDExLjUxYTEuOTgyIDEuOTgyIDAgMCAwIDIuMjcxLjM4NWw2LjU4OS0zLjE3MmExLjk5MyAxLjk5MyAwIDAgMCAxLjEzLTEuODAyVjUuMjQ4YzAtLjc2Ni0uNDQzLTEuNDY5LTEuMTM1LTEuODAyem0tNi44NiAxOS44MThMMTQuNDMyIDE2bDkuNTczLTcuMjY2eiIKICAgIC8+Cjwvc3ZnPgo=&label=extension&style=for-the-badge&color=c7f292&logoColor=F0FCD6&labelColor=0E1901)](https://marketplace.visualstudio.com/items?itemName=STDF.stdf-vscode-extension)
[![GitHub stars](https://img.shields.io/github/stars/any-tdf/stdf?logo=github&label=star&style=for-the-badge&color=A1DAD7&logoColor=D9F8F2&labelColor=011918)](https://github.com/any-tdf/stdf)
[![GitHub license](https://img.shields.io/github/license/any-tdf/stdf?logo=github&style=for-the-badge&color=B9C46A&logoColor=F3F3CB&labelColor=161901)](https://github.com/any-tdf/stdf)

  <h3>
    <a href="https://github.com/any-tdf/stdf/blob/main/README.md" target="_blank">English</a>
    <span> • </span>
    <a href="https://stdf.design?lang=zh_CN" target="_blank">网站</a>
  </h3>
</div>

# 介绍

基于 [Svelte](https://svelte.dev) 与 [Tailwind](https://www.tailwindcss.com) 的移动 web 组件库。

> **S**imple • **T**iny • **D**esign • **F**ast

> 简 单 • 轻 量 • 设 计 • 快 速

# 特性

- 🔥 完整支持 Svelte v5、Tailwind CSS v4 与 TypeScript。
- 🚀 无运行时，无虚拟 DOM，线上运行更快。
- 🧰 API 丰富，轻松配置出符合需求的组件样式。
- 🍭 支持暗模式与多主题配置。
- 📖 提供丰富的中英文文档和组件示例。
- 🌍 支持国际化，已内置 60+ 种语言包。
- 🫰 交互友好，动画参数可配，可自定义主题。
- 🤝 支持 Tailwind 类库，如 UnoCSS。
- 🫡 无三方依赖，无需担心三方库版本与安全问题。
- 📦 支持按需引入，减少打包体积。
- 🪜 配套脚手架，快速创建工程。
- 🔗 配套 SVG 合并插件，快速合并 SVG。
- 🍺 配套 IDE 插件，快速查看组件 API。

# 快速上手

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm create stdf
```
<!-- :: -->
<!-- npm -->
```sh
npm create stdf
# 或
npm init stdf
# 或
npx create-stdf
```
<!-- :: -->
<!-- bun -->
```sh
bun create stdf
```
<!-- :: -->
<!-- yarn -->
```sh
yarn create stdf
```
<!-- ::: -->

# 预览 Demo

扫描二维码访问移动端 Demo：

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://stdf.design/assets/qr/demo_zh_dark.png">
  <img src="https://stdf.design/assets/qr/demo_zh.png" width="220" height="220" >
</picture>

# 快速尝试

可以到 StackBlitz 的 [STDF Demo](https://stackblitz.com/github/any-tdf/demo-stdf) 快速尝试 STDF。

# 反馈与交流

推荐使用 [GitHub Issues](https://github.com/any-tdf/stdf/issues) 进行直接有效地反馈与交流，贡献代码就更好了。也可以选择以下几种方式：

- [QQ 群](https://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=U8ZlXJ3KVpTI9oZzs1jBnyWc3gVA0h6Y&authKey=ScWu0nU9g8BqNsC7o2eYkESwgVDVz9vzGNZEb17MrEAay9%2F7bTkXDiLJRIzo2vrg&noverify=0&group_code=581073686)
- [QQ 频道](https://pd.qq.com/s/fdd8incyr)
- [Discord](https://discord.gg/DMkHu8GGre)
- [Discussions](https://github.com/any-tdf/stdf/discussions)

# 贡献者

<a href="https://github.com/any-tdf/stdf/graphs/contributors">
  <img src="https://contrib.nn.ci/api?repo=any-tdf/stdf" />
</a>

# 赞助者

<a href="https://github.com/sbscan" target="_blank">
  <img src="https://avatars.githubusercontent.com/sbscan" width="60" height="auto" style="border-radius:100%" >
</a>
<a href="https://github.com/MuGuiLin" target="_blank">
  <img src="https://avatars.githubusercontent.com/MuGuiLin" width="60" height="auto" style='border-radius:100%' >
</a>
<a href="https://github.com/yuedanlabs" target="_blank">
  <img src="https://avatars.githubusercontent.com/yuedanlabs" width="60" height="auto" style='border-radius:100%' >
</a>

# 开源协议

本项目基于 [MIT](https://github.com/any-tdf/stdf/blob/main/LICENSE) 协议，请自由地享受和参与开源。

# Star 历史

<a href="https://github.com/any-tdf/stdf">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=any-tdf/stdf&type=Timeline&theme=dark" />
    <img alt="Star History Chart" width="100%" src="https://api.star-history.com/svg?repos=any-tdf/stdf&type=Timeline" />
  </picture>
</a>



================================================
FILE: SECURITY.md
================================================
# Security Policy

## Reporting a Vulnerability

- [QQ Group](https://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=U8ZlXJ3KVpTI9oZzs1jBnyWc3gVA0h6Y&authKey=ScWu0nU9g8BqNsC7o2eYkESwgVDVz9vzGNZEb17MrEAay9%2F7bTkXDiLJRIzo2vrg&noverify=0&group_code=581073686)
- [QQ Discord](https://pd.qq.com/s/fdd8incyr)
- [Discord](https://discord.gg/DMkHu8GGre)
- [Discussions](https://github.com/any-tdf/stdf/discussions)



================================================
FILE: docs/mds/components/actionSheet/api.md
================================================
## ActionSheet Props

| 名称           | 类型                                                        | 默认值                            | 必传 | 说明                                |
| -------------- | ----------------------------------------------------------- | --------------------------------- | ---- | ----------------------------------- |
| visible        | `boolean`                                                   | `false`                           | N    | 是否显示。                          |
| title          | `string`                                                    | `''`                              | N    | 标题。                              |
| titleAlign     | `'left'\|'center'\|'right'`                                 | `'center'`                        | N    | 标题对齐方式。                      |
| actions        | `Action[]`                                                  | `[]`                              | N    | 菜单选项，Action Props 组成的数组。 |
| popup          | [`Popup`](https://stdf.design/components?nav=popup&tab=1) | `{}`                              | N    | 弹出层参数。                        |
| showCancel     | `boolean`                                                   | `false`                           | N    | 是否显示取消选项。                  |
| cancelText     | `string`                                                    | 当前语言的 actionSheet.cancelText | N    | 取消选项文本。                      |
| actionClosable | `boolean`                                                   | `true`                            | N    | 点击选项是否关闭。                  |
| align          | `'left'\|'center'\|'right'`                                 | `'center'`                        | N    | 对齐方式。                          |

## ActionSheet Events

| 名称          | 类型                                      | 参数                                          | 描述                                         |
| ------------- | ----------------------------------------- | --------------------------------------------- | -------------------------------------------- |
| onclose       | `() => void`                              | -                                             | 关闭时触发。                                 |
| oncancel      | `() => void`                              | -                                             | 点击取消时触发。                             |
| onclickAction | `(index: number, action: Action) => void` | index - 点击索引值<br />action - 点击选项数据 | 点击选项时触发，即使点击选项不关闭也会触发。 |

## Action Props

| 名称      | 类型                                      | 默认值     | 必传 | 说明           |
| --------- | ----------------------------------------- | ---------- | ---- | -------------- |
| content   | `string`                                  | `''`       | Y    | 选项内容。     |
| style     | `'normal'\|'theme'\|'danger'\|'disabled'` | `'normal'` | N    | 选项样式。     |
| desc      | `string`                                  | `''`       | N    | 选项描述。     |
| showImg   | `boolean`                                 | `false`    | N    | 是否显示图片。 |
| imgRadius | `'none'\|'sm'\|'full'\|'lg'`              | `'full'`   | N    | 图片圆角。     |
| imgSrc    | `string`                                  | `''`       | N    | 图片地址。     |



================================================
FILE: docs/mds/components/actionSheet/api_en.md
================================================
## ActionSheet Props

| Name           | Type                                                        | Default                                 | Required | Description                                  |
| -------------- | ----------------------------------------------------------- | --------------------------------------- | -------- | -------------------------------------------- |
| visible        | `boolean`                                                   | `false`                                 | N        | Whether to show the action sheet.            |
| title          | `string`                                                    | `''`                                    | N        | Title text.                                  |
| titleAlign     | `'left'\|'center'\|'right'`                                 | `'center'`                              | N        | Title alignment.                             |
| actions        | `Action[]`                                                  | `[]`                                    | N        | Menu options array composed of Action Props. |
| popup          | [`Popup`](https://stdf.design/components?nav=popup&tab=1) | `{}`                                    | N        | Popup layer parameters.                      |
| showCancel     | `boolean`                                                   | `false`                                 | N        | Whether to show cancel button.               |
| cancelText     | `string`                                                    | Current language actionSheet.cancelText | N        | Cancel button text.                          |
| actionClosable | `boolean`                                                   | `true`                                  | N        | Whether to close when clicking an option.    |
| align          | `'left'\|'center'\|'right'`                                 | `'center'`                              | N        | Content alignment.                           |

## ActionSheet Events

| Name          | Type                                      | Parameters                                      | Description                                                           |
| ------------- | ----------------------------------------- | ----------------------------------------------- | --------------------------------------------------------------------- |
| onclose       | `() => void`                              | -                                               | Triggered when closing.                                               |
| oncancel      | `() => void`                              | -                                               | Triggered when clicking cancel button.                                |
| onclickAction | `(index: number, action: Action) => void` | index - Click index; action - Click option data | Triggered when clicking an option, even if the option does not close. |

## Action Props

| Name      | Type                                      | Default    | Required | Description            |
| --------- | ----------------------------------------- | ---------- | -------- | ---------------------- |
| content   | `string`                                  | `''`       | Y        | Option content.        |
| style     | `'normal'\|'theme'\|'danger'\|'disabled'` | `'normal'` | N        | Option style.          |
| desc      | `string`                                  | `''`       | N        | Option description.    |
| showImg   | `boolean`                                 | `false`    | N        | Whether to show image. |
| imgRadius | `'none'\|'sm'\|'full'\|'lg'`              | `'full'`   | N        | Image border radius.   |
| imgSrc    | `string`                                  | `''`       | N        | Image source URL.      |



================================================
FILE: docs/mds/components/actionSheet/FAQ.md
================================================



================================================
FILE: docs/mds/components/actionSheet/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/actionSheet/guide.md
================================================
## 使用

ActionSheet 动作面板一般从页面底部弹出，提供与当前场景相关的操作动作。此操作一般不会携带数据，不用担心误触，默认不显示取消操作项，允许点击遮罩关闭。

## 说明

ActionSheet 动作面板是在 Popup 基础上封装的，通过预先定义一些 Popup 的 Props 实现，因此可以通过传入 Popup 的属性来实现不同的效果。比如示例中通过设置 popup 的 radius 改变圆角风格。

## actions

ActionSheet 的 actions 属性是一个数组，数组中的每一项都是一个对象，对象属性参考 Action Props。

## Radio、ActionSheet、IndexBar、Picker、AsyncPicker 区别

Radio、Checkbox、ActionSheet、IndexBar、Picker、AsyncPicker 组件本质都是给出一系列数据，让用户进行数据选择或执行一些操作，但在使用上有一些区别：

- Radio 一般用于单选数据，数据量固定且较少，需要在 UI 界面上直接展示选项，方便用户在界面交互时对备选数据有个概览，比如性别选择。
- Checkbox 使用场景类似 Radio，但是可以多选。
- ActionSheet 一般用于选择之后立即执行一些操作，选项固定且较少，但不需要在 UI 界面上直接展示选项，比如做一些删除、修改等操作。
- IndexBar 一般用于选择单条数据，数据量非常大的动态数据，且已经对数据进行了分类索引，一般会用整个页面来展示。
- Picker 一般用于选择单条或多条数据，数据量较大或无法确定长度的动态数据，或用于一些联动数据的选择。**无论是否联动，数据在传入时已经是确定的。**
- AsyncPicker 一般用于选择多条数据，下级数据是根据上级数据动态获取的，比如服务端接口单次只返回一级数据，需要根据用户选择的一级数据再次请求接口获取下级数据。



================================================
FILE: docs/mds/components/actionSheet/guide_en.md
================================================
## Usage

ActionSheet is a panel that pops up from the bottom of the page and provides operation actions related to the current scene. This operation generally does not carry data, so there is no need to worry about accidental touch. The cancel operation item is not displayed by default and clicking the mask can close it.

## Description

ActionSheet is encapsulated based on Popup. By predefining some Props of Popup, different effects can be achieved by passing Popup's properties. For example, in the example, the radius style is changed by setting the radius of popup.

## Actions

The actions property of ActionSheet is an array, and each item in the array is an object. The properties of the object refer to Action Props.

## Differences between Radio, ActionSheet, IndexBar, Picker, and AsyncPicker

Radio, Checkbox, ActionSheet, IndexBar, Picker, and AsyncPicker components essentially provide a series of data for users to select or perform operations, but there are some differences in their usage:

- Radio is generally used for single selection data with fixed and small amount of options that need to be displayed directly on the UI interface, making it convenient for users to have an overview of alternative data during interface interaction, such as gender selection.
- Checkbox has similar usage scenarios to Radio, but allows multiple selections.
- ActionSheet is generally used for immediate operations after selection, with fixed and few options that don't need to be displayed directly on the UI interface, such as delete or modify operations.
- IndexBar is generally used to select a single piece of data from a very large dynamic dataset that has been categorized with indexes, usually displayed on an entire page.
- Picker is generally used to select single or multiple pieces of data from large or uncertain length dynamic datasets, or for linked data selection. **Whether linked or not, the data is determined when passed in.**
- AsyncPicker is generally used to select multiple pieces of data where lower-level data is dynamically obtained based on upper-level data, such as when a server interface only returns one level of data at a time and needs to request the interface again based on the user's first-level selection to get the next level of data.



================================================
FILE: docs/mds/components/actionSheet/version.md
================================================



================================================
FILE: docs/mds/components/actionSheet/version_en.md
================================================



================================================
FILE: docs/mds/components/asyncPicker/api.md
================================================
## AsyncPicker Props

| 名称         | 类型                                                            | 默认值                            | 必传 | 说明                         |
| ------------ | --------------------------------------------------------------- | --------------------------------- | ---- | ---------------------------- |
| visible      | `boolean`                                                       | `false`                           | N    | 是否显示。                   |
| data         | `array`                                                         | `[]`                              | Y    | 列数据，具体使用请参考示例。 |
| lastLevel    | `boolean`                                                       | `false`                           | N    | 是否是最后一级。             |
| firstLevel   | `boolean`                                                       | `false`                           | N    | 是否是第一级。               |
| showRow      | `3\|5\|7`                                                       | `5`                               | N    | 列显示行数。                 |
| labelKey     | `string`                                                        | `'label'`                         | N    | 自定义 label 的 key。        |
| align        | `'left'\|'center'\|'right'`                                     | `'center'`                        | N    | 对齐方式。                   |
| cancelText   | `string`                                                        | 当前语言的 picker.defaultCancel   | N    | 取消选项文本。               |
| confirmText  | `string`                                                        | 当前语言的 picker.defaultConfirm  | N    | 确定选项文本。               |
| title        | `string`                                                        | 当前语言的 picker.defaultTitle    | N    | 中间标题文本。               |
| nextText     | `string`                                                        | 当前语言的 picker.defaultNext     | N    | 下一级文本。                 |
| prevText     | `string`                                                        | 当前语言的 picker.defaultPrev     | N    | 上一级文本。                 |
| showSelected | `boolean`                                                       | `false`                           | N    | 是否显示已选项。             |
| selectedText | `string`                                                        | 当前语言的 picker.defaultSelected | N    | 已选文本。                   |
| popup        | [`Popup`](https://stdf.design/components?nav=popup&tab=1)     | `{}`                              | N    | 弹出层参数。                 |
| loading      | [`Loading`](https://stdf.design/components?nav=loading&tab=1) | `{}`                              | N    | 加载数据时 Loading 参数。    |

## AsyncPicker Events

| 名称      | 类型                                       | 参数                                                                    | 描述                   |
| --------- | ------------------------------------------ | ----------------------------------------------------------------------- | ---------------------- |
| onclose   | `() => void`                               | -                                                                       | 关闭时触发。           |
| oncancel  | `() => void`                               | -                                                                       | 点击左侧取消时触发。   |
| onprev    | `() => void`                               | -                                                                       | 点击左侧上一级时触发。 |
| onnext    | `(index: number) => void`                  | index - 当前选定项在所在列的索引                                        | 点击右侧下一级时触发。 |
| onconfirm | `(items: any[], indexs: number[]) => void` | items - 选定多列数据组成的数组<br />indexs - 选定多列数据索引组成的数组 | 点击右侧确定时触发。   |



================================================
FILE: docs/mds/components/asyncPicker/api_en.md
================================================
## AsyncPicker Props

| Name         | Type                                                            | Default                                 | Required | Description                                               |
| ------------ | --------------------------------------------------------------- | --------------------------------------- | -------- | --------------------------------------------------------- |
| visible      | `boolean`                                                       | `false`                                 | N        | Whether to show the picker.                               |
| data         | `array`                                                         | `[]`                                    | Y        | Column data. Please refer to examples for specific usage. |
| lastLevel    | `boolean`                                                       | `false`                                 | N        | Whether it is the last level.                             |
| firstLevel   | `boolean`                                                       | `false`                                 | N        | Whether it is the first level.                            |
| showRow      | `3\|5\|7`                                                       | `5`                                     | N        | Number of rows to display in the column.                  |
| labelKey     | `string`                                                        | `'label'`                               | N        | Custom key for label.                                     |
| align        | `'left' \| 'center' \| 'right'`                                 | `'center'`                              | N        | Text alignment.                                           |
| cancelText   | `string`                                                        | Current language picker.defaultCancel   | N        | Cancel button text.                                       |
| confirmText  | `string`                                                        | Current language picker.defaultConfirm  | N        | Confirm button text.                                      |
| title        | `string`                                                        | Current language picker.defaultTitle    | N        | Title text.                                               |
| nextText     | `string`                                                        | Current language picker.defaultNext     | N        | Next level text.                                          |
| prevText     | `string`                                                        | Current language picker.defaultPrev     | N        | Previous level text.                                      |
| showSelected | `boolean`                                                       | `false`                                 | N        | Whether to show selected items.                           |
| selectedText | `string`                                                        | Current language picker.defaultSelected | N        | Selected text.                                            |
| popup        | [`Popup`](https://stdf.design/components?nav=popup&tab=1)     | `{}`                                    | N        | Popup parameters.                                         |
| loading      | [`Loading`](https://stdf.design/components?nav=loading&tab=1) | `{}`                                    | N        | Loading parameters when loading data.                     |

## AsyncPicker Events

| Name      | Type                                       | Parameters                                                                    | Description                             |
| --------- | ------------------------------------------ | ----------------------------------------------------------------------------- | --------------------------------------- |
| onclose   | `() => void`                               | -                                                                             | Triggered when closing.                 |
| oncancel  | `() => void`                               | -                                                                             | Triggered when clicking cancel.         |
| onprev    | `() => void`                               | -                                                                             | Triggered when clicking previous level. |
| onnext    | `(index: number) => void`                  | index - Index of selected item in current column                              | Triggered when clicking next level.     |
| onconfirm | `(items: any[], indexs: number[]) => void` | items - Array of selected column data<br />indexs - Array of selected indexes | Triggered when clicking confirm.        |



================================================
FILE: docs/mds/components/asyncPicker/FAQ.md
================================================



================================================
FILE: docs/mds/components/asyncPicker/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/asyncPicker/guide.md
================================================
## 使用场景

AsyncPicker 组件使用场景类似于 Picker 多级联动，是为了解决下级数据根据上级数据从服务端查询的情况。例如：选择省级数据后，动态查询对应的市级数据，再选择市级数据后，动态查询对应的区级数据，以此类推。

## 使用方式

AsyncPicker 的使用对比 Picker 多级联动稍微有些复杂，因为数据不是一次性传入，而是通过接口动态获取，所以需要开发者自己处理数据。

通过监听 onnext 和 onprev 方法，更新当前列的新数据 data 并动态绑定至组件内部，同时需要动态绑定当前列是否是第一级 lastLevel，是否是最后一级 firstLevel。

当数据是最后一级时，右侧按钮会触发 onconfirm 方法，返回选定的数据；当数据不是最后一级时，右侧按钮会触发 onnext 方法，返回当前选定项的索引值。

## 返回数据

AsyncPicker 组件最终返回的数据有两项，一项是选定的多列数据组成的数组 items，另一项是选定的多列数据的索引组成的数组 indexs，请按照需求选择使用。

其中 items 每一项的数据结构与传入的数据结构一致，也方便开发者直接使用。

## 使用优化

实际开发中，多数情况下 AsyncPicker 的数据都是动态获取的，通常是通过接口获取，一般我们需要对传入的数据进行循环处理，以便于 AsyncPicker 组件能够正常使用。但这是一个比较繁琐且没必要的过程，因此 STDF 对 AsyncPicker 组件的入参做了一些优化，使得开发者可以直接传入接口返回的数据，而不需要做循环处理。

- 可以通过动态绑定每次数据的 labelKey，自定义传入的每列数据 label 属性名，如果不传入则默认使用 'label'，请参考示例。

## 说明

AsyncPicker 是在 Popup 基础上封装的，通过预先定义一些 Popup 的 Props 实现，因此可以通过传入 Popup 的属性来实现不同的效果。比如示例中通过设置 popup 的 radius 改变圆角风格。

AsyncPicker 内加载数据时显示的 loading 是在 Loading 组件基础上封装的，可以通过传入 Loading 的属性来实现不同的效果。比如示例中通过设置 loading 的一些参数换了一个 loading 效果。

## Radio、ActionSheet、IndexBar、Picker、AsyncPicker 区别

Radio、Checkbox、ActionSheet、IndexBar、Picker、AsyncPicker 组件本质都是给出一系列数据，让用户进行数据选择或执行一些操作，但在使用上有一些区别：

- Radio 一般用于单选数据，数据量固定且较少，需要在 UI 界面上直接展示选项，方便用户在界面交互时对备选数据有个概览，比如性别选择。
- Checkbox 使用场景类似 Radio，但是可以多选。
- ActionSheet 一般用于选择之后立即执行一些操作，选项固定且较少，但不需要在 UI 界面上直接展示选项，比如做一些删除、修改等操作。
- IndexBar 一般用于选择单条数据，数据量非常大的动态数据，且已经对数据进行了分类索引，一般会用整个页面来展示。
- Picker 一般用于选择单条或多条数据，数据量较大或无法确定长度的动态数据，或用于一些联动数据的选择。**无论是否联动，数据在传入时已经是确定的。**
- AsyncPicker 一般用于选择多条数据，下级数据是根据上级数据动态获取的，比如服务端接口单次只返回一级数据，需要根据用户选择的一级数据再次请求接口获取下级数据。



================================================
FILE: docs/mds/components/asyncPicker/guide_en.md
================================================
## Usage Scenarios

The AsyncPicker component is similar to Picker's multi-level linkage, but it's designed to handle scenarios where child-level data needs to be queried from the server based on parent-level selections. For example: after selecting province-level data, dynamically query corresponding city-level data, and after selecting city-level data, dynamically query corresponding district-level data, and so on.

## How to Use

Using AsyncPicker is slightly more complex compared to Picker's multi-level linkage because the data isn't passed in all at once but is obtained dynamically through APIs. Therefore, developers need to handle the data themselves.

By monitoring the onnext and onprev methods, update the current column's new data and dynamically bind it to the component internally. Additionally, you need to dynamically bind whether the current column is the first level (lastLevel) or the last level (firstLevel).

When the data is at the last level, the right button will trigger the onconfirm method, returning the selected data; when the data is not at the last level, the right button will trigger the onnext method, returning the index of the current selection.

## Return Data

The AsyncPicker component ultimately returns two items: an array of items containing the selected multi-column data, and an array of indexs containing the indices of the selected multi-column data. Please choose according to your needs.

The structure of each item in items matches the structure of the input data, making it convenient for developers to use directly.

## Usage Optimization

In actual development, AsyncPicker data is usually obtained dynamically, typically through APIs. Generally, we need to process the input data through loops to make it work with the AsyncPicker component. However, this is a cumbersome and unnecessary process. Therefore, STDF has optimized the AsyncPicker component's input parameters, allowing developers to directly pass in API response data without loop processing.

- You can dynamically bind labelKey for each data set to customize the label property name for each column's data. If not provided, it defaults to 'label'. Please refer to the examples.

## Notes

AsyncPicker is built on top of Popup by pre-defining some Popup Props. Therefore, different effects can be achieved by passing in Popup properties. For example, in the demo, the border radius style is changed by setting the popup's radius.

The loading display in AsyncPicker during data loading is built on top of the Loading component. Different effects can be achieved by passing in Loading properties. For example, in the demo, a different loading effect is achieved by setting some loading parameters.

## Differences between Radio, ActionSheet, IndexBar, Picker, and AsyncPicker

Radio, Checkbox, ActionSheet, IndexBar, Picker, and AsyncPicker components essentially all provide a series of data for users to select or perform operations, but there are some differences in their usage:

- Radio is generally used for single-selection data with fixed and fewer options, requiring direct display of options in the UI interface for users to have an overview during interaction, such as gender selection.
- Checkbox is similar to Radio in usage scenarios but allows multiple selections.
- ActionSheet is generally used when immediate actions need to be executed after selection, with fixed and fewer options, but doesn't need to display options directly in the UI interface, such as delete or modify operations.
- IndexBar is generally used for selecting single data items from very large dynamic datasets that have been categorized with indexes, typically using an entire page for display.
- Picker is generally used for selecting single or multiple data items from large or variable-length dynamic datasets, or for selecting linked data. **Whether linked or not, the data is determined when passed in.**
- AsyncPicker is generally used for selecting multiple data items where child-level data is dynamically obtained based on parent-level selections, such as when server APIs return only one level of data at a time and require additional requests based on user selections to obtain child-level data.



================================================
FILE: docs/mds/components/asyncPicker/version.md
================================================



================================================
FILE: docs/mds/components/asyncPicker/version_en.md
================================================



================================================
FILE: docs/mds/components/avatar/api.md
================================================
## Avatar Props

| 属性     | 类型                                                      | 默认值   | 必传 | 说明                 |
| -------- | --------------------------------------------------------- | -------- | ---- | -------------------- |
| image    | `string`                                                  | `''`     | N    | 图片路径。           |
| alt      | `string`                                                  | `''`     | N    | 替换文本，建议单字。 |
| icon     | [`Icon`](https://stdf.design/components?nav=icon&tab=1) | `{}`     | N    | 替换图标。           |
| altSize  | `'xs'\|'sm'\|'md'\|'lg'\|'xl'`                            | `'md'`   | N    | 替换文本大小。       |
| radius   | `'none'\|'sm'\|'xl'\|'2xl'\|'3xl'\|'full'`                | `'sm'`   | N    | 圆角风格。           |
| size     | `'xs'\|'sm'\|'base'\|'md'\|'lg'\|'xl'\|'2xl'`             | `'md'`   | N    | 头像框大小。         |
| imgSize  | `'s'\|'m'\|'l'`                                           | `'l'`    | N    | 头像图片大小。       |
| line     | `'none'\|'solid'\|'dashed'\|'dotted'`                     | `'none'` | N    | 边框风格。           |
| injClass | `string`                                                  | `''`     | N    | 注入 CSS 名称。      |

## Avatar Events

| 名称    | 类型         | 参数 | 描述       |
| ------- | ------------ | ---- | ---------- |
| onclick | `() => void` | -    | 点击触发。 |

## Avatars Props

| 名称      | 类型                                                                                        | 默认值    | 必传 | 说明                             |
| --------- | ------------------------------------------------------------------------------------------- | --------- | ---- | -------------------------------- |
| data      | `Avatar[]`                                                                                  | `[]`      | N    | 由 Avatar Props 组成的头像数据。 |
| radius    | `'none'\|'base'\|'xl'\|'2xl'\|'3xl'\|'full'`                                                | `'full'`  | N    | 圆角风格。                       |
| size      | `'xs'\|'sm'\|'base'\|'md'\|'lg'\|'xl'\|'2xl'`                                               | `'md'`    | N    | 头像框大小。                     |
| compact   | `number`                                                                                    | `5`       | N    | 紧凑程度，越大越紧凑。           |
| lineWidth | `'0'\|'1'\|'2'\|'3'\|'4'\|'8'`                                                              | `'3'`     | N    | 边框粗细。                       |
| reverse   | `boolean`                                                                                   | `false`   | N    | 是否反向。                       |
| max       | `number`                                                                                    | `10`      | N    | 最大最大显示数量。               |
| top       | `'totle'\|'add'\|null`\|[`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | `'totle'` | N    | 顶层内容。                       |
| injClass  | `string`                                                                                    | `''`      | N    | 注入 CSS 名称。                  |

## Avatars Events

| 名称    | 类型         | 参数 | 描述             |
| ------- | ------------ | ---- | ---------------- |
| onclick | `() => void` | -    | 点击头像组触发。 |



================================================
FILE: docs/mds/components/avatar/api_en.md
================================================
## Avatar Props

| Property | Type                                                      | Default  | Required | Description                        |
| -------- | --------------------------------------------------------- | -------- | -------- | ---------------------------------- |
| image    | `string`                                                  | `''`     | N        | Image path.                        |
| alt      | `string`                                                  | `''`     | N        | Alt text, single char recommended. |
| icon     | [`Icon`](https://stdf.design/components?nav=icon&tab=1) | `{}`     | N        | Alternative icon.                  |
| altSize  | `'xs'\|'sm'\|'md'\|'lg'\|'xl'`                            | `'md'`   | N        | Alt text size.                     |
| radius   | `'none'\|'sm'\|'xl'\|'2xl'\|'3xl'\|'full'`                | `'sm'`   | N        | Border radius style.               |
| size     | `'xs'\|'sm'\|'base'\|'md'\|'lg'\|'xl'\|'2xl'`             | `'md'`   | N        | Avatar frame size.                 |
| imgSize  | `'s'\|'m'\|'l'`                                           | `'l'`    | N        | Avatar image size.                 |
| line     | `'none'\|'solid'\|'dashed'\|'dotted'`                     | `'none'` | N        | Border style.                      |
| injClass | `string`                                                  | `''`     | N        | Injected CSS class name.           |

## Avatar Events

| Name    | Type         | Params | Description         |
| ------- | ------------ | ------ | ------------------- |
| onclick | `() => void` | -      | Triggered on click. |

## Avatars Props

| Name      | Type                                                                                        | Default   | Required | Description                                   |
| --------- | ------------------------------------------------------------------------------------------- | --------- | -------- | --------------------------------------------- |
| data      | `Avatar[]`                                                                                  | `[]`      | N        | Array of Avatar Props data.                   |
| radius    | `'none'\|'base'\|'xl'\|'2xl'\|'3xl'\|'full'`                                                | `'full'`  | N        | Border radius style.                          |
| size      | `'xs'\|'sm'\|'base'\|'md'\|'lg'\|'xl'\|'2xl'`                                               | `'md'`    | N        | Avatar frame size.                            |
| compact   | `number`                                                                                    | `5`       | N        | Compactness level, higher means more compact. |
| lineWidth | `'0'\|'1'\|'2'\|'3'\|'4'\|'8'`                                                              | `'3'`     | N        | Border width.                                 |
| reverse   | `boolean`                                                                                   | `false`   | N        | Whether to reverse the order.                 |
| max       | `number`                                                                                    | `10`      | N        | Maximum number of avatars to display.         |
| top       | `'totle'\|'add'\|null`\|[`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | `'totle'` | N        | Top layer content.                            |
| injClass  | `string`                                                                                    | `''`      | N        | Injected CSS class name.                      |

## Avatars Events

| Name    | Type         | Params | Description                          |
| ------- | ------------ | ------ | ------------------------------------ |
| onclick | `() => void` | -      | Triggered when avatar group clicked. |



================================================
FILE: docs/mds/components/avatar/FAQ.md
================================================



================================================
FILE: docs/mds/components/avatar/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/avatar/guide.md
================================================
> Avatar 使用了图标 ri-user-3-line 和 ri-user-add-line，请确保项目的 symbol.svg 文件中包含这些图标。详细信息请参考 [STDF-指南 - 图标](https://stdf.design/guide/icon)。

## 内容说明

image 可以传入图片的相对路径或绝对路径，组件内部将其转换为 img 标签的 src 属性；alt 传入文字将直接显示；icon 传入 Icon Props 将使用 Icon 组件渲染头像框内容，请参考 Icon API；若 image、alt、icon 都不传，Avatar 组件会默认使用 Icon 组件显示一个用户图标。

内容的可配置性结合其他对于样式调整的参数，Avatar 组件不仅仅适用于头像这一种业务场景了，请灵活使用。

## 内容优先级

image > alt > icon。

## imgSize

此参数决定头像框内部的图片占整个头像框的比例，三个档位 s、m、l 分别对应 1/3、2/3、铺满。多数业务场景都是铺满使用的，但是有些界面设计要求使用 png 格式图片，此时可能需要使用此参数调整使页面有呼吸感。

## injClass

通过 injClass 参数可以向组件内部 button 元素注入 CSS 名称（不仅限于 Tailwind CSS），这将使组件样式有更多自定义可能性，示例中通过 injClass 实现了自定义背景色和边框颜色。

若注入的 class 没生效，请在注入的 class 名称前添加“!” ，可参考 [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier)。

## 头像组

v0.4.0 开始支持头像组，头像组的使用场景是在头像框内部显示多个头像，例如群聊头像、评论头像等。传入由 Avatar Props 组成的数组即可，头像组有自己的 Props 用于控制不同样式。

默认顶层显示头像总数，可通过 top 参数控制顶层显示内容，可选值有 totle（显示头像总数）、add（新增头像 Icon）、null（不显示）、Snippet（自定义顶层内容）。

头像组 Props 自己也有一个 injClass，可为头像组注入 Class 名称，一般用于当默认边框颜色与背景色不统一时传入传入 ring 的颜色使其统一。



================================================
FILE: docs/mds/components/avatar/guide_en.md
================================================
> Avatar uses icons ri-user-3-line and ri-user-add-line. Please ensure these icons are included in your project's symbol.svg file. For detailed information, please refer to [STDF-Guide-Icon](https://stdf.design/guide/icon).

## Content Description

image accepts relative or absolute image paths, which will be converted to the src attribute of an img tag internally; alt displays the input text directly; icon accepts Icon Props to render avatar content using the Icon component, please refer to Icon API; if image, alt, and icon are not provided, the Avatar component will display a default user icon using the Icon component.

With the configurability of content combined with other style adjustment parameters, the Avatar component is not limited to just avatar scenarios - please use it flexibly.

## Content Priority

image > alt > icon.

## imgSize

This parameter determines the ratio of the internal image to the entire avatar frame. The three levels s, m, l correspond to 1/3, 2/3, and full coverage respectively. Most business scenarios use full coverage, but some interface designs require PNG format images, in which case this parameter may need to be adjusted to give the page a sense of breathing space.

## injClass

The injClass parameter allows injecting CSS class names (not limited to Tailwind CSS) into the component's internal button element, enabling more customization possibilities for component styles. The example demonstrates custom background color and border color through injClass.

If the injected class doesn't take effect, please add "!" before the class name. Refer to [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier).

## Avatar Group

Starting from v0.4.0, avatar groups are supported. Avatar groups are used to display multiple avatars within an avatar frame, such as group chat avatars or comment avatars. Simply pass in an array composed of Avatar Props, and the avatar group has its own Props to control different styles.

By default, the top layer displays the total number of avatars. The top parameter can control the top layer content, with options including totle (display total avatar count), add (add avatar Icon), null (no display), and Snippet (custom top layer content).

Avatar group Props also has its own injClass, which can inject Class names for the avatar group, typically used to unify the ring color when the default border color doesn't match the background color.



================================================
FILE: docs/mds/components/avatar/version.md
================================================
## 0.5.1

- [!tag|B|3|]修复未传入 altSizeObj 时的默认值问题。

## 0.4.0

- [!tag|A|0|]新增头像组用法。



================================================
FILE: docs/mds/components/avatar/version_en.md
================================================
## 0.5.1

- [!tag|B|3|] Fix the problem of default values when altSizeObj is not passed in.

## 0.4.0

- [!tag|A|0|] Add avatar component.



================================================
FILE: docs/mds/components/badge/api.md
================================================
## Badge Props

| 名称     | 类型                           | 默认值   | 必传 | 说明                                         |
| -------- | ------------------------------ | -------- | ---- | -------------------------------------------- |
| text     | `string`                       | `''`     | N    | 徽标文案。                                   |
| radius   | `'full'\|'sm'\|'none'\|'leaf'` | `'full'` | N    | 圆角风格。                                   |
| isLeft   | `boolean`                      | `false`  | N    | 是否位于左侧（仅 isInner 为 false 时生效）。 |
| isShow   | `boolean`                      | `true`   | N    | 是否显示。                                   |
| offsetY  | `number`                       | `0`      | N    | 上下偏移量（仅 isInner 为 false 时生效）。   |
| offsetX  | `number`                       | `0`      | N    | 左右偏移量（仅 isInner 为 false 时生效）。   |
| isInner  | `boolean`                      | `false`  | N    | 是否位于内部。                               |
| injClass | `string`                       | `''`     | N    | 注入 CSS 名称。                              |

## Badge Snippets

| 名称     | 类型                                                                | 参数 | 说明                                             |
| -------- | ------------------------------------------------------------------- | ---- | ------------------------------------------------ |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | `isInner` 为 false 时作为 Badge 相对位置的内容。 |



================================================
FILE: docs/mds/components/badge/api_en.md
================================================
## Badge Props

| Name     | Type                           | Default  | Required | Description                                                         |
| -------- | ------------------------------ | -------- | -------- | ------------------------------------------------------------------- |
| text     | `string`                       | `''`     | N        | Badge text content.                                                 |
| radius   | `'full'\|'sm'\|'none'\|'leaf'` | `'full'` | N        | Border radius style.                                                |
| isLeft   | `boolean`                      | `false`  | N        | Whether to position on the left (only works when isInner is false). |
| isShow   | `boolean`                      | `true`   | N        | Whether to show the badge.                                          |
| offsetY  | `number`                       | `0`      | N        | Vertical offset (only works when isInner is false).                 |
| offsetX  | `number`                       | `0`      | N        | Horizontal offset (only works when isInner is false).               |
| isInner  | `boolean`                      | `false`  | N        | Whether to position inside.                                         |
| injClass | `string`                       | `''`     | N        | Injected CSS class name.                                            |

## Badge Snippets

| Name     | Type                                                                | Params | Description                                             |
| -------- | ------------------------------------------------------------------- | ------ | ------------------------------------------------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -      | Content for relative positioning when isInner is false. |



================================================
FILE: docs/mds/components/badge/FAQ.md
================================================



================================================
FILE: docs/mds/components/badge/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/badge/guide.md
================================================
## 搭配使用

Badge 组件一般位于内容的右上角，所以常规使用时请将主体内容作为默认 Snippet 传入。同时 Badge 是相对于主体内容定位的，所以不会影响主体内容的布局。

但是一些特殊组件如 Cell，Badge 有可能位于组件内部指定位置，这时候可以使用 `isInner` 属性将 Badge 作为内部元素，放置位置由组件内部决定，请参考示例。

## offsetY 与 offsetX

Badge 组件默认位置是相对于主体内容右上角，左右和上下偏移量分别是 Badge 自身宽高的一半，但是由于内部内容的不确定性和复杂性，offsetY 与 offsetX 可以用来在原本基础上再调整 Badge 的位置，使其满足更多的需求。

## 叶形圆角

当 radius 为 `'leaf'` 时，Badge 圆角风格为叶形，同时叶形方向会与当前位置关联。

## CSS 注入

通过 injClass 参数可以向 Badge 组件内部注入 CSS 名称（不仅限于 Tailwind CSS），这将使组件样式有更多自定义可能性，示例中通过 injClass 实现了自定义背景色与边框。

若注入的 class 没生效，请在注入的 class 名称前添加“!” ，可参考 [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier)。



================================================
FILE: docs/mds/components/badge/guide_en.md
================================================
## Usage

The `Badge` component is usually placed in the upper right corner of the content, so when used conventionally, please pass the main content as the default Snippet. Since the `Badge` is positioned relative to the main content, it will not affect the layout of the main content.

However, for some special components, such as `Cell`, the `Badge` may be placed in a specific position within the component. In this case, you can use the `isInner` attribute to position the `Badge` as an inner element, with the placement determined by the component itself. See the example for reference.

## `offsetY` and `offsetX`

By default, the `Badge` component is positioned relative to the upper right corner of the main content, and the left and top offsets are half the width and height of the `Badge`, respectively. However, due to the uncertainty and complexity of the internal content, `offsetY` and `offsetX` can be used to adjust the position of the `Badge` based on the original position, in order to meet more requirements.

## Leaf-shaped Corner Radius

When `radius` is set to `'leaf'`, the corner style of the `Badge` is leaf-shaped, and the direction of the leaves is associated with the current position.

## Injecting CSS

The `injClass` parameter can be used to inject custom CSS class names (not limited to Tailwind CSS) into the `Badge` component, which allows for further customization of the component's appearance. For example, the example uses `injClass` to customize the background color and border of the `Badge`.

If the injected class name does not take effect, add a `!` before the class name, as demonstrated in the [Tailwind Important Modifier](https://tailwindcss.com/docs/configuration#important-modifier).



================================================
FILE: docs/mds/components/badge/version.md
================================================



================================================
FILE: docs/mds/components/badge/version_en.md
================================================



================================================
FILE: docs/mds/components/bottomSheet/api.md
================================================
## BottomSheet Props

| 名称            | 类型                                                      | 默认值                       | 必传 | 说明                               |
| --------------- | --------------------------------------------------------- | ---------------------------- | ---- | ---------------------------------- |
| visible         | `boolean`                                                 | `false`                      | N    | 是否显示。                         |
| title           | `string`                                                  | 当前语言的 bottomSheet.title | N    | 标题。                             |
| titleAlign      | `'left'\|'center'\|'right'`                               | `'left'`                     | N    | 标题对齐方式。                     |
| showBackIcon    | `boolean`                                                 | `false`                      | N    | 是否显示返回图标。                 |
| closeContent    | `'downIcon'\|'closeIcon'\|''\|string`                     | `'downIcon'`                 | N    | 关闭区域内容。                     |
| showDivider     | `boolean`                                                 | `true`                       | N    | 是否显示分割线。                   |
| duration        | `number`                                                  | `450`                        | N    | 过渡动画出现时间，单位：ms。       |
| outDuration     | `number`                                                  | `240`                        | N    | 过渡动画退出时间，单位：ms。       |
| mask            | [`Mask`](https://stdf.design/components?nav=mask&tab=1) | `{}`                         | N    | 遮罩层参数。                       |
| maskClosable    | `boolean`                                                 | `false`                      | N    | 点击遮罩层是否关闭。               |
| zIndex          | `number`                                                  | `600`                        | N    | z-index。                          |
| stayHeightList  | `number[]`                                                | `[10, 50, 90]`               | N    | 固定高度列表。                     |
| stayHeightIndex | `number`                                                  | `1`                          | N    | 初始固定高度索引。                 |
| closeHeight     | `number`                                                  | `0`                          | N    | 滑动结束时位置低于此高度自动关闭。 |
| radius          | `'none'\|'middle'\|'full'`                                | `'full'`                     | N    | 圆角风格。                         |

## BottomSheet Events

| 名称           | 类型                       | 参数                | 描述                                                      |
| -------------- | -------------------------- | ------------------- | --------------------------------------------------------- |
| onclose        | `() => void`               | -                   | 浮窗关闭时触发。                                          |
| onclickMask    | `() => void`               | -                   | 点击浮窗遮罩时触发，即使 maskClosable 为 false 也会触发。 |
| onback         | `() => void`               | -                   | 点击左侧返回图标时触发。                                  |
| onheightChange | `(height: number) => void` | height - 当前高度。 | 滑动结束时触发。                                          |

## BottomSheet Snippets

| 名称     | 类型                                                                | 参数 | 说明   |
| -------- | ------------------------------------------------------------------- | ---- | ------ |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 内容。 |



================================================
FILE: docs/mds/components/bottomSheet/api_en.md
================================================
## BottomSheet Props

| Name            | Type                                                      | Default                        | Required | Description                                                            |
| --------------- | --------------------------------------------------------- | ------------------------------ | -------- | ---------------------------------------------------------------------- |
| visible         | `boolean`                                                 | `false`                        | N        | Whether to display.                                                    |
| title           | `string`                                                  | Current lang bottomSheet.title | N        | Title.                                                                 |
| titleAlign      | `'left'\|'center'\|'right'`                               | `'left'`                       | N        | Title alignment.                                                       |
| showBackIcon    | `boolean`                                                 | `false`                        | N        | Whether to show back icon.                                             |
| closeContent    | `'downIcon'\|'closeIcon'\|''\|string`                     | `'downIcon'`                   | N        | Close area content.                                                    |
| showDivider     | `boolean`                                                 | `true`                         | N        | Whether to show divider.                                               |
| duration        | `number`                                                  | `450`                          | N        | Transition animation appear time, unit: ms.                            |
| outDuration     | `number`                                                  | `240`                          | N        | Transition animation exit time, unit: ms.                              |
| mask            | [`Mask`](https://stdf.design/components?nav=mask&tab=1) | `{}`                           | N        | Mask parameters.                                                       |
| maskClosable    | `boolean`                                                 | `false`                        | N        | Whether to close when clicking mask.                                   |
| zIndex          | `number`                                                  | `600`                          | N        | z-index.                                                               |
| stayHeightList  | `number[]`                                                | `[10, 50, 90]`                 | N        | Fixed height list.                                                     |
| stayHeightIndex | `number`                                                  | `1`                            | N        | Initial fixed height index.                                            |
| closeHeight     | `number`                                                  | `0`                            | N        | Auto close when position is lower than this height after sliding ends. |
| radius          | `'none'\|'middle'\|'full'`                                | `'full'`                       | N        | Border radius style.                                                   |

## BottomSheet Events

| Name           | Type                       | Parameters              | Description                                                  |
| -------------- | -------------------------- | ----------------------- | ------------------------------------------------------------ |
| onclose        | `() => void`               | -                       | Triggered when popup closes.                                 |
| onclickMask    | `() => void`               | -                       | Triggered when clicking mask, even if maskClosable is false. |
| onback         | `() => void`               | -                       | Triggered when clicking left back icon.                      |
| onheightChange | `(height: number) => void` | height - Current height | Triggered when sliding ends.                                 |

## BottomSheet Snippets

| Name     | Type                                                                | Parameters | Description          |
| -------- | ------------------------------------------------------------------- | ---------- | -------------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | BottomSheet content. |



================================================
FILE: docs/mds/components/bottomSheet/FAQ.md
================================================



================================================
FILE: docs/mds/components/bottomSheet/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/bottomSheet/guide.md
================================================
## BottomSheet 与 Popup

在 STDF 的设计思路内，BottomSheet 与 Popup 都属于界面内的浮动交互，一般用于页面内的二级操作场景，在组件使用上有一些相似之处。**但弹出层 Popup 是「层」的概念，而底部浮窗 BottomSheet 是「窗」的概念**。

Popup 作为弹出层，内部一般不宜做比较复杂步骤的交互，默认点击遮罩层就可以关闭，但可以自定义弹出的位置、大小、过渡动画、方向、样式等多项参数。**重样式轻逻辑。**

BottomSheet 作为底部浮窗，就只能从底部弹出。「浮」体现在可以通过滑动其内部的头部区域来控制其固定高度；而「窗」区别于「层」的是，BottomSheet 有自己的头部区域，可以自定义头部内容，并派发出关闭、返回、滑动等类似窗口交互的事件，可以用于一些相对复杂的交互场景，默认点击遮罩不可关闭。**重逻辑轻样式。**

## 固定高度

BottomSheet 的高度由 stayHeightList 决定，stayHeightList 是由多个 0-100 正整数组成的数组，将 BottomSheet 在页面上的显示高度按照页面高度百分比划分成几个档位，当滑动停止时，BottomSheet 会自动停留在最接近的一个档位高度。stayHeightIndex 表示初始固定高度索引，结合 stayHeightList 决定 BottomSheet 的初始高度。

## 滑动关闭

当滑动结束时 BottomSheet 位置相对于页面高度的百分比数值低于 closeHeight 时 BottomSheet 将自动关闭。closeHeight 默认为 0，即不允许滑动关闭。

## 事件

BottomSheet 支持通过 onclose/onback/onheightChange 来监听关闭、返回、固定高度变化事件，而 onclickMask 事件则是点击遮罩层时触发，即使 maskClosable 为 false 也会触发。



================================================
FILE: docs/mds/components/bottomSheet/guide_en.md
================================================
## BottomSheet and Popup

In STDF's design philosophy, both BottomSheet and Popup are floating interactions within the interface, generally used for secondary operation scenarios on the page, and share some similarities in component usage. **However, Popup is a concept of "layer", while BottomSheet is a concept of "window"**.

As a popup layer, Popup generally should not involve complex interaction steps. By default, clicking the mask layer can close it, but you can customize parameters such as popup position, size, transition animation, direction, and style. **Emphasizes style over logic.**

As a bottom window, BottomSheet can only pop up from the bottom. The "floating" aspect is reflected in the ability to control its fixed height by sliding its internal header area. The difference between a "window" and a "layer" is that BottomSheet has its own header area, which can be customized with content and dispatches events like close, back, and slide similar to window interactions. It can be used for relatively complex interaction scenarios, and by default, clicking the mask cannot close it. **Emphasizes logic over style.**

## Fixed Height

The height of BottomSheet is determined by stayHeightList, which is an array of integers between 0-100. It divides the display height of BottomSheet on the page into several levels based on page height percentage. When sliding stops, BottomSheet will automatically stay at the closest level height. stayHeightIndex indicates the initial fixed height index, which, combined with stayHeightList, determines the initial height of BottomSheet.

## Slide to Close

When sliding ends, if BottomSheet's position relative to the page height percentage is lower than closeHeight, BottomSheet will automatically close. closeHeight defaults to 0, meaning sliding to close is not allowed.

## Events

BottomSheet supports monitoring close, back, and fixed height change events through onclose/onback/onheightChange, while the onclickMask event is triggered when clicking the mask layer, even if maskClosable is false.



================================================
FILE: docs/mds/components/bottomSheet/version.md
================================================
## 0.5.1

- [!tag|O|0|]优化滑动动画效果。关联 [PR](https://github.com/any-tdf/stdf/pull/31)。[!contribute|mrlovables|]



================================================
FILE: docs/mds/components/bottomSheet/version_en.md
================================================
## 0.5.1

- [!tag|O|0|] Optimize the sliding animation effect. Related [PR](https://github.com/any-tdf/stdf/pull/31). [!contribute|mrlovables|]



================================================
FILE: docs/mds/components/button/api.md
================================================
## Button Props

| 名称            | 类型                                                                          | 默认值    | 必传 | 说明                           |
| --------------- | ----------------------------------------------------------------------------- | --------- | ---- | ------------------------------ |
| fill            | `'base'\|'line'\|'lineLight'\|'lineTheme'\|'text'\|'textTheme'\|'colorLight'` | `'base'`  | N    | 填充模式。                     |
| state           | `'theme'\|'success'\|'warning'\|'error'\|'info'`                              | `'theme'` | N    | 状态色，theme 表示跟随主题色。 |
| radius          | `'none'\|'sm'\|'xl'\|'2xl'\|'full'`                                           | `'sm'`    | N    | 圆角风格。                     |
| size            | `'full'\|'big'\|'md'\|'sm'\|'auto'`                                           | `'big'`   | N    | 尺寸。                         |
| line            | `'solid'\|'dashed'\|'dotted'`                                                 | `'solid'` | N    | 边框风格。                     |
| heightOut       | `'0'\|'1'\|'2'\|'3'\|'4'`                                                     | `'2'`     | N    | 按钮外部高度。                 |
| heightIn        | `'0'\|'1'\|'2'\|'3'\|'4'`                                                     | `'3'`     | N    | 按钮高度。                     |
| injClass        | `string`                                                                      | `''`      | N    | 注入 CSS 名称。                |
| love            | `boolean`                                                                     | `false`   | N    | 是否开启关爱版。               |
| group           | `boolean`                                                                     | `false`   | N    | 是否使用按钮组。               |
| disabled        | `boolean`                                                                     | `false`   | N    | 是否禁用。                     |
| customSize      | `boolean`                                                                     | `false`   | N    | 是否自定义大小。               |
| customWidth     | `number`                                                                      | `0`       | N    | 自定义宽度。                   |
| customHeight    | `number`                                                                      | `0`       | N    | 自定义高度。                   |
| icon            | [`Icon`](https://stdf.design/components?nav=icon&tab=1)\|`null`             | `null`    | N    | 图标参数。                     |
| loading         | [`Loading`](https://stdf.design/components?nav=loading&tab=1)\|`null`       | `null`    | N    | 加载参数。                     |
| disabledLoading | `boolean`                                                                     | `false`   | N    | 加载时是否禁用。               |
| type            | `'button'\|'reset'\|'submit'`                                                | `button`  | N        | button 的类型。               |

## Button Events

| 名称    | 类型         | 参数 | 描述       |
| ------- | ------------ | ---- | ---------- |
| onclick | `() => void` | -    | 点击触发。 |

## Button Snippets

| 名称     | 类型                                                                | 参数 | 说明       |
| -------- | ------------------------------------------------------------------- | ---- | ---------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 按钮内容。 |



================================================
FILE: docs/mds/components/button/api_en.md
================================================
## Button Props

| Name            | Type                                                                          | Default   | Required | Description                                      |
| --------------- | ----------------------------------------------------------------------------- | --------- | -------- | ------------------------------------------------ |
| fill            | `'base'\|'line'\|'lineLight'\|'lineTheme'\|'text'\|'textTheme'\|'colorLight'` | `'base'`  | N        | Fill mode.                                       |
| state           | `'theme'\|'success'\|'warning'\|'error'\|'info'`                              | `'theme'` | N        | Status color, theme means following theme color. |
| radius          | `'none'\|'sm'\|'xl'\|'2xl'\|'full'`                                           | `'sm'`    | N        | Border radius style.                             |
| size            | `'full'\|'big'\|'md'\|'sm'\|'auto'`                                           | `'big'`   | N        | Size.                                            |
| line            | `'solid'\|'dashed'\|'dotted'`                                                 | `'solid'` | N        | Border style.                                    |
| heightOut       | `'0'\|'1'\|'2'\|'3'\|'4'`                                                     | `'2'`     | N        | Button outer height.                             |
| heightIn        | `'0'\|'1'\|'2'\|'3'\|'4'`                                                     | `'3'`     | N        | Button height.                                   |
| injClass        | `string`                                                                      | `''`      | N        | Inject CSS class name.                           |
| love            | `boolean`                                                                     | `false`   | N        | Whether to enable care version.                  |
| group           | `boolean`                                                                     | `false`   | N        | Whether to use button group.                     |
| disabled        | `boolean`                                                                     | `false`   | N        | Whether to disable.                              |
| customSize      | `boolean`                                                                     | `false`   | N        | Whether to use custom size.                      |
| customWidth     | `number`                                                                      | `0`       | N        | Custom width.                                    |
| customHeight    | `number`                                                                      | `0`       | N        | Custom height.                                   |
| icon            | [`Icon`](https://stdf.design/components?nav=icon&tab=1)\|`null`               | `null`    | N        | Icon props.                                      |
| loading         | [`Loading`](https://stdf.design/components?nav=loading&tab=1)\|`null`         | `null`    | N        | Loading props.                                   |
| disabledLoading | `boolean`                                                                     | `false`   | N        | Whether to disable when loading.                 |
| type            | `'button'\|'reset'\|'submit'`                                                 | `button`  | N        | The default behavior of the button               |

## Button Events

| Name    | Type         | Parameters | Description         |
| ------- | ------------ | ---------- | ------------------- |
| onclick | `() => void` | -          | Triggered on click. |

## Button Snippets

| Name     | Type                                                                | Parameters | Description     |
| -------- | ------------------------------------------------------------------- | ---------- | --------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Button content. |



================================================
FILE: docs/mds/components/button/FAQ.md
================================================



================================================
FILE: docs/mds/components/button/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/button/guide.md
================================================
## 默认样式

通过查看大量主流的移动端 UI 设计（包含原生与 web），发现在实际应用中，大块主题色按钮的使用频率比较高，因为它的突出性与品牌属性，非常适合用来引导用户操作。故而 STDF 没有跟随主流组件库的灰色边框按钮作为默认样式，而采用大块主题色填充按钮，应该可以减少使用时的书写代码量。其余样式基本上按照 Tailwind 的样式规则，只是对一些选项做了分类与限定，传入可选外的值将被按照默认值处理。

## 填充模式

填充模式中，line 为线性按钮（幽灵按钮）；lineLight 线性浅色按钮；text 为纯文本按钮；而 lineTheme 与 textTheme 表示对应边框和文字颜色会跟随主题色，包括亮暗模式；colorLight 为带透明度浅色背景按钮，也自动适配亮暗模式。

## 状态色

状态色对应着 STDF 颜色系统的成功、警告、错误、信息四种功能色，请确保在 Tailwind 的配置文件 tailwind.config.js 中已经配置了对应色值，当然也可以根据你的项目自行灵活配置。

## 尺寸

按钮尺寸为 full 和 big 表示块级元素，md、sm、xs 表示行内元素，auto 时按钮宽度由内部元素的宽度决定。

## 边框风格

边框风格（line）必须在填充模式（fill）为 line 或 lineTheme 情况下才会生效。

## CSS 注入

通过 injClass 参数可以向组件内部 button 元素注入 CSS 名称（不仅限于 Tailwind CSS），这将使组件样式有更多自定义可能性，示例中通过 injClass 实现了自定义颜色。

若注入的 class 没生效，请在注入的 class 名称前添加“!” ，可参考 [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier)。

## 按钮组

要使用按钮组可以直接通过在内部 Snippet 放入多个元素，结合 heightOut 与 heightIn 就可以实现。需要注意的是此时点击事件就需要绑定在内部独立元素之上，另外需要通过将 Props 的 group 设置为 true，将不显示整个按钮区域的点击效果。可参考示例。

## 带图标或加载

通过 icon 参数可以向 Button 组件内容区域前注入图标，参数为 Icon 组件的 Props；通过 loading 参数可以向 Button 组件内容区域前注入加载，参数为 Loading 组件的 Props，当传入 loading 时按钮默认禁用，可通过 disabledLoading 参数控制。请参考示例。



================================================
FILE: docs/mds/components/button/guide_en.md
================================================
## Default style

In the practical application of mobile web, the use of large theme color buttons is relatively high, because of its prominence and brand attributes, it is very suitable for guiding users to operate. Therefore, STDF does not follow the gray border button of the mainstream component library as the default style, but uses a large theme color to fill the button, which should reduce the amount of writing code when using it. The rest of the styles are basically in accordance with Tailwind's style rules, but some options are classified and limited, and the incoming optional values ​​will be processed according to the default values.

## Fill pattern

In fill mode, line is a linear button (ghost button), lineLight is a linear light button, text is a plain text button, and lineTheme and textTheme indicate that the corresponding border and text color will follow the theme color, including light and dark colors.

## Status color

The status color corresponds to the four functional colors of success, warning, error, and information of the STDF color system. Please make sure that the corresponding color values ​​have been configured in the Tailwind configuration file tailwind.config.js. Of course, you can also configure it flexibly according to your project.

## Size

The button size is full and big for block-level elements, md, sm, and xs for inline elements. When auto, the button width is determined by the width of the inner element.

## Border style

The border style (line) will only take effect if the fill mode (fill) is line or lineTheme.

## CSS injection

Through the injClass parameter, you can inject CSS names (not limited to Tailwind CSS) to the button element inside the component, which will allow more customization possibilities for component styles. In the example, injClass implements custom colors.

If the injected class does not take effect, please add "!" before the injected class name, please refer to [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier).

## Button group

To use the button group, you can directly put multiple elements in the inner Snippet, which can be achieved by combining heightOut and heightIn. It should be noted that the click event needs to be bound to the internal independent element at this time. In addition, by setting the group of Props to true, the click effect of the entire button area will not be displayed. Examples are available.

## With icon or loading

Through the icon parameter, you can inject an icon into the content area of the Button component, the parameter is the Props of the Icon component; through the loading parameter, you can inject a loading into the content area of the Button component, the parameter is the Props of the Loading component. When loading is passed in, the button is disabled by default, which can be controlled by the disabledLoading parameter. Please refer to the example.



================================================
FILE: docs/mds/components/button/version.md
================================================
<!-- "[!tag|A|0|]"表示一个 tag，其中 A 表示新增，B 表示 BUG，O 表示优化，第二个数字表示 BUG 等级，0 暂无意义。 -->
<!-- "[!issue|dufu1991|]"表示一个 issue 提出者，其中 dufu1991 是提出者的 id。 -->
<!-- "[!contribute|dufu1991|]"表示一个贡献者，其中 eric1932 是贡献者的 id。 -->

<!-- 记得带上版本号和更新日期，以下是一个示例：

## 0.0.1

-   [!tag|B|1|] 严重 BUG。[!contribute|dufu1991|][!issue|dufu1991|]
-   [!tag|B|2|] 一般 BUG。
-   [!tag|B|3|] 轻微 BUG。
-   [!tag|O|0|] 优化。
-   [!tag|A|0|] 新增。
 -->

## 1.0.4

- [!tag|A|0|] 新增 `type` 属性 [PR#43](https://github.com/any-tdf/stdf/pull/43)，相关 [MDN](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Reference/Elements/button#type)。[!contribute|arithefirst|]

## 0.5.2

- [!tag|O|0|]调整 icon 与 loading 参数，使其可同时存在。

## 0.5.1

- [!tag|A|0|]支持通过传入 iconLoading 参数实现在按钮内容前显示图标或者加载。



================================================
FILE: docs/mds/components/button/version_en.md
================================================
## 1.0.4

- [!tag|A|0|] Added `type` property [PR#43](https://github.com/any-tdf/stdf/pull/43), related [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/button#type). [!contribute|arithefirst|]

## 0.5.2

- [!tag|O|0|]Adjust the icon and loading parameters to allow them to coexist.

## 0.5.1

- [!tag|A|0|]Support displaying icons or loading before the button content by passing in the iconLoading parameter.



================================================
FILE: docs/mds/components/calendar/api.md
================================================
## Calendar Props

| 名称            | 类型                                                          | 默认值                               | 必传 | 说明                                         |
| --------------- | ------------------------------------------------------------- | ------------------------------------ | ---- | -------------------------------------------- |
| visible         | `boolean`                                                     | `false`                              | N    | 是否显示。                                   |
| startMonth      | `string`                                                      | 当前月份前第 6 个月                  | N    | 开始月份，格式为 YYYYMM。                    |
| endMonth        | `string`                                                      | 当前月份后第 6 个月                  | N    | 结束月份，格式为 YYYYMM。                    |
| initMonth       | `string`                                                      | 当前月份                             | N    | 初始化时显示月份，格式为 YYYYMM。            |
| mode            | `'single'\|'multiple'\|'range'`                               | `'single'`                           | N    | 选择模式。                                   |
| startSunday     | `boolean`                                                     | `false`                              | N    | 是否从周日开始。                             |
| weekendRed      | `boolean`                                                     | `false`                              | N    | 是否周末红色。                               |
| monthCard       | `boolean`                                                     | `true`                               | N    | 月数据是否使用卡片样式。                     |
| monthMark       | `boolean`                                                     | `false`                              | N    | 是否显示月份水印。                           |
| monthMarkSize   | `'3xl'\|'4xl'\|'5xl'\|'6xl'\|'7xl'\|'8xl'\|'9xl'`             | `'7xl'`                              | N    | 月份水印文字大小。                           |
| height          | `number`                                                      | `50`                                 | N    | 显示高度占页面高度百分比。                   |
| infoDates       | `InfoDate[]`                                                  | `[]`                                 | N    | 需要显示信息的日期。                         |
| disabledDates   | `string[]`                                                    | `[]`                                 | N    | 不可选的日期。                               |
| radius          | `'none'\|'sm'\|'xl'\|'2xl'`                                   | `'xl'`                               | N    | 选定日期的圆角风格。                         |
| showSelectedDay | `boolean`                                                     | `true`                               | N    | 多选和范围选择时确定按钮是否显示已选天数。   |
| confirmText     | `string`                                                      | 当前语言的 calendarLang.confirmText  | N    | 确定按钮文案。                               |
| selectedText    | `string`                                                      | 当前语言的 calendarLang.selectedText | N    | showSelectedDay 为 true 时确定按钮部分文案。 |
| dayText         | `string`                                                      | 当前语言的 calendarLang.dayText      | N    | showSelectedDay 为 true 时确定按钮部分文案。 |
| quickSelects    | `('week'\|'month'\|'quarter'\|number)[]`                      | `[]`                                 | N    | 快捷选择配置参数。                           |
| includeToday    | `boolean`                                                     | `false`                              | N    | 快速选择天数时是否包含今天。                 |
| highlightToday  | `boolean`                                                     | `true`                               | N    | 是否高亮今天。                               |
| useAnimation    | `boolean`                                                     | `true`                               | N    | 自动滚动到指定月份时是否使用动画。           |
| outFormat       | `string`                                                      | `'YMD'`                              | N    | 返回日期数据格式。                           |
| popup           | [`Popup`](https://stdf.design/components?nav=popup&tab=1)   | `{}`                                 | N    | 弹出层参数。                                 |
| button          | [`Button`](https://stdf.design/components?nav=button&tab=1) | `{}`                                 | N    | 确定按钮参数。                               |
| clear           | `boolean`                                                     | `true`                               | N    | 关闭时是否清空已选日期。                     |

## Calendar Events

| 名称      | 类型                        | 参数                                           | 描述                 |
| --------- | --------------------------- | ---------------------------------------------- | -------------------- |
| onclose   | `() => void`                | -                                              | 关闭时触发。         |
| onconfirm | `(dates: string[]) => void` | dates - 所有选定日期格式化后字符串组成的数组。 | 点击确定按钮时触发。 |

## InfoDate Props

| 名称 | 类型     | 默认值 | 必传 | 说明                               |
| ---- | -------- | ------ | ---- | ---------------------------------- |
| date | `string` | -      | Y    | 由年月日 YYYYMMDD 格式组成的数组。 |
| info | `string` | -      | Y    | 信息内容，长度尽量短。             |



================================================
FILE: docs/mds/components/calendar/api_en.md
================================================
## Calendar Props

| Name            | Type                                                          | Default                                    | Required | Description                                                                    |
| --------------- | ------------------------------------------------------------- | ------------------------------------------ | -------- | ------------------------------------------------------------------------------ |
| visible         | `boolean`                                                     | `false`                                    | N        | Whether to show the calendar.                                                  |
| startMonth      | `string`                                                      | 6 months before current month              | N        | Start month in YYYYMM format.                                                  |
| endMonth        | `string`                                                      | 6 months after current month               | N        | End month in YYYYMM format.                                                    |
| initMonth       | `string`                                                      | Current month                              | N        | Initial display month in YYYYMM format.                                        |
| mode            | `'single'\|'multiple'\|'range'`                               | `'single'`                                 | N        | Selection mode.                                                                |
| startSunday     | `boolean`                                                     | `false`                                    | N        | Whether week starts from Sunday.                                               |
| weekendRed      | `boolean`                                                     | `false`                                    | N        | Whether weekend dates are in red.                                              |
| monthCard       | `boolean`                                                     | `true`                                     | N        | Whether to use card style for month data.                                      |
| monthMark       | `boolean`                                                     | `false`                                    | N        | Whether to show month watermark.                                               |
| monthMarkSize   | `'3xl'\|'4xl'\|'5xl'\|'6xl'\|'7xl'\|'8xl'\|'9xl'`             | `'7xl'`                                    | N        | Month watermark text size.                                                     |
| height          | `number`                                                      | `50`                                       | N        | Display height as percentage of page height.                                   |
| infoDates       | `InfoDate[]`                                                  | `[]`                                       | N        | Dates that need to display information.                                        |
| disabledDates   | `string[]`                                                    | `[]`                                       | N        | Disabled dates.                                                                |
| radius          | `'none'\|'sm'\|'xl'\|'2xl'`                                   | `'xl'`                                     | N        | Border radius style for selected dates.                                        |
| showSelectedDay | `boolean`                                                     | `true`                                     | N        | Whether to show selected days count in confirm button for multiple/range mode. |
| confirmText     | `string`                                                      | Current language calendarLang.confirmText  | N        | Confirm button text.                                                           |
| selectedText    | `string`                                                      | Current language calendarLang.selectedText | N        | Part of confirm button text when showSelectedDay is true.                      |
| dayText         | `string`                                                      | Current language calendarLang.dayText      | N        | Part of confirm button text when showSelectedDay is true.                      |
| quickSelects    | `('week'\|'month'\|'quarter'\|number)[]`                      | `[]`                                       | N        | Quick selection configuration parameters.                                      |
| includeToday    | `boolean`                                                     | `false`                                    | N        | Whether to include today when using quick select days.                         |
| highlightToday  | `boolean`                                                     | `true`                                     | N        | Whether to highlight today.                                                    |
| useAnimation    | `boolean`                                                     | `true`                                     | N        | Whether to use animation when auto-scrolling to specified month.               |
| outFormat       | `string`                                                      | `'YMD'`                                    | N        | Output date format.                                                            |
| popup           | [`Popup`](https://stdf.design/components?nav=popup&tab=1)   | `{}`                                       | N        | Popup parameters.                                                              |
| button          | [`Button`](https://stdf.design/components?nav=button&tab=1) | `{}`                                       | N        | Confirm button parameters.                                                     |
| clear           | `boolean`                                                     | `true`                                     | N        | Whether to clear selected dates when closing.                                  |

## Calendar Events

| Name      | Type                        | Parameters                                        | Description                 |
| --------- | --------------------------- | ------------------------------------------------- | --------------------------- |
| onclose   | `() => void`                | -                                                 | Triggered when closing.     |
| onconfirm | `(dates: string[]) => void` | dates - Array of formatted selected date strings. | Triggered on confirm click. |

## InfoDate Props

| Name | Type     | Default | Required | Description                           |
| ---- | -------- | ------- | -------- | ------------------------------------- |
| date | `string` | -       | Y        | Date in YYYYMMDD format.              |
| info | `string` | -       | Y        | Information content, keep it concise. |



================================================
FILE: docs/mds/components/calendar/FAQ.md
================================================



================================================
FILE: docs/mds/components/calendar/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/calendar/guide.md
================================================
## 使用场景

Calendar 组件用于选择单个日期、多个日期或日期范围。

## 注意事项

传入的 startMonth、endMonth、initMonth 必须是 YYYYMM 格式的字符串，且 initMonth 必须在 startMonth 和 endMonth 之间。另外其他传入用到年月或年月日的属性时，请保证传入的数据格式都是 YYYYMM 或 YYYYMMDD，月和日如果不足两位数时，需要在前面补 0。

## 周开始

部分国家或地区在日常生活中习惯将周日作为一周的第一天，但是按照国际标准 [ISO 8601](https://wikipedia.org/wiki/ISO_8601) 规定，一周的第一天是周一。同时从「周末」这个词的含义来看，周六周日应该是一周的末尾，而不是开头。

所以 Calendar 组件默认周一作为一周的第一天，也建议大家尽量以此为标准。如果需要将周日作为一周的第一天，可以通过 startSunday 属性来设置。

## infoDates

Calendar 组件可以通过传入 infoDates 属性来显示某天的一些提示信息，建议传入的 info 信息长度尽量简短，否则可能造成日历显示不美观。

## disabledDates

Calendar 组件可以通过传入 disabledDates 属性来禁用某些日期，此时如果是范围选择模式，选择的日期中会自动过滤掉禁用的日期。

## 快捷选择

当处于范围选择模式时，Calendar 组件可以通过传入 quickSelects 这个数组属性来决定启用哪些快捷选择方式。

- 当传入的 quickSelects 包含 week 字符时，可以点击当前周快速选定一周的日期范围；当传入的 quickSelects 包含 month 字符时，可以点击当前月快速选定一个月的日期范围；当传入的 quickSelects 包含 quarter 字符时，可以点击当前季度快速选定一个季度的日期范围。
- 当传入的 quickSelects 包含正整数时，组件内部会显示对应的未来几天的快捷选择按钮，比如传入 [3, 7] 时，会显示未来 3 天、7 天的快捷选择按钮，点击后会自动选定对应的日期范围。
- 当传入的 quickSelects 包含负整数时，组件内部会显示对应的过去几天的快捷选择按钮，比如传入 [-3, -7] 时，会显示最近 3 天、7 天的快捷选择按钮，点击后会自动选定对应的日期范围。
- 当使用快捷选择指定天数时，默认是不包含当天的，可以通过修改 includeToday 的值来决定是否包含今天，请参考示例。

## 返回日期格式

当点击 Calendar 组件底部的确定按钮时，会触发 confirm 事件，此时会将当前选中的所有日期数据字符组成数组返回。每个日期的数据格式由 outFormat 决定，返回后的格式中的年与 outFormat 中的 Y 对应，月与 outFormat 中的 M 对应，日与 outFormat 中的 D 对应。请参考示例。

## 月份水印

Calendar 组件可以通过传入 monthMark 属性来决定是否在日历的每个月内显示月份文字的水印，考虑不同语言的月份文字长度不同，可以通过 monthMarkSize 属性来设置水印的字体大小。

## 说明

Calendar 是在 Popup 基础上封装的，通过预先定义一些 Popup 的 Props 实现，因此可以通过传入 Popup 的属性来实现不同的效果。比如示例中通过设置 popup 的 radius 改变圆角风格。

Calendar 内底部的确定按钮使用了 Button 组件，可以通过传入 button 参数来自定义按钮的样式，请参考示例。



================================================
FILE: docs/mds/components/calendar/guide_en.md
================================================
## Usage

The Calendar component is used to select a single date, multiple dates, or a range of dates.

## Notes

The startMonth, endMonth, and initMonth passed in must be strings in the format YYYYMM, and initMonth must be between startMonth and endMonth. Additionally, when other attributes that use year-month or year-month-day are used, please ensure that the data format passed in is either YYYYMM or YYYYMMDD. If the month or day is less than two digits long, add a 0 before it.

## Week Start Day

Some countries or regions habitually consider Sunday as the first day of the week in daily life. However, according to international standard [ISO 8601](https://wikipedia.org/wiki/ISO_8601), Monday is considered as the first day of the week. Also from the meaning of "weekend," Saturday and Sunday should be at the end of a week rather than at its beginning.

Therefore by default Calendar considers Monday as the first day of a week; we also recommend using this as your standard whenever possible. If you need to set Sunday as your first day instead for some reason you can do so with startSunday attribute.

## infoDates

Calendar can display some prompt information about certain days by passing an infoDates attribute. It's recommended to keep these messages short; otherwise they may cause calendar display issues.

## disabledDates

Calendar can disable certain dates by passing disabledDates attribute; if range selection mode is enabled then any selected date(s) will automatically filter out any disabled ones.

## Quick Selections

When in range selection mode Calendar can enable quick selections via passing an array property called quickSelects:

- When quickSelects contains 'week', clicking on current week will quickly select all dates within that same week.
- When quickSelects contains 'month', clicking on current month will quickly select all dates within that same month.
- When quickSelects contains 'quarter', clicking on current quarter will quickly select all dates within that same quarter.
- When positive integers are included inside quickSelects array component internally displays corresponding future days' shortcut buttons (e.g., [3，7] shows shortcuts for next three days & seven days).
- Similarly when negative integers are included inside quickSelects array component internally displays corresponding past few days' shortcut buttons (e.g., [-3,-7] shows shortcuts for last three & seven days).
- By default when specifying number of days through Quick Select feature today's date isn't included but includeToday value can be modified accordingly - see example below.

## Return Date Format

When user clicks confirm button located at bottom part of Calendar component it triggers confirm event which returns an array containing character data representing currently selected date(s). The format for each individual date depends upon outFormat parameter: Year corresponds with Y from outFormat while Month corresponds with M from outFormat and Day corresponds with D from outFormat - see example below.

## Month Watermark

By setting monthMark property Calendar component decides whether watermark text displaying name(s)of months appears inside every calendar month view; since different languages have varying lengths for their respective names one may adjust font size via monthMarkSize property.
]=[]

### Note

Calendar was built atop Popup module utilizing predefined Props thus allowing various effects achieved through properties passed into Popup object itself e.g., radius style change demonstrated via sample code snippet provided hereunder.

Calendar's Confirm Button uses Button Component enabling customization options available through button parameter - refer to examples provided below.



================================================
FILE: docs/mds/components/calendar/version.md
================================================
## 1.0.3

- [!tag|A|0|]新增 `clear` 属性，关闭时可保留已选日期。

## 0.0.8

- [!tag|B|2|]修复显示快捷选项时已选项的高亮样式。



================================================
FILE: docs/mds/components/calendar/version_en.md
================================================
## 1.0.3

- [!tag|A|0|]Add `clear` property, keep the selected date when closed.

## 0.0.8

- [!tag|B|2|]Fix the highlighted style that was selected when shortcut options were displayed.



================================================
FILE: docs/mds/components/cell/api.md
================================================
## Cell Props

| 名称         | 类型                                                              | 默认值    | 必传 | 说明                   |
| ------------ | ----------------------------------------------------------------- | --------- | ---- | ---------------------- |
| title        | `string`                                                          | `''`      | N    | 标题。                 |
| detail       | `string`                                                          | `''`      | N    | 右侧详情。             |
| left         | `null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `null`    | N    | 最左侧内容。           |
| right        | `null\|'arrow'\|CellRight`                                        | `'arrow'` | N    | 最右侧内容。           |
| subTitle     | `string`                                                          | `''`      | N    | 左侧次级标题。         |
| info         | `string`                                                          | `''`      | N    | 右侧次级信息。         |
| line         | `boolean`                                                         | `false`   | N    | 是否显示底部分割线。   |
| my           | `'0'\|'1'\|'2'\|'3'\|'4'\|'6'\|'8'`                               | `'4'`     | N    | 上下间距。             |
| mx           | `'0'\|'1'\|'2'\|'3'\|'4'\|'6'\|'8'`                               | `'2'`     | N    | 左右间距。             |
| radius       | `'none'\|'sm'\|'md'\|'lg'\|'xl'\|'2xl'\|'full'`                   | `'lg'`    | N    | 圆角风格。             |
| switchActive | `boolean`                                                         | `false`   | N    | 开关状态。             |
| shadow       | `'none'\|'xs'\|'sm'\|'md'\|'lg'\|'xl'\|'2xl'`                     | `'xs'`    | N    | 阴影风格。             |
| injClass     | `string`                                                          | `''`      | N    | 注入 CSS 名称。        |
| love         | `boolean`                                                         | `false`   | N    | 是否开启关爱版。       |
| clickAll     | `boolean`                                                         | `true`    | N    | 是否点击整行触发事件。 |

## Cell Events

| 名称    | 类型         | 参数 | 描述     |
| ------- | ------------ | ---- | -------- |
| onclick | `() => void` | -    | 点击触发 |

## Cell Snippets

| 名称        | 类型                                                                | 参数 | 说明          |
| ----------- | ------------------------------------------------------------------- | ---- | ------------- |
| leftChild   | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 最左侧内容。  |
| rightChild  | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 最右侧内容。  |
| detailChild | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | Detail 内容。 |

## CellGroup Props

| 名称   | 类型                                            | 默认值 | 必传 | 说明       |
| ------ | ----------------------------------------------- | ------ | ---- | ---------- |
| my     | `'0'\|'1'\|'2'\|'3'\|'4'\|'6'\|'8'`             | `'4'`  | N    | 上下间距。 |
| mx     | `'0'\|'1'\|'2'\|'3'\|'4'\|'6'\|'8'`             | `'2'`  | N    | 左右间距。 |
| radius | `'none'\|'sm'\|'md'\|'lg'\|'xl'\|'2xl'\|'full'` | `'lg'` | N    | 圆角风格。 |
| shadow | `'none'\|'xs'\|'sm'\|'md'\|'lg'\|'xl'\|'2xl'`   | `'xs'` | N    | 阴影风格。 |

## CellGroup Snippets

| 名称     | 类型                                                                | 参数 | 说明                               |
| -------- | ------------------------------------------------------------------- | ---- | ---------------------------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | Cell Group 内容，一般是多个 Cell。 |

## CellRight

```javascript
type CellRight = {
    type: 'switch' | 'icon',
    switch?: Switch,
    icon?: Icon,
};
```



================================================
FILE: docs/mds/components/cell/api_en.md
================================================
## Cell Props

| Name         | Type                                                              | Default   | Required | Description                  |
| ------------ | ----------------------------------------------------------------- | --------- | -------- | ---------------------------- |
| title        | `string`                                                          | `''`      | N        | Title.                       |
| detail       | `string`                                                          | `''`      | N        | Right detail.                |
| left         | `null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `null`    | N        | Leftmost content.            |
| right        | `null\|'arrow'\|CellRight`                                        | `'arrow'` | N        | Rightmost content.           |
| subTitle     | `string`                                                          | `''`      | N        | Left subtitle.               |
| info         | `string`                                                          | `''`      | N        | Right secondary info.        |
| line         | `boolean`                                                         | `false`   | N        | Show bottom divider.         |
| my           | `'0'\|'1'\|'2'\|'3'\|'4'\|'6'\|'8'`                               | `'4'`     | N        | Vertical margin.             |
| mx           | `'0'\|'1'\|'2'\|'3'\|'4'\|'6'\|'8'`                               | `'2'`     | N        | Horizontal margin.           |
| radius       | `'none'\|'base'\|'md'\|'lg'\|'xl'\|'2xl'\|'full'`                 | `'lg'`    | N        | Border radius style.         |
| switchActive | `boolean`                                                         | `false`   | N        | Switch state.                |
| shadow       | `'none'\|'xs'\|'sm'\|'md'\|'lg'\|'xl'\|'2xl'`                   | `'xs'`    | N        | Shadow style.                |
| injClass     | `string`                                                          | `''`      | N        | Inject CSS class name.       |
| love         | `boolean`                                                         | `false`   | N        | Enable care version.         |
| clickAll     | `boolean`                                                         | `true`    | N        | Click entire row to trigger. |

## Cell Events

| Name    | Type         | Params | Description    |
| ------- | ------------ | ------ | -------------- |
| onclick | `() => void` | -      | Click callback |

## Cell Snippets

| Name        | Type                                                                | Params | Description        |
| ----------- | ------------------------------------------------------------------- | ------ | ------------------ |
| leftChild   | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -      | Leftmost content.  |
| rightChild  | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -      | Rightmost content. |
| detailChild | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -      | Detail content.    |

## CellGroup Props

| Name   | Type                                              | Default | Required | Description        |
| ------ | ------------------------------------------------- | ------- | -------- | ------------------ |
| my     | `'0'\|'1'\|'2'\|'3'\|'4'\|'6'\|'8'`               | `'4'`   | N        | Vertical margin.   |
| mx     | `'0'\|'1'\|'2'\|'3'\|'4'\|'6'\|'8'`               | `'2'`   | N        | Horizontal margin. |
| radius | `'none'\|'base'\|'md'\|'lg'\|'xl'\|'2xl'\|'full'` | `'lg'`  | N        | Border radius.     |
| shadow | `'none'\|'xs'\|'sm'\|'md'\|'lg'\|'xl'\|'2xl'`     | `'xs'`  | N        | Shadow style.      |

## CellGroup Snippets

| Name     | Type                                                                | Params | Description                                      |
| -------- | ------------------------------------------------------------------- | ------ | ------------------------------------------------ |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -      | Cell Group content, usually multiple Cell items. |

## CellRight

```javascript
type CellRight = {
	type: 'switch' | 'icon';
	switch?: Switch;
	icon?: Icon;
};
```



================================================
FILE: docs/mds/components/cell/FAQ.md
================================================



================================================
FILE: docs/mds/components/cell/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/cell/guide.md
================================================
> Cell 使用了图标 ri-arrow-right-s-line，请确保项目的 symbol.svg 文件中包含此图标。详细信息请参考 [STDF-指南 - 图标](https://stdf.design/guide/icon)。

## 说明

组件库开发中满足自定义与上手简单始终是不可兼得的。

Cell 作为移动端使用频率较高的组件，承载的使用场景也比较多，因此可以很明显地看出来 Props 比较多，支持的自定义选项也比较多。

## Snippet

Cell 组件支持 leftChild、rightChild 和 detailChild 三种 Snippet，当传入 leftChild 时 Cell 最左侧内容会被 leftChild 渲染，可参考示例自定义左侧图片；当传入 rightChild 时 Cell 最右侧内容会被 rightChild 渲染，可参考示例自定义右侧图片；当传入 detailChild 时 Cell 右侧详情内容会被 detailChild 渲染，可参考示例自定义右侧详情内容。

## left & right

left 参数支持使用 Icon Props，此时将使用 STDF 的 Icon 组件渲染。

考虑到 Cell 右侧区域使用箭头的场景非常多，组件默认 right 参数为 `'arrow'`，显示箭头。

right 也支持传入 Icon Props，考虑右侧使用开关的场景较多，为了区分是 Switch Props 还是其他 Icon Props，right 增加了一个 type 属性（可选 `'icon'` 和 `'switch'`）用于区分 Icon 和 Switch 组件。

优化：当右侧为 switch 时，点击整个 Cell 区域都会切换 Switch 的开关状态。

具体 Icon Props 与 Switch Props 请查看对应组件 API。

## clickAll

移动端考虑交互的友好性，Cell 默认点击整行都会触发事件，但是考虑场景的多样性，你可以通过将 clickAll 参数设置为 false 来禁用这个功能。只是在特定区域触发事件，比如示例中配合 Switch 组件使用，仅在点击 Switch 时触发事件。

## switchActive

switchActive 值仅在 right 的 type 为 switch 时生效，表示开关状态值。注意，此时 Cell 内部 Switch 的 active 由 switchActive 决定，**请不要在 switch 内部再传入 active**。

## 底部分割线

主要用于组合时，当 Cell 与 Cell 之间有间隔时，可以使用 line 参数控制是否显示底部分割线。

## 组合使用

Cell 组件支持组合使用，可以向 CellGroup 传入 Cell 来实现。为了不影响布局，注意配置单条 Cell 的 my、mx、radius、shadow、line 参数，请参考示例。

## 自定义

使用上下左右间距和顶部底部圆角参数，可以配置出多种 Cell 风格，如果还不能满足，可以使用注入 CSS（injClass）来实现更多自定义的样式，请参考示例。



================================================
FILE: docs/mds/components/cell/guide_en.md
================================================
> Cell uses the icon ri-arrow-right-s-line, please make sure this icon is included in your project's symbol.svg file. For detailed information, please refer to [STDF-Guide-Icon](https://stdf.design/guide/icon).

## Description

In component library development, satisfying both customization and ease of use is always a trade-off.

As a frequently used component in mobile applications, Cell supports many use cases, which is why it has quite a few Props and customization options.

## Snippet

Cell component supports three Snippet: leftChild, rightChild and detailChild. When leftChild is provided, the leftmost content of Cell will be rendered by the leftChild, refer to examples for customizing left images; when rightChild is provided, the rightmost content will be rendered by rightChild, refer to examples for customizing right images; when detailChild is provided, the right detail content will be rendered by detailChild, refer to examples for customizing right detail content.

## left & right

The left parameter supports Icon Props, which will be rendered using STDF's Icon component.

Considering that arrows are commonly used in the right area of Cell, the default right parameter is set to `'arrow'`, displaying an arrow.

right also supports Icon Props. Given that switches are frequently used on the right side, to distinguish between Switch Props and other Icon Props, right includes a type attribute (options are `'icon'` and `'switch'`) to differentiate between Icon and Switch components.

Optimization: When right is set to switch, clicking anywhere in the Cell area will toggle the Switch state.

For specific Icon Props and Switch Props, please refer to the corresponding component APIs.

## clickAll

Considering mobile interaction friendliness, Cell triggers events by default when clicking anywhere in the row. However, for diverse scenarios, you can disable this feature by setting clickAll parameter to false. This restricts event triggering to specific areas, like in examples where it's used with Switch component to only trigger events when clicking the Switch.

## switchActive

switchActive value only takes effect when right's type is switch, indicating the switch state. Note that in this case, the Cell's internal Switch active state is determined by switchActive, **please do not pass active inside switch again**.

## Bottom Divider

Mainly used in combinations, when there are gaps between Cells, you can use the line parameter to control whether to display the bottom divider.

## Combination Usage

Cell component supports combination usage by passing Cells to CellGroup. To avoid affecting the layout, pay attention to configuring individual Cell's my, mx, radius, shadow, line parameters, please refer to examples.

## Customization

Using vertical and horizontal margin parameters and top/bottom border radius parameters, you can configure various Cell styles. If these still don't meet your needs, you can use injected CSS (injClass) to achieve more custom styles, please refer to examples.



================================================
FILE: docs/mds/components/cell/version.md
================================================
## 1.0.3

- [!tag|B|3|]修复右侧箭头未垂直居中问题。
- [!tag|O|0|]减少左右两侧间距。

## 0.2.11

- [!tag|B|2|]修复左右区域上下居中对齐问题。

## 0.2.10

- [!tag|A|0|]增加 `clickAll` 参数，用于控制是否点击整行都触发事件。关联 [Issues](https://github.com/any-tdf/stdf/issues/7)。[!issue|yuedanlabs|]

## 0.0.10

- [!tag|O|0|]增加 title 与右侧 detail 间距。[!contribute|893358308|]



================================================
FILE: docs/mds/components/cell/version_en.md
================================================
## 1.0.3

- [!tag|B|3|]Fix the problem that the right arrow is not vertically centered.
- [!tag|O|0|]Reduce the distance between the left and right sides.

## 0.2.11

- [!tag|B|2|]Fix the problem of up and down alignment in the left and right areas.

## 0.2.10

- [!tag|A|0|]Add the `clickAll` parameter to control whether clicking on the entire row triggers an event. Related [Issues](https://github.com/any-tdf/stdf/issues/7). [!issue|yuedanlabs|]

## 0.0.10

- [!tag|O|0|]Increase the distance between title and right detail. [!contribute|893358308|]



================================================
FILE: docs/mds/components/checkbox/api.md
================================================
## Checkbox Props

| 名称         | 类型                                                                         | 默认值      | 必传 | 说明                         |
| ------------ | ---------------------------------------------------------------------------- | ----------- | ---- | ---------------------------- |
| data         | `CheckboxItem[]`                                                             | `[]`        | Y    | 选项数据。                   |
| layout       | `'h'\|'v'\|'inline'`                                                         | `'v'`       | N    | 排列方式。                   |
| checkeds     | `string[]`                                                                   | `[]`        | N    | 选中的选项标识符组成的数组。 |
| textPosition | `'l'\|'r'\|'t'\|'b'`                                                         | `'r'`       | N    | 选项文本区域位置。           |
| icon         | `'default'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'default'` | N    | 未选中选项图标区域内容。     |
| iconChecked  | `'default'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'default'` | N    | 选中选项图标区域内容。       |

## Checkbox Events

| 名称     | 类型                           | 参数                                | 描述             |
| -------- | ------------------------------ | ----------------------------------- | ---------------- |
| onchange | `(checkeds: string[]) => void` | checkeds - 选定项标识符组成的数组。 | 点击选项时触发。 |

## Checkbox Snippets

| 名称          | 类型                                                                                          | 参数              | 说明                     |
| ------------- | --------------------------------------------------------------------------------------------- | ----------------- | ------------------------ |
| checkboxChild | [`Snippet<[{ item: CheckboxItem }]>`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | item - 选项数据。 | 当选项区域自定义时使用。 |

## CheckboxItem Props

| 名称         | 类型                                                                         | 默认值      | 必传 | 说明                     |
| ------------ | ---------------------------------------------------------------------------- | ----------- | ---- | ------------------------ |
| name         | `string`                                                                     | `''`        | Y    | 标识符。                 |
| label        | `string`                                                                     | `''`        | N    | 选项文本，主要用于显示。 |
| layout       | `'h'\|'v'\|'inline'`                                                         | `'v'`       | N    | 排列方式。               |
| textPosition | `'l'\|'r'\|'t'\|'b'`                                                         | `'r'`       | N    | 选项文本区域位置。       |
| icon         | `'default'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'default'` | N    | 未选中选项图标区域内容。 |
| iconChecked  | `'default'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'default'` | N    | 选中选项图标区域内容。   |
| checked      | `boolean`                                                                    | `false`     | N    | 是否选中。               |

## CheckboxItem Events

| 名称    | 类型                     | 参数            | 描述             |
| ------- | ------------------------ | --------------- | ---------------- |
| onclick | `(name: string) => void` | name - 标识符。 | 点击选项时触发。 |

## CheckboxItem Snippets

| 名称     | 类型                                                                | 参数 | 说明               |
| -------- | ------------------------------------------------------------------- | ---- | ------------------ |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 选项文本区域内容。 |



================================================
FILE: docs/mds/components/checkbox/api_en.md
================================================
## Checkbox Props

| Name         | Type                                                                         | Default     | Required | Description                            |
| ------------ | ---------------------------------------------------------------------------- | ----------- | -------- | -------------------------------------- |
| data         | `CheckboxItem[]`                                                             | `[]`        | Y        | Option data.                           |
| layout       | `'h'\|'v'\|'inline'`                                                         | `'v'`       | N        | Layout mode.                           |
| checkeds     | `string[]`                                                                   | `[]`        | N        | Array of selected option identifiers.  |
| textPosition | `'l'\|'r'\|'t'\|'b'`                                                         | `'r'`       | N        | Position of option text area.          |
| icon         | `'default'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'default'` | N        | Content of unchecked option icon area. |
| iconChecked  | `'default'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'default'` | N        | Content of checked option icon area.   |

## Checkbox Events

| Name     | Type                           | Parameters                                | Description                    |
| -------- | ------------------------------ | ----------------------------------------- | ------------------------------ |
| onchange | `(checkeds: string[]) => void` | checkeds - Array of selected identifiers. | Triggered when option clicked. |

## Checkbox Snippets

| Name          | Type                                                                                          | Parameters          | Description                        |
| ------------- | --------------------------------------------------------------------------------------------- | ------------------- | ---------------------------------- |
| checkboxChild | [`Snippet<[{ item: CheckboxItem }]>`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | item - Option data. | Used when customizing option area. |

## CheckboxItem Props

| Name         | Type                                                                         | Default     | Required | Description                            |
| ------------ | ---------------------------------------------------------------------------- | ----------- | -------- | -------------------------------------- |
| name         | `string`                                                                     | `''`        | Y        | Identifier.                            |
| label        | `string`                                                                     | `''`        | N        | Option text, mainly for display.       |
| layout       | `'h'\|'v'\|'inline'`                                                         | `'v'`       | N        | Layout mode.                           |
| textPosition | `'l'\|'r'\|'t'\|'b'`                                                         | `'r'`       | N        | Position of option text area.          |
| icon         | `'default'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'default'` | N        | Content of unchecked option icon area. |
| iconChecked  | `'default'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'default'` | N        | Content of checked option icon area.   |
| checked      | `boolean`                                                                    | `false`     | N        | Whether checked.                       |

## CheckboxItem Events

| Name    | Type                     | Parameters         | Description                    |
| ------- | ------------------------ | ------------------ | ------------------------------ |
| onclick | `(name: string) => void` | name - Identifier. | Triggered when option clicked. |

## CheckboxItem Snippets

| Name     | Type                                                                | Parameters | Description                  |
| -------- | ------------------------------------------------------------------- | ---------- | ---------------------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Content of option text area. |



================================================
FILE: docs/mds/components/checkbox/FAQ.md
================================================



================================================
FILE: docs/mds/components/checkbox/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/checkbox/guide.md
================================================
> Checkbox 使用了图标 ri-checkbox-fill 和 ri-checkbox-line，请确保项目的 symbol.svg 文件中包含这些图标。详细信息请参考 [STDF-指南 - 图标](https://stdf.design/guide/icon)。

## 说明

由于移动端横向显示内容有限，Checkbox 默认为纵向布局，横向布局建议只用作简单使用。当选项较多、内容较长或显示内容较多时建议使用纵向布局，当 Checkbox 内的选项被点击时，通过 onchange 事件，可以获取到当前所有选定项标识符 name 组成的数组。

## icon && iconChecked

Checkbox Props 的 icon 默认值 `'default'` 会按照 Remix Icon 的 checkbox-line 以 Icon 组件形式渲染；传入字符 `null`，表示未选中选项图标区域不显示内容；也可以传入 Icon Props，未选中选项图标区域将会以传入的参数以 Icon 组件形式渲染。

iconChecked 与 icon 逻辑一样，对应的是选中选项的图标区域内容。

## Checkbox Snippet

当传入 checkboxChild 这个 Snippet 时，选项区域将会以传入的 Snippet 内容渲染，可自由设计选中与未选中的效果，获取数据逻辑等。

> 虽然有 Tailwind 写样式比较方便，但过多的自定义将会失去使用组件库的意义。

## 点击区域优化

为了优化体验，CheckboxItem 整个区域都可以点击，将会激活与之对应的选项，不仅仅只可以点击文字或图标区域。



================================================
FILE: docs/mds/components/checkbox/guide_en.md
================================================
> Checkbox uses icons ri-checkbox-fill and ri-checkbox-line. Please ensure these icons are included in your project's symbol.svg file. For more details, please refer to [STDF-Guide-Icon](https://stdf.design/guide/icon).

## Description

Due to limited horizontal display space on mobile devices, Checkbox defaults to vertical layout, with horizontal layout recommended only for simple use cases. When there are multiple options, long content, or rich display content, vertical layout is recommended. When an option within the Checkbox is clicked, through the onchange event, you can get an array of name identifiers for all currently selected items.

## icon && iconChecked

The default value `'default'` for Checkbox Props' icon will render as an Icon component following Remix Icon's checkbox-line style; passing `null` means no content will be displayed in the unchecked option's icon area; you can also pass Icon Props, and the unchecked option's icon area will be rendered as an Icon component with the passed parameters.

iconChecked follows the same logic as icon, corresponding to the icon area content for checked options.

## Checkbox Snippet

When passing the checkboxChild Snippet, the option area will be rendered with the passed Snippet content, allowing free design of checked and unchecked effects, data logic handling, etc.

> Although Tailwind makes styling convenient, too much customization will defeat the purpose of using a component library.

## Click Area Optimization

To optimize the user experience, the entire CheckboxItem area is clickable and will activate its corresponding option, not just the text or icon areas.



================================================
FILE: docs/mds/components/checkbox/version.md
================================================



================================================
FILE: docs/mds/components/checkbox/version_en.md
================================================



================================================
FILE: docs/mds/components/dialog/api.md
================================================
## Dialog Props

| 名称            | 类型                                                          | 默认值                          | 必传 | 说明                   |
| --------------- | ------------------------------------------------------------- | ------------------------------- | ---- | ---------------------- |
| visible         | `boolean`                                                     | `false`                         | N    | 是否显示。             |
| title           | `string`                                                      | 当前语言的 dialog.title         | N    | 标题。                 |
| titleAlign      | `'left'\|'center'\|'right'`                                   | `'center'`                      | N    | 标题对齐方式。         |
| content         | `string`                                                      | 当前语言的 dialog.content       | N    | 内容。                 |
| popup           | [`Popup`](https://stdf.design/components?nav=popup&tab=1)   | `{}`                            | N    | 弹出层参数。           |
| showIcon        | `boolean`                                                     | `false`                         | N    | 是否显示图标。         |
| icon            | [`Icon`](https://stdf.design/components?nav=icon&tab=1)     | `{}`                            | N    | 图标参数。             |
| btnStyle        | `'button'\|'text'\|'textLine'`                                | `'button'`                      | N    | 按钮样式。             |
| primaryText     | `string`                                                      | 当前语言的 dialog.primaryText   | N    | 主按钮文字。           |
| primaryButton   | [`Button`](https://stdf.design/components?nav=button&tab=1) | `{}`                            | N    | 主按钮参数。           |
| secondaryText   | `string`                                                      | 当前语言的 dialog.secondaryText | N    | 次按钮文字。           |
| secondaryButton | [`Button`](https://stdf.design/components?nav=button&tab=1) | `{}`                            | N    | 次按钮参数。           |
| btnRatio        | `[number,number]`                                             | `[1, 1]`                        | N    | 主次按钮大小比例。     |
| btnReverse      | `boolean`                                                     | `false`                         | N    | 主次按钮位置是否反转。 |
| secondaryClose  | `boolean`                                                     | `true`                          | N    | 次按钮是否关闭弹窗。   |
| btnGap          | `'0'\|'1'\|'2'\|'4'\|'8'\|'12'\|'16'`                         | `'2'`                           | N    | 按钮间距。             |

## Dialog Events

| 名称        | 类型         | 参数 | 描述               |
| ----------- | ------------ | ---- | ------------------ |
| onclose     | `() => void` | -    | 对话框关闭时触发。 |
| onprimary   | `() => void` | -    | 点击主按钮时触发。 |
| onsecondary | `() => void` | -    | 点击次按钮时触发。 |

## Dialog Snippets

| 名称         | 类型                                                                | 参数 | 描述                          |
| ------------ | ------------------------------------------------------------------- | ---- | ----------------------------- |
| contentChild | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 传入时渲染 content 内容。     |
| primaryChild | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 传入时渲染 primaryText 内容。 |



================================================
FILE: docs/mds/components/dialog/api_en.md
================================================
## Dialog Props

| Name            | Type                                                          | Default                               | Required | Description                                  |
| --------------- | ------------------------------------------------------------- | ------------------------------------- | -------- | -------------------------------------------- |
| visible         | `boolean`                                                     | `false`                               | N        | Whether to show the dialog.                  |
| title           | `string`                                                      | Current language dialog.title         | N        | Title.                                       |
| titleAlign      | `'left'\|'center'\|'right'`                                   | `'center'`                            | N        | Title alignment.                             |
| content         | `string`                                                      | Current language dialog.content       | N        | Content.                                     |
| popup           | [`Popup`](https://stdf.design/components?nav=popup&tab=1)   | `{}`                                  | N        | Popup parameters.                            |
| showIcon        | `boolean`                                                     | `false`                               | N        | Whether to show icon.                        |
| icon            | [`Icon`](https://stdf.design/components?nav=icon&tab=1)     | `{}`                                  | N        | Icon parameters.                             |
| btnStyle        | `'button'\|'text'\|'textLine'`                                | `'button'`                            | N        | Button style.                                |
| primaryText     | `string`                                                      | Current language dialog.primaryText   | N        | Primary button text.                         |
| primaryButton   | [`Button`](https://stdf.design/components?nav=button&tab=1) | `{}`                                  | N        | Primary button parameters.                   |
| secondaryText   | `string`                                                      | Current language dialog.secondaryText | N        | Secondary button text.                       |
| secondaryButton | [`Button`](https://stdf.design/components?nav=button&tab=1) | `{}`                                  | N        | Secondary button parameters.                 |
| btnRatio        | `[number,number]`                                             | `[1, 1]`                              | N        | Size ratio of primary and secondary buttons. |
| btnReverse      | `boolean`                                                     | `false`                               | N        | Whether to reverse button positions.         |
| secondaryClose  | `boolean`                                                     | `true`                                | N        | Whether secondary button closes dialog.      |
| btnGap          | `'0'\|'1'\|'2'\|'4'\|'8'\|'12'\|'16'`                         | `'2'`                                 | N        | Gap between buttons.                         |

## Dialog Events

| Name        | Type         | Parameters | Description                                 |
| ----------- | ------------ | ---------- | ------------------------------------------- |
| onclose     | `() => void` | -          | Triggered when dialog closes.               |
| onprimary   | `() => void` | -          | Triggered when primary button is clicked.   |
| onsecondary | `() => void` | -          | Triggered when secondary button is clicked. |

## Dialog Snippets

| Name         | Type                                                                | Parameters | Description                                  |
| ------------ | ------------------------------------------------------------------- | ---------- | -------------------------------------------- |
| contentChild | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Render the content when it is passed in.     |
| primaryChild | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Render the primaryText when it is passed in. |



================================================
FILE: docs/mds/components/dialog/FAQ.md
================================================



================================================
FILE: docs/mds/components/dialog/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/dialog/guide.md
================================================
## 使用

Dialog 对话框一般用于展示一些需要用户明确知悉的内容或步骤，同时可以完成一些简单的交互操作，为避免误触，点击遮罩默认不会关闭。比一般只用于展示的 Modal 组件更加强大一些。

## 说明

Dialog 弹框组件是在 Popup 基础上封装的，通过预先定义一些 Popup 的 Props 实现，因此可以通过传入 Popup 的属性来实现不同的效果。比如示例中通过设置 popup 的 easeType 换了一种缓动效果。

而 Dialog 内部又使用了 Icon 和 Button 组件，可以通过传入 Icon 和 Button 的 Props 来实现不同的效果。比如示例中通过设置 Button 的 radius 自定义按钮的圆角风格。

## contentChild

Dialog 的内容可以通过 contentChild 这个 Snippet 渲染，当需要显示复杂内容时，可以通过此方式来实现。

## btnRatio

Dialog 的按钮有主次之分，通过 btnRatio 可以设置主次按钮的大小比例，如 btnRatio 为 `[2,1]` 时，主按钮宽度为次按钮的两倍。

## 关闭

Dialog 默认不会自动关闭，默认点击内部次要按钮可以关闭，或者通过改变外部的 visible 来关闭。当然这些参数都可以通过传入的 Props 来控制。



================================================
FILE: docs/mds/components/dialog/guide_en.md
================================================
## Usage

Dialog is generally used to display content or steps that users need to be clearly aware of, while also enabling simple interactions. To prevent accidental touches, clicking the mask will not close the dialog by default. It is more powerful than the Modal component which is mainly used for display.

## Description

The Dialog component is built on top of Popup by pre-defining some Popup Props. Therefore, different effects can be achieved by passing in Popup properties. For example, in the demo, a different easing effect is achieved by setting the easeType of popup.

Dialog internally uses Icon and Button components, and different effects can be achieved by passing in Icon and Button Props. For example, in the demo, the button's rounded corner style is customized by setting the Button's radius.

## contentChild

The content of Dialog can be rendered through the contentChild Snippet. When complex content needs to be displayed, it can be achieved through this method.

## btnRatio

Dialog's buttons have primary and secondary distinctions. The size ratio of primary and secondary buttons can be set through btnRatio. For example, when btnRatio is `[2,1]`, the width of the primary button is twice that of the secondary button.

## Close

Dialog will not automatically close by default. By default, clicking the internal secondary button can close it, or it can be closed by changing the external visible prop. Of course, these parameters can be controlled through the passed Props.



================================================
FILE: docs/mds/components/dialog/version.md
================================================



================================================
FILE: docs/mds/components/dialog/version_en.md
================================================



================================================
FILE: docs/mds/components/divider/api.md
================================================
## Divider Props

| 名称     | 类型                          | 默认值     | 必传 | 说明                        |
| -------- | ----------------------------- | ---------- | ---- | --------------------------- |
| layout   | `'h'\|'v'`                    | `'h'`      | N    | 分隔线类型，水平 h/垂直 v。 |
| px       | `'0'\|'4'\|'8'\|'16'\|'36'`   | `'0'`      | N    | 左右留白（仅水平有效）。    |
| py       | `'0'\|'4'\|'8'`               | `'4'`      | N    | 高度（仅水平有效）。        |
| text     | `string`                      | `''`       | N    | 文本内容（仅水平有效）。    |
| align    | `'left'\|'center'\|'right'`   | `'center'` | N    | 文本位置（仅水平有效）。    |
| line     | `'solid'\|'dashed'\|'dotted'` | `'solid'`  | N    | 线条风格。                  |
| weight   | `'1'\|'2'\|'4'`               | `'1'`      | N    | 线条粗细。                  |
| mx       | `'1'\|'2'\|'4'`               | `'1'`      | N    | 左右间距（仅垂直有效）。    |
| injClass | `string`                      | `''`       | N    | 注入 CSS 名称。             |



================================================
FILE: docs/mds/components/divider/api_en.md
================================================
## Divider Props

| Name     | Type                          | Default    | Required | Description                               |
| -------- | ----------------------------- | ---------- | -------- | ----------------------------------------- |
| layout   | `'h'\|'v'`                    | `'h'`      | N        | Divider type, horizontal h/vertical v.    |
| px       | `'0'\|'4'\|'8'\|'16'\|'36'`   | `'0'`      | N        | Left and right padding (horizontal only). |
| py       | `'0'\|'4'\|'8'`               | `'4'`      | N        | Height (horizontal only).                 |
| text     | `string`                      | `''`       | N        | Text content (horizontal only).           |
| align    | `'left'\|'center'\|'right'`   | `'center'` | N        | Text position (horizontal only).          |
| line     | `'solid'\|'dashed'\|'dotted'` | `'solid'`  | N        | Line style.                               |
| weight   | `'1'\|'2'\|'4'`               | `'1'`      | N        | Line thickness.                           |
| mx       | `'1'\|'2'\|'4'`               | `'1'`      | N        | Left and right margin (vertical only).    |
| injClass | `string`                      | `''`       | N        | Inject CSS class name.                    |



================================================
FILE: docs/mds/components/divider/FAQ.md
================================================



================================================
FILE: docs/mds/components/divider/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/divider/guide.md
================================================
## CSS 注入

由于 Divider 是利用元素的 border 实现，所以无论是水平还是垂直时，injClass 注入的的 class 只会对相应属性生效，border 属性对线条生效，text 属性对水平分割线内文本生效。

## 可选值

传入可选值以外的参数将按照默认参数处理。

## Props 类型

部分 Props 比如 px、py、weight、mx，明明是数字为何要用字符类型？主要是由于可选参数传入组件内部是作为 object 的 key 使用的，就必须为字符，况且组件传值的时候写 '' 应该比写 {} 更方便吧！坚持传入数字的话也可以，只是开启类型检查时会报错。



================================================
FILE: docs/mds/components/divider/guide_en.md
================================================
## Injecting CSS

As Divider uses element borders to create the line effect, the injClass passed in will only affect the corresponding properties, such as the border property affecting the line and the text property affecting the text in the horizontal divider.

## Available Options

Passing in values other than the available options will be treated as the default parameters.

## Prop Types

For some Props such as px, py, weight, mx, they are clearly numbers, why use string types? It is mainly because the optional parameters passed in to the component are used as object keys inside, so they must be strings. Besides, it should be more convenient to write '' instead of {} when passing values to the component! Of course, you can also insist on passing in numbers, but it will report an error when type checking is enabled.



================================================
FILE: docs/mds/components/divider/version.md
================================================



================================================
FILE: docs/mds/components/divider/version_en.md
================================================



================================================
FILE: docs/mds/components/grids/api.md
================================================
## Grids Props

| 名称 | 类型                                                            | 默认值 | 必传 | 说明         |
| ---- | --------------------------------------------------------------- | ------ | ---- | ------------ |
| cols | `'1'\|'2'\|'3'\|'4'\|'5'\|'6'\|'7'\|'8'\|'9'\|'10'\|'11'\|'12'` | `'6'`  | N    | 列数。       |
| gap  | `'0'\|'1'\|'2'\|'4'\|'8'`                                       | `'2'`  | N    | 单元格间距。 |
| mx   | `'0'\|'1'\|'2'\|'4'\|'8'`                                       | `'2'`  | N    | 左右外边距。 |
| my   | `'0'\|'1'\|'2'\|'4'\|'8'`                                       | `'2'`  | N    | 上下外边距。 |

## Grids Snippets

| 名称     | 类型                                                                | 参数 | 说明         |
| -------- | ------------------------------------------------------------------- | ---- | ------------ |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | Grids 内容。 |

## Grid Props

| 名称 | 类型                                                            | 默认值 | 必传 | 说明             |
| ---- | --------------------------------------------------------------- | ------ | ---- | ---------------- |
| col  | `'1'\|'2'\|'3'\|'4'\|'5'\|'6'\|'7'\|'8'\|'9'\|'10'\|'11'\|'12'` | `'1'`  | N    | 单元格所占列数。 |
| row  | `'1'\|'2'\|'3'\|'4'\|'5'\|'6'`                                  | `'1'`  | N    | 单元格所占行数。 |

## Grid Snippets

| 名称     | 类型                                                                | 参数 | 说明        |
| -------- | ------------------------------------------------------------------- | ---- | ----------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | Grid 内容。 |



================================================
FILE: docs/mds/components/grids/api_en.md
================================================
## Grids Props

| Name | Type                                                            | Default | Required | Description       |
| ---- | --------------------------------------------------------------- | ------- | -------- | ----------------- |
| cols | `'1'\|'2'\|'3'\|'4'\|'5'\|'6'\|'7'\|'8'\|'9'\|'10'\|'11'\|'12'` | `'6'`   | N        | Number of columns |
| gap  | `'0'\|'1'\|'2'\|'4'\|'8'`                                       | `'2'`   | N        | Cell spacing      |
| mx   | `'0'\|'1'\|'2'\|'4'\|'8'`                                       | `'2'`   | N        | Horizontal margin |
| my   | `'0'\|'1'\|'2'\|'4'\|'8'`                                       | `'2'`   | N        | Vertical margin   |

## Grids Snippets

| Name     | Type                                                                | Parameters | Description   |
| -------- | ------------------------------------------------------------------- | ---------- | ------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Grids content |

## Grid Props

| Name | Type                                                            | Default | Required | Description                            |
| ---- | --------------------------------------------------------------- | ------- | -------- | -------------------------------------- |
| col  | `'1'\|'2'\|'3'\|'4'\|'5'\|'6'\|'7'\|'8'\|'9'\|'10'\|'11'\|'12'` | `'1'`   | N        | Number of columns occupied by the cell |
| row  | `'1'\|'2'\|'3'\|'4'\|'5'\|'6'`                                  | `'1'`   | N        | Number of rows occupied by the cell    |

## Grid Snippets

| Name     | Type                                                                | Parameters | Description  |
| -------- | ------------------------------------------------------------------- | ---------- | ------------ |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Grid content |



================================================
FILE: docs/mds/components/grids/FAQ.md
================================================



================================================
FILE: docs/mds/components/grids/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/grids/guide.md
================================================
## 说明

Grids 组件本质使用 CSS 的 grid 布局，只是将 grid 在参数上做了一下简化，使用起来更方便。

移动端没有了 IE 浏览器，grid 的兼容性已经非常乐观了，可放心食用。

## 使用

Grids 的 cols 决定了内部等分的列数，而高度由每个单元格内部元素的高度决定。

## 行与列

Grid 的 row 和 col 属性决定了单元格所占行数和列数，默认为 1。

排列行列小技巧：**优先从左上角开始摆放，右侧放不下将挤到下一行。**



================================================
FILE: docs/mds/components/grids/guide_en.md
================================================
## Description

The Grids component essentially uses CSS grid layouts, but simplifies the grid with parameters for more convenient use.

With the disappearance of Internet Explorer on mobile devices, the compatibility of grid layout is now very optimistic and can be used with confidence.

## Usage

The `cols` property of Grids determines the number of columns in the internal division, while the height is determined by the height of the internal elements of each cell.

## Rows and Columns

The `row` and `col` properties of Grid determine the number of rows and columns occupied by the cell, respectively, and the default is 1.

A small tip for arranging rows and columns: **start from the top left corner and place items in a row, if there is no room on the right side, they will be squeezed into the next row.**



================================================
FILE: docs/mds/components/grids/version.md
================================================
## 1.0.8

- [!tag|B|2|] 修复 Grid Props 的 `col` 为 `'10'|'11'|'12'` 时的类名错误 [PR#45](https://github.com/any-tdf/stdf/pull/45)。[!contribute|nakulrathore|]



================================================
FILE: docs/mds/components/grids/version_en.md
================================================
## 1.0.8

- [!tag|B|2|] Fixed the class name error when `col` is `'10'|'11'|'12'` in Grid Props [PR#45](https://github.com/any-tdf/stdf/pull/45). [!contribute|nakulrathore|]



================================================
FILE: docs/mds/components/icon/api.md
================================================
## Icon Props

| 名称     | 类型      | 默认值               | 必传 | 说明                             |
| -------- | --------- | -------------------- | ---- | -------------------------------- |
| name     | `string`  | `''`                 | N    | 图标名称。                       |
| size     | `number`  | `24`                 | N    | 图标大小。                       |
| theme    | `boolean` | `false`              | N    | 是否跟随主题色（包含亮暗模式）。 |
| alpha    | `number`  | `1`                  | N    | 图标透明度。                     |
| top      | `number`  | `0`                  | N    | 上下偏移量。                     |
| injClass | `string`  | `''`                 | N    | 注入 CSS 名称。                  |
| path     | `string`  | `'fonts/symbol.svg'` | N    | 项目存放 symbol.svg 的路径。     |

## Icon Snippets

| 名称     | 类型                                                                | 参数 | 说明                                      |
| -------- | ------------------------------------------------------------------- | ---- | ----------------------------------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 自定义内容，一般是 Icon 组件或 SVG 元素。 |



================================================
FILE: docs/mds/components/icon/api_en.md
================================================
## Icon Props

| Name     | Type      | Default              | Required | Description                                      |
| -------- | --------- | -------------------- | -------- | ------------------------------------------------ |
| name     | `string`  | `''`                 | N        | Icon name.                                       |
| size     | `number`  | `24`                 | N        | Icon size.                                       |
| theme    | `boolean` | `false`              | N        | Whether to follow theme color (light/dark mode). |
| alpha    | `number`  | `1`                  | N        | Icon opacity.                                    |
| top      | `number`  | `0`                  | N        | Vertical offset.                                 |
| injClass | `string`  | `''`                 | N        | Injected CSS class name.                         |
| path     | `string`  | `'fonts/symbol.svg'` | N        | Project path for symbol.svg file.                |

## Icon Snippets

| Name     | Type                                                                | Parameters | Description                                            |
| -------- | ------------------------------------------------------------------- | ---------- | ------------------------------------------------------ |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Custom content, usually Icon component or SVG element. |



================================================
FILE: docs/mds/components/icon/FAQ.md
================================================



================================================
FILE: docs/mds/components/icon/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/icon/guide.md
================================================
## 背景

STDF 使用 SVG Sprites 技术使用图标，这样可以减少 HTTP 请求，提高页面性能。

STDF 的 SVG Sprites 是使用 [SVG symbol](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/symbol)，大致原理类似于 CSS 中的 Sprite 技术，将项目中的 SVG 拼接在一个文件内，通过 SVG 中的 use 元素找到对应的图标来显示。

你可以把它类比看成是一种字体，只不过这种字体是由 SVG 组成的，而且可以通过 CSS 控制颜色、大小等属性。所以如果用到比较大或者有多种颜色等比较复杂的图标，建议单独引入 SVG 文件使用，不要放在 symbol 中。

兼容性方面也完全没问题。参考 [MDN symbol](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/symbol#browser_compatibility)。

## rollup-plugin-stdf-icon

STDF 已经开发了一个 Rollup/Vite 插件，用于将项目中的 SVG 文件合并成 SVG Sprites，具体使用请参考 [rollup-plugin-stdf-icon](https://www.npmjs.com/package/rollup-plugin-stdf-icon)，由于 svg 格式的多样性，可能存在 rollup-plugin-stdf-icon 处理不准确的情况，请到 [GitHub](https://github.com/any-tdf/stdf/issues) 提 issue，注明 svg 文件的具体情况。

或使用其他 SVG Sprites 合成工具或手动合成，也可以请设计师提供设计物料时一并提供对应的 SVG Sprites。或类似 Remix Icon 这样的图标库，可以直接将选定的多个图标下载为 SVG Sprites。

## 内置说明

STDF 部分组件内使用的图标源自 [Remix Icon 图标库](https://remixicon.com)（[GitHub](https://github.com/Remix-Design/remixicon)），在此表示感谢 🙏🏻🙏🏻。

**如果使用这些组件，请确保项目的 symbol.svg 中包含了对应图标。**

具体请参考 [STDF-指南 - 图标](https://stdf.design/guide/icon)。

可到 `node_modules/stdf/assets/svg_base/` 查看这些图标的 SVG 源文件。

## 图标名称

当传入 Snippet 时表示图标内部使用传入的元素渲染，其他字符如 'ri-home-line' 使用 symbol.svg 中对应的 SVG 图标渲染。

## 图标颜色

如果 theme 不传或传入 false，图标颜色将继承自父级文字颜色，传入 true 图标颜色会根据主题色变化（包含亮暗模式）；如果要实现自定义颜色，而颜色又同时包含亮暗模式，建议使用 CSS 注入或 Snippet 渲染，在 injClass 或 Snippet 中分别配置亮暗模式，请查看示例。

## 颜色优先级

颜色优先级 Snippet > injClass > theme > 默认。

## 偏移量

欧洲和西亚文字排版中是有一条基准线的，东亚文字没有基线，参考 [MDN](https://developer.mozilla.org/zh-CN/docs/Glossary/baseline)。但由于不同系统不同字体中的差异，可能导致图标与文字一起排列时上下无法对齐，可以通过偏移量来微调。或者某些图标由于视觉重心的差异，需要排版时给出偏移量来保持视觉平衡。

## CSS 注入

通过 injClass 参数可以向组件内部最外层元素注入 CSS 名称（不仅限于 Tailwind CSS），这将使组件样式有更多自定义可能性。因为 CSS 注入于最后，此时最外层元素若已有同属性 CSS 将会以 injClass 为准，这也是通过 injClass 实现自定义图标颜色的原因。

## Snippet

可放入任何元素（甚至 Icon 组件自身），当然主要用于自定义图标或自定义图标颜色，如将自定义 SVG 放入 Icon 组件，请注意 SVG 的 viewBox、height、width 关系与 display 属性。此时图标内容取决于传入的元素，Props 中的 name、size、theme 等参数都将失效。通过 Snippet 将使组件内容有更多自定义可能性。

## 全局注入图标 svg 路径

STDF Icon 组件使用 Svg 文件路径配置，适用于一次性配置全局 SVG symbol 路径，或应用部署在服务器非根路径下。一般在应用的入口如 `App.svelte` 或 `+layout.svelte` 中配置 Context，例如：

```svelte
<!-- App.svelte/+layout.svelte -->
<script>
	import { setContext } from 'svelte'; // 引入 setContext

	setContext('STDF-global-icon-svg-path', 'webapps/svelte_demo/fonts/symbol.svg'); // 设置 svg 文件路径
</script>
```



================================================
FILE: docs/mds/components/icon/guide_en.md
================================================
## Background

STDF uses SVG Sprites technology for icons, which reduces HTTP requests and improves page performance.

STDF's SVG Sprites uses [SVG symbol](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/symbol), with a principle similar to CSS Sprite technology - combining project SVG files into one file and displaying icons through the SVG use element.

You can think of it as a font, except it's composed of SVGs and can be styled with CSS properties like color and size. For large or complex icons with multiple colors, it's recommended to import SVG files separately rather than including them in the symbol.

Browser compatibility is not an issue. See [MDN symbol](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/symbol#browser_compatibility).

## rollup-plugin-stdf-icon

STDF has developed a Rollup/Vite plugin to merge SVG files into SVG Sprites. For usage details, see [rollup-plugin-stdf-icon](https://www.npmjs.com/package/rollup-plugin-stdf-icon). Due to SVG format variations, if you encounter any issues with rollup-plugin-stdf-icon processing, please submit an issue on [GitHub](https://github.com/any-tdf/stdf/issues) with specific SVG file details.

You can also use other SVG Sprites generation tools, manual compilation, or request SVG Sprites from designers along with design assets. Icon libraries like Remix Icon allow direct download of selected icons as SVG Sprites.

## Built-in Icons

Some STDF components use icons from [Remix Icon](https://remixicon.com) ([GitHub](https://github.com/Remix-Design/remixicon)). We express our gratitude 🙏🏻🙏🏻.

**When using these components, ensure your project's symbol.svg includes the corresponding icons.**

For details, refer to [STDF-Guide-Icon](https://stdf.design/guide/icon).

You can find SVG source files in `node_modules/stdf/assets/svg_base/`.

## Icon Names

When a Snippet is passed, the icon renders using the passed element. Other strings like 'ri-home-line' render the corresponding SVG icon from symbol.svg.

## Icon Colors

Without theme prop or when set to false, icons inherit parent text color. When true, icons follow theme colors (including light/dark modes). For custom colors with light/dark mode support, use CSS injection or Snippet rendering with injClass or Snippet configured for both modes. See examples.

## Color Priority

Color priority: Snippet > injClass > theme > default.

## Vertical Offset

European and West Asian typography has a baseline, while East Asian text doesn't. See [MDN](https://developer.mozilla.org/zh-CN/docs/Glossary/baseline). Due to differences in system fonts, icons may misalign with text. Use the offset to fine-tune alignment or balance visual weight of icons.

## CSS Injection

The injClass parameter injects CSS classes (not limited to Tailwind CSS) into the component's outer element, enabling more style customization. Since CSS injection occurs last, any existing CSS properties on the outer element will be overridden by injClass, which enables custom icon colors.

## Snippet

Can contain any element (even Icon component itself), primarily used for custom icons or colors. When placing custom SVGs in Icon component, note the relationships between SVG viewBox, height, width, and display property. Icon content depends on the passed element, and Props like name, size, theme become ineffective. Snippets enable more customization possibilities for component content.

## Global Injection Icon SVG Path

STDF Icon component uses SVG file path configuration, which is suitable for a one-time configuration of the global SVG symbol path or the application being deployed on a non-root server path. Usually, the Context is configured in the entry of the application, such as `App.svelte` or `+layout.svelte`, for example:

```svelte
<!-- App.svelte/+layout.svelte -->
<script>
	import { setContext } from 'svelte'; // Import setContext

	setContext('STDF-global-icon-svg-path', 'webapps/svelte_demo/fonts/symbol.svg'); // Set the SVG file path
</script>
```



================================================
FILE: docs/mds/components/icon/version.md
================================================
## 0.5.3

- [!tag|O|0|] 支持一次性配置全局 SVG symbol 路径。关联 [PR](https://github.com/any-tdf/stdf/pull/28)。[!contribute|zh1047842950|]

## 0.2.11

- [!tag|B|1|] Icon 组件区域不再是 `inline-block`。

## 0.2.5

- [!tag|O|0|] path 默认值由 `/assets/fonts/symbol.svg` 修改为 `fonts/symbol.svg`。



================================================
FILE: docs/mds/components/icon/version_en.md
================================================
## 0.5.3

- [!tag|O|0|] Support one-time configuration of the global SVG symbol path. Related to [PR](https://github.com/any-tdf/stdf/pull/28). [!contribute|zh1047842950|]

## 0.2.11

- [!tag|B|1|] The Icon component area is no longer `inline-block`.

## 0.2.5

- [!tag|O|0|] The default value of `path` has been changed from `/assets/fonts/symbol.svg` to `fonts/symbol.svg`.



================================================
FILE: docs/mds/components/indexBar/api.md
================================================
## IndexBar Props

| 名称          | 类型                       | 默认值     | 必传 | 说明                             |
| ------------- | -------------------------- | ---------- | ---- | -------------------------------- |
| data          | `IndexBarItem[]`           | `[]`       | Y    | 索引数据组成的数组。             |
| current       | `number`                   | `0`        | N    | 当前激活的索引值。               |
| top           | `number`                   | `0`        | N    | 索引内容区域距离文档顶部的距离。 |
| height        | `number`                   | `100`      | Y    | 索引内容区域高度。               |
| radius        | `'none'\|'middle'\|'full'` | `'middle'` | N    | 圆角风格。                       |
| scrollAlign   | `boolean`                  | `true`     | N    | 是否开启滚动自动对齐。           |
| titleInjClass | `string`                   | `''`       | N    | 索引组标题注入 CSS。             |
| textInjClass  | `string`                   | `''`       | N    | 索引项文本注入 CSS。             |

## IndexBar Events

| 名称         | 类型                                                                              | 参数                                                                                                                | 描述               |
| ------------ | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------ |
| onclickChild | `(index: number, group: IndexBarItem, childIndex: number, child: string) => void` | index - 点击项的父级组索引值<br />group - 点击项的父级组内容<br />childIndex - 点击项索引值<br />child - 点击项内容 | 点击索引项时触发。 |

## IndexBarItem Props

| 名称   | 类型       | 默认值 | 必传 | 说明             |
| ------ | ---------- | ------ | ---- | ---------------- |
| index  | `string`   | `''`   | Y    | 索引值。         |
| title  | `string`   | `''`   | Y    | 标题。           |
| child  | `string[]` | `[]`   | Y    | 子项组成的数组。 |
| height | `number`   | `0`    | N    | 子项高度。       |



================================================
FILE: docs/mds/components/indexBar/api_en.md
================================================
## IndexBar Props

| Name          | Type                     | Default  | Required | Description                                       |
| ------------- | ------------------------ | -------- | -------- | ------------------------------------------------- |
| data          | `IndexBarItem[]`         | `[]`     | Y        | Array of index data.                              |
| current       | `number`                 | `0`      | N        | Currently active index value.                     |
| top           | `number`                 | `0`      | N        | Distance from index content area to document top. |
| height        | `number`                 | `100`    | Y        | Height of index content area.                     |
| radius        | `'none'\|'base'\|'full'` | `'base'` | N        | Border radius style.                              |
| scrollAlign   | `boolean`                | `true`   | N        | Whether to enable scroll auto-alignment.          |
| titleInjClass | `string`                 | `''`     | N        | Inject CSS for index group title.                 |
| textInjClass  | `string`                 | `''`     | N        | Inject CSS for index item text.                   |

## IndexBar Events

| Name         | Type                                                                              | Parameters                                                                                                                                                                | Description                            |
| ------------ | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
| onclickChild | `(index: number, group: IndexBarItem, childIndex: number, child: string) => void` | index - Parent group index of clicked item<br />group - Parent group content of clicked item<br />childIndex - Index of clicked item<br />child - Content of clicked item | Triggered when clicking an index item. |

## IndexBarItem Props

| Name   | Type       | Default | Required | Description            |
| ------ | ---------- | ------- | -------- | ---------------------- |
| index  | `string`   | `''`    | Y        | Index value.           |
| title  | `string`   | `''`    | Y        | Title.                 |
| child  | `string[]` | `[]`    | Y        | Array of child items.  |
| height | `number`   | `0`     | N        | Height of child items. |



================================================
FILE: docs/mds/components/indexBar/FAQ.md
================================================



================================================
FILE: docs/mds/components/indexBar/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/indexBar/guide.md
================================================
## 说明

一般用于页面中信息快速检索，可以根据目录中的索引值快速找到所需的内容。

## data

此 Props 是索引项组组成的数组，基本结构为`{ index: 'x', title: 'xx', child: ['xx', 'xx'] }`，其中 index 用于显示右侧 Bar 内的文字（建议单个字符），title 为内容区域每一组索引的标题，child 为一组索引内的单项内容，具体使用请参考示例。

## height && top

由于索引的内容区域在 Y 轴滚动，需要内容区域的高度，同时需要结合内容区域距离文档顶部的距离，用于监听与设置内容区域的滚动位置等操作。

建议 data 长度较大时 height 请传入较大值，总不能整个索引内容显示区域还没右侧的滑动 Bar 区域高吧。当然也不能传入过大，导致滚动区域显示不全或出现多个滚动条问题。

## CSS 注入

IndexBar 支持在两个地方注入 Class，注入 titleInjClass 会在索引组标题生效，注入 textInjClass 会在索引项的文本处生效。可以参考示例中改变索引内容区域样式。

若注入的 class 没生效，请在注入的 class 名称前添加“!” ，可参考 Tailwind Important modifier。

## scrollAlign

当索引内容区域滚动结束时，通过 CSS 的 scroll-snap-align 模块，每组索引内容顶部都会自动吸附到内容区域顶部，当然如果觉得影响滚动体验或不需要的话也可以关闭。

关于 scroll-snap-align 可参考 [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-align)。



================================================
FILE: docs/mds/components/indexBar/guide_en.md
================================================
## Description

Generally used for quickly searching information on a page, where you can quickly find the desired content based on the index value in the directory.

## data

This Props is an array composed of indexing items, the basic structure is `{ index: 'x', title: 'xx', child: ['xx', 'xx'] }`, where index is used to display the text in the right-side bar (it is recommended to use a single character), title is the title of each index group in the content area, and child is the content of a single indexing group. For specific usage, please refer to the example.

## height && top

Since the content area of the index scrolls on the Y-axis, the height of the content area is required, and the distance between the content area and the top of the document needs to be combined to listen for and set the scroll position in the content area and other operations.

When the length of data is large, it is recommended to pass in a larger value for height. After all, the display area of the entire index content cannot be lower than the height of the right-side scroll bar area. Of course, it cannot be too large either, which may cause the scroll area to be incomplete or multiple scrollbars to appear.

## CSS injection

IndexBar supports injecting classes in two places, where injecting titleInjClass will have an effect on the title of the indexing group, and injecting textInjClass will have an effect on the text of the indexing item. You can refer to the example to change the style of the index content area.

If the injected class is not effective, please prefix the injected class name with "!". You can refer to the Tailwind Important modifier.

## scrollAlign

When the index content area scrolls to an end, based on the CSS scroll-snap-align module, the top of each group of index content will automatically snap to the top of the content area. Of course, this feature can also be turned off if it affects the scrolling experience or is not needed.

Refer to [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-align) for more information on scroll-snap-align.



================================================
FILE: docs/mds/components/indexBar/version.md
================================================
## 0.5.1

- [!tag|O|0|]优化滑动动画效果。



================================================
FILE: docs/mds/components/indexBar/version_en.md
================================================
## 0.5.1

- [!tag|O|0|] Optimize the sliding animation effect.



================================================
FILE: docs/mds/components/input/api.md
================================================
## Input Props

| 名称              | 类型                                                                                                      | 默认值    | 必传 | 说明                            |
| ----------------- | --------------------------------------------------------------------------------------------------------- | --------- | ---- | ------------------------------- |
| title             | `string`                                                                                                  | `''`      | N    | 标题内容。                      |
| titlePosition     | `'in'\|'out'\|null`                                                                                       | `'out'`   | N    | 标题位置。                      |
| inputPosition     | `'left'\|'right'`                                                                                         | `'left'`  | N    | 输入框文字位置。                |
| placeholder       | `string`                                                                                                  | `''`      | N    | 输入框提示文本。                |
| radius            | `'none'\|'sm'\|'xl'\|'full'`                                                                              | `'sm'`    | N    | 圆角风格。                      |
| inputStyle        | `'block'\|'line'`                                                                                         | `'block'` | N    | 输入框风格。                    |
| lineTransition    | `'left'\|'center'`                                                                                         | `'left'`  | N    | 线性过渡位置。                  |
| duration          | `'fast'\|'base'\|'slow'\|'slower'`                                                                        | `'base'`  | N    | 过渡时间。                      |
| autocomplete      | `boolean`                                                                                                 | `true`    | N    | 是否开启自动填充功能。          |
| py                | `'0'\|'0.5'\|'1'\|'2'\|'3'\|'4'\|'6'`                                                                     | `'2'`     | N    | 垂直间距。                      |
| disabled          | `boolean`                                                                                                 | `false`   | N    | 是否禁用。                      |
| state             | `'theme'\|'success'\|'warning'\|'error'\|'info'`                                                          | `'theme'` | N    | 状态。                          |
| type              | `'text'\|'decimal'\|'email'\|'none'\|'numeric'\|'search'\|'tel'\|'url'\|'password'\|'number'\|'textarea'` | `'text'`  | N    | 输入框类型。                    |
| inputmode         | `'text'\|'decimal'\|'email'\|'none'\|'numeric'\|'search'\|'tel'\|'url'\|''`                               | `''`      | N    | 指定输入的数据类型。            |
| maxlength         | `number`                                                                                                  | `24`      | N    | 最多可输入文本长度。            |
| textareaMaxlength | `number`                                                                                                  | `200`     | N    | textarea 时最多可输入文本长度。 |
| rows              | `number`                                                                                                  | `2`       | N    | textarea 时行数。               |
| autosize          | `boolean`                                                                                                 | `false`   | N    | textarea 时是否自动调整高度。   |
| negative          | `boolean`                                                                                                 | `false`   | N    | 是否允许输入负数。              |
| label1            | [`Icon`](https://stdf.design/components?nav=icon&tab=1)\|`null`                                         | `null`    | N    | 标签 1 内容。                   |
| label2            | `string\|null`                                                                                            | `null`    | N    | 标签 2 内容。                   |
| label3            | [`Icon`](https://stdf.design/components?nav=icon&tab=1)\|`null`                                         | `null`    | N    | 标签 3 内容。                   |
| label4            | [`Icon`](https://stdf.design/components?nav=icon&tab=1)\|`null`                                         | `null`    | N    | 标签 4 内容。                   |
| label5            | `string\|null`                                                                                            | `null`    | N    | 标签 5 内容。                   |
| label6            | [`Icon`](https://stdf.design/components?nav=icon&tab=1)\|`null`                                         | `null`    | N    | 标签 6 内容。                   |
| tip               | `string\|null`                                                                                            | `null`    | N    | 提示信息内容。                  |
| data1             | `string\|null`                                                                                            | `null`    | N    | 数据项 1 内容。                 |
| data2             | `string\|null`                                                                                            | `null`    | N    | 数据项 2 内容。                 |
| data3             | `string\|null`                                                                                            | `null`    | N    | 数据项 3 内容。                 |
| value             | `string`                                                                                                  | `''`      | N    | 输入框值。                      |
| clear             | `boolean`                                                                                                 | `false`   | N    | 是否可清空。                    |

## Input Events

| 名称          | 类型                      | 参数                 | 说明                     |
| ------------- | ------------------------- | -------------------- | ------------------------ |
| onfocus       | `(value: string) => void` | value - 当前 value   | 获得焦点时触发。         |
| onblur        | `(value: string) => void` | value - 当前 value   | 失去焦点时触发。         |
| onchange      | `(value: string) => void` | value - 当前 value   | 输入框值发生变化时触发。 |
| onclear       | `() => void`              | -                    | 清空按钮点击时触发。     |
| onclickLabel1 | `() => void`              | -                    | 点击标签 1 时触发。      |
| onclickLabel2 | `() => void`              | -                    | 点击标签 2 时触发。      |
| onclickLabel3 | `() => void`              | -                    | 点击标签 3 时触发。      |
| onclickLabel4 | `() => void`              | -                    | 点击标签 4 时触发。      |
| onclickLabel5 | `() => void`              | -                    | 点击标签 5 时触发。      |
| onclickLabel6 | `() => void`              | -                    | 点击标签 6 时触发。      |
| onkeydown     | `(key: string) => void`   | key - 按下的按键 key | 按下键盘时触发。         |

## Input Snippets

| 名称        | 类型                                                                | 参数 | 说明                    |
| ----------- | ------------------------------------------------------------------- | ---- | ----------------------- |
| titleChild  | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 标题 Snippet 内容。     |
| data1Child  | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 数据项 1 Snippet 内容。 |
| data2Child  | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 数据项 2 Snippet 内容。 |
| data3Child  | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 数据项 3 Snippet 内容。 |
| label1Child | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 标签 1 Snippet 内容。   |
| label2Child | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 标签 2 Snippet 内容。   |
| label3Child | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 标签 3 Snippet 内容。   |
| label4Child | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 标签 4 Snippet 内容。   |
| label5Child | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 标签 5 Snippet 内容。   |
| label6Child | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 标签 6 Snippet 内容。   |
| tipChild    | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 提示信息 Snippet 内容。 |



================================================
FILE: docs/mds/components/input/api_en.md
================================================
## Input Props

| Name              | Type                                                                                                      | Default   | Required | Description                       |
| ----------------- | --------------------------------------------------------------------------------------------------------- | --------- | -------- | --------------------------------- |
| title             | `string`                                                                                                  | `''`      | N        | Title content.                    |
| titlePosition     | `'in'\|'out'\|null`                                                                                       | `'out'`   | N        | Title position.                   |
| inputPosition     | `'left'\|'right'`                                                                                         | `'left'`  | N        | Input text position.              |
| placeholder       | `string`                                                                                                  | `''`      | N        | Input placeholder text.           |
| radius            | `'none'\|'base'\|'xl'\|'full'`                                                                            | `'base'`  | N        | Border radius style.              |
| inputStyle        | `'block'\|'line'`                                                                                         | `'block'` | N        | Input box style.                  |
| lineTransition    | `'left'\|'center'`                                                                                         | `'left'`  | N        | Linear transition position.       |
| duration          | `'fast'\|'base'\|'slow'\|'slower'`                                                                        | `'base'`  | N        | Transition duration.              |
| autocomplete      | `boolean`                                                                                                 | `true`    | N        | Whether to enable autocomplete.   |
| py                | `'0'\|'0.5'\|'1'\|'2'\|'3'\|'4'\|'6'`                                                                     | `'2'`     | N        | Vertical padding.                 |
| disabled          | `boolean`                                                                                                 | `false`   | N        | Whether disabled.                 |
| state             | `'theme'\|'success'\|'warning'\|'error'\|'info'`                                                          | `'theme'` | N        | State.                            |
| type              | `'text'\|'decimal'\|'email'\|'none'\|'numeric'\|'search'\|'tel'\|'url'\|'password'\|'number'\|'textarea'` | `'text'`  | N        | Input type.                       |
| inputmode         | `'text'\|'decimal'\|'email'\|'none'\|'numeric'\|'search'\|'tel'\|'url'\|''`                               | `''`      | N        | Specify input data type.          |
| maxlength         | `number`                                                                                                  | `24`      | N        | Maximum input text length.        |
| textareaMaxlength | `number`                                                                                                  | `200`     | N        | Maximum text length for textarea. |
| rows              | `number`                                                                                                  | `2`       | N        | Number of rows for textarea.      |
| autosize          | `boolean`                                                                                                 | `false`   | N        | Auto adjust height for textarea.  |
| negative          | `boolean`                                                                                                 | `false`   | N        | Whether to allow negative numbers. |
| label1            | [`Icon`](https://stdf.design/components?nav=icon&tab=1)\|`null`                                         | `null`    | N        | Label 1 content.                  |
| label2            | `string\|null`                                                                                            | `null`    | N        | Label 2 content.                  |
| label3            | [`Icon`](https://stdf.design/components?nav=icon&tab=1)\|`null`                                         | `null`    | N        | Label 3 content.                  |
| label4            | [`Icon`](https://stdf.design/components?nav=icon&tab=1)\|`null`                                         | `null`    | N        | Label 4 content.                  |
| label5            | `string\|null`                                                                                            | `null`    | N        | Label 5 content.                  |
| label6            | [`Icon`](https://stdf.design/components?nav=icon&tab=1)\|`null`                                         | `null`    | N        | Label 6 content.                  |
| tip               | `string\|null`                                                                                            | `null`    | N        | Tip message content.              |
| data1             | `string\|null`                                                                                            | `null`    | N        | Data item 1 content.              |
| data2             | `string\|null`                                                                                            | `null`    | N        | Data item 2 content.              |
| data3             | `string\|null`                                                                                            | `null`    | N        | Data item 3 content.              |
| value             | `string`                                                                                                  | `''`      | N        | Input value.                      |
| clear             | `boolean`                                                                                                 | `false`   | N        | Whether clearable.                |

## Input Events

| Name          | Type                      | Parameters            | Description                             |
| ------------- | ------------------------- | --------------------- | --------------------------------------- |
| onfocus       | `(value: string) => void` | value - current value | Triggered when input gets focus.        |
| onblur        | `(value: string) => void` | value - current value | Triggered when input loses focus.       |
| onchange      | `(value: string) => void` | value - current value | Triggered when input value changes.     |
| onclear       | `() => void`              | -                     | Triggered when clear button is clicked. |
| onclickLabel1 | `() => void`              | -                     | Triggered when Label 1 is clicked.      |
| onclickLabel2 | `() => void`              | -                     | Triggered when Label 2 is clicked.      |
| onclickLabel3 | `() => void`              | -                     | Triggered when Label 3 is clicked.      |
| onclickLabel4 | `() => void`              | -                     | Triggered when Label 4 is clicked.      |
| onclickLabel5 | `() => void`              | -                     | Triggered when Label 5 is clicked.      |
| onclickLabel6 | `() => void`              | -                     | Triggered when Label 6 is clicked.      |
| onkeydown     | `(key: string) => void`   | key - pressed key     | Triggered when keyboard key is pressed. |

## Input Snippets

| Name        | Type                                                                | Parameters | Description                  |
| ----------- | ------------------------------------------------------------------- | ---------- | ---------------------------- |
| titleChild  | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Title Snippet content.       |
| data1Child  | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Data item 1 Snippet content. |
| data2Child  | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Data item 2 Snippet content. |
| data3Child  | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Data item 3 Snippet content. |
| label1Child | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Label 1 Snippet content.     |
| label2Child | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Label 2 Snippet content.     |
| label3Child | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Label 3 Snippet content.     |
| label4Child | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Label 4 Snippet content.     |
| label5Child | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Label 5 Snippet content.     |
| label6Child | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Label 6 Snippet content.     |
| tipChild    | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Tip message Snippet content. |



================================================
FILE: docs/mds/components/input/FAQ.md
================================================



================================================
FILE: docs/mds/components/input/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/input/guide.md
================================================
> Input 使用了图标 ri-close-circle-fill，请确保项目的 symbol.svg 文件中包含此图标。详细信息请参考 [STDF-指南 - 图标](https://stdf.design/guide/icon)。

## title 与 placeholder

如果传入了 title 而未传入 placeholder，Input 组件内部使用”请输入+title“作为默认 placeholder，**title 和 placeholder 请至少传入一项**。

## type 与 inputmode

关于 inputmode 请参考 [MDN](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/inputmode) 。

针对移动端交互特性，Input 组件主要用于输入文本，原生 input 标签的 type 值 file、radio、date 等有其他组件支持或交互方式，同时 type 与 inputmode 有高度重合性，type 的可选值在 inputmode 的基础上增加了 password 与 number。**使用时一般只需要传入 type 即可，当然你也可以单独设置 inputmode。**

因为在组件内部对输入内容做了一些处理，渲染为页面的最终 input 时 type 除了 password 外输入框内都会被转成 text，获取返回值时请自行转换类型。

## 监听按键事件

Input 组件内部监听了键盘按键事件，当按下任意按键时会触发 onkeydown 事件，返回的 `value` 表示按下的按键 key（备注：keyCode 已弃用，参考 [MDN](https://developer.mozilla.org/zh-CN/docs/Web/API/KeyboardEvent/keyCode) ），可根据此值做一些特殊处理。参考示例。

## 可配置项

Input 组件的所有可配置项位置如下图所示。

<img src="input.png" alt="input config" title="输入框配置项">

一般 label1、label3、label4、label6 用 Icon Props，label2 与 label5 用文字。

当然，如果这些配置项不能满足需求，它们也都支持使用 Snippet 渲染，请参考示例。

## textarea

textareaMaxlength、rows、autosize 三个参数只在 type 为 'textarea' 时生效，而且当 autosize 为 true 时 rows 将失效。

## CJK 输入

输入中日韩文等各种包含【选字】环节的文字过程中，组件内部在对输入长度、内容等信息处理时，是在**内容上屏后**才做校验。



================================================
FILE: docs/mds/components/input/guide_en.md
================================================
> Input uses the icon ri-close-circle-fill. Please ensure this icon is included in your project's symbol.svg file. For detailed information, please refer to [STDF-Guide-Icon](https://stdf.design/guide/icon).

## title and placeholder

If title is provided but placeholder is not, the Input component internally uses "Please enter + title" as the default placeholder. **At least one of title or placeholder must be provided**.

## type and inputmode

For inputmode, please refer to [MDN](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/inputmode).

Considering mobile interaction characteristics, the Input component is mainly used for text input. Native input tag type values like file, radio, date, etc. have other component support or interaction methods. Additionally, type and inputmode have high overlap, with type adding password and number options on top of inputmode's base values. **Generally, you only need to pass type, though you can set inputmode separately if needed.**

Because the component internally processes input content, when rendering the final input to the page, all type values except password will be converted to text. Please convert the return value type as needed.

## Listening to Key Events

The Input component internally listens to keyboard events. When any key is pressed, it triggers the onkeydown event, returning a `value` representing the pressed key (Note: keyCode is deprecated, refer to [MDN](https://developer.mozilla.org/zh-CN/docs/Web/API/KeyboardEvent/keyCode)). You can handle this value for special processing. See examples.

## Configuration Options

All configurable items of the Input component are shown in the image below.

<img src="input_en.png" alt="input config" title="Input Configuration Items">

Typically, label1, label3, label4, and label6 use Icon Props, while label2 and label5 use text.

Of course, if these configuration options don't meet your needs, they all support Snippet rendering. Please refer to the examples.

## textarea

The parameters textareaMaxlength, rows, and autosize only take effect when type is 'textarea', and when autosize is true, rows will be ineffective.

## CJK Input

When inputting Chinese, Japanese, Korean, or other text that involves a character selection process, the component internally validates input length, content, and other information **only after the content is committed to the screen**.



================================================
FILE: docs/mds/components/input/version.md
================================================
## 1.0.6

- [!tag|B|3|]修复切换亮暗模式时，输入框 placeholder 字体颜色不跟随变化的问题。

## 1.0.5

- [!tag|B|3|]输入数字时不允许小数点开头。

## 1.0.4

- [!tag|B|3|]触发 `onclear` 同时也触发 `onchange`。
- [!tag|A|0|]通过 `negative` 属性允许输入负数 [Issue#37](https://github.com/any-tdf/stdf/issues/37) [PR#38](https://github.com/any-tdf/stdf/pull/38)。[!issue|sbscan|] [!contribute|rizmyabdulla|]
- [!tag|O|0|]输入数字时不允许小数点开头且只允许一个小数点。

## 0.3.2

- [!tag|B|2|]修复 textarea 回车无法换行的问题。

## 0.3.1

- [!tag|A|0|]新增监听键盘事件 keydown。

## 0.0.11

- [!tag|O|0|]垂直间距 py 默认值改为 2，并新增 3 与 6 两个可选值。
- [!tag|O|0|]标题与输入框增加一点间距。



================================================
FILE: docs/mds/components/input/version_en.md
================================================
## 1.0.6

- [!tag|B|3|] Fix the problem that the input box placeholder font color does not follow the change when the light and dark mode is switched.

## 1.0.5

- [!tag|B|3|] Do not allow decimal points to start when entering numbers.

## 1.0.4

- [!tag|B|3|] Trigger `onclear` also triggers `onchange`.
- [!tag|A|0|] Allow negative numbers through the `negative` property [Issue#37](https://github.com/any-tdf/stdf/issues/37) [PR#38](https://github.com/any-tdf/stdf/pull/38). [!issue|sbscan|] [!contribute|rizmyabdulla|]
- [!tag|O|0|] Do not allow decimal points to start and only allow one decimal point when entering numbers.

## 0.3.2

- [!tag|B|2|] Fixed the problem that textarea cannot wrap when pressing enter.

## 0.3.1

- [!tag|A|0|] Added keydown event listener.

## 0.0.11

- [!tag|O|0|] The default vertical spacing of py has been changed to 2, and two optional values of 3 and 6 have been added.
- [!tag|O|0|] A little extra spacing has been added between the title and input box.



================================================
FILE: docs/mds/components/loading/api.md
================================================
## Loading Props

| 名称          | 类型                                                                                           | 默认值  | 必传 | 说明                               |
| ------------- | ---------------------------------------------------------------------------------------------- | ------- | ---- | ---------------------------------- |
| type          | `string`                                                                                       | `'1_0'` | N    | 类型编号。                         |
| height        | `'2'\|'4'\|'6'\|'8'\|'12'\|'16'\|'20'\|'28'\|'36'\|'48'\|'56'\|'64'\|'72'\|'80'\|'96'\|'full'` | `'8'`   | N    | 容器高度。                         |
| width         | `'2'\|'4'\|'6'\|'8'\|'12'\|'16'\|'20'\|'28'\|'36'\|'48'\|'56'\|'64'\|'72'\|'80'\|'96'\|'full'` | `'8'`   | N    | 容器宽度。                         |
| theme         | `boolean`                                                                                      | `false` | N    | 是否使用主题色，仅单色生效。       |
| inverse       | `boolean`                                                                                      | `false` | N    | 是否使用反差色，仅单色与双色生效。 |
| customColor   | `string[]`                                                                                     | `[]`    | N    | 自定义颜色数组。                   |
| lazyAnimation | `boolean`                                                                                      | `true`  | N    | 是否开启懒动画。                   |
| speed         | `number`                                                                                       | `1`     | N    | 动画速度，基数为 1。               |



================================================
FILE: docs/mds/components/loading/api_en.md
================================================
## Loading Props

| Name          | Type                                                                                           | Default | Required | Description                                                     |
| ------------- | ---------------------------------------------------------------------------------------------- | ------- | -------- | --------------------------------------------------------------- |
| type          | `string`                                                                                       | `'1_0'` | N        | Type number.                                                    |
| height        | `'2'\|'4'\|'6'\|'8'\|'12'\|'16'\|'20'\|'28'\|'36'\|'48'\|'56'\|'64'\|'72'\|'80'\|'96'\|'full'` | `'8'`   | N        | Container height.                                               |
| width         | `'2'\|'4'\|'6'\|'8'\|'12'\|'16'\|'20'\|'28'\|'36'\|'48'\|'56'\|'64'\|'72'\|'80'\|'96'\|'full'` | `'8'`   | N        | Container width.                                                |
| theme         | `boolean`                                                                                      | `false` | N        | Whether to use theme color, only works for monochrome.          |
| inverse       | `boolean`                                                                                      | `false` | N        | Whether to use contrast color, only works for mono/dual colors. |
| customColor   | `string[]`                                                                                     | `[]`    | N        | Custom color array.                                             |
| lazyAnimation | `boolean`                                                                                      | `true`  | N        | Whether to enable lazy animation.                               |
| speed         | `number`                                                                                       | `1`     | N        | Animation speed, base value is 1.                               |



================================================
FILE: docs/mds/components/loading/FAQ.md
================================================



================================================
FILE: docs/mds/components/loading/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/loading/guide.md
================================================
## 类型

Loading 目前支持四种类型，分别是单色、双色、四色和其他，通过 type 的第一个值来区分，如 `1_0`、`2_0`、`4_0`、`o_0`，第二个值表示此类型的编号。

更多的 Loading 将会在后续版本中逐步增加，也欢迎参与开发。

## 尺寸

Loading 的容器大小由 height 与 width 决定，除了少数几个需要固定尺寸，大多数 Loading 都会自动铺满给定的容器，请根据自己的需求调整大小。

## 主题色

当使用单色模式时，可以通过 theme 来控制是否使用主题色，颜色会自动适配亮暗模式，请参考示例。

## 反差色

通常情况下，页面颜色是浅色系颜色，Loading 会使用深色系颜色。但在一些场景，比如 Toast 组件内背景色与页面颜色深浅恰好相反，比如默认按钮背景色偏深色等情况，在这些组件内部使用 Loading 时，可以通过 inverse 来控制颜色，使其恰好与页面的亮暗模式相反，请参考示例。

## 自定义颜色

当需要传入自定义颜色时，可以通过 customColor 来传入颜色数组，数组长度与 type 的第一个值相同，如 `1_0` 需要传入一个颜色，`2_0` 需要传入两个颜色，`4_0` 需要传入四个颜色，请参考示例。

注：当使用自定义颜色时，theme 和 inverse 会失效。

## 四色默认颜色

当使用四色模式时，Loading 内部默认的四个颜色分别是红色（#DA1414）、绿色（#11BB8D）、紫色（#7356BF）、黄色（#FFC043），对应 STDF 颜色系统的 error、success、purple、yellow，如果需要自定义颜色请传入长度为 4 的 customColor，请参考示例。

## 动画速度

Loading 的动画速度可以通过 speed 来控制，基数为 1 表示正常速度，speed 的值越大，动画速度越快。请使用大于 0 的数值，但不建议使用过大的数值，否则可能会导致动画过快，徒增功耗还影响用户体验。

部分 Loading 因为动画的特殊性，当 speed 的值会影响元素之间连贯性时，会忽略 speed 的值，使用默认值。

## 懒动画

Loading 自带了一系列过渡动画，极端情况下，当页面同时有大量过渡效果时，考虑到设备性能与动画帧率等问题，Loading 通过 lazyAnimation 默认开启了懒动画，即 Loading 组件**不在页面可视范围内时会暂停动画**，当然你也可以单独设置。

## 感谢

部分动效灵感来自 [德育处主任](https://gitee.com/k21vin/front-end-data-visualization/tree/master/src/views/Native/PureCSS/pages/Loading/components) 与 [LDRS](https://uiball.com/ldrs), 感谢他们的分享。



================================================
FILE: docs/mds/components/loading/guide_en.md
================================================
## Type

There are currently four types of Loading, which are monochrome, bicolor, quadricolor, and other. They can be distinguished by the first value of the `type`, such as `1_0`, `2_0`, `4_0`, `o_0`. The second value represents the identification number of this type.

More Loading types will be gradually added in future versions, and your feedback is welcome.

## Size

The size of the Loading container is determined by `height` and `width`. Most Loading components will automatically fill the given container, except for a few that require a fixed size. Please adjust the size according to your needs.

## Theme Color

When using the monochrome mode, the `theme` can be used to control whether to use the theme color. The color will automatically adapt to light and dark mode. Please refer to the example.

## Contrast Color

Usually, the color scheme of the website is light, and Loading will use dark colors. However, in some scenarios, such as toast components where the background color is opposite in light and dark mode, or default button background colors that are darker, you can use `inverse` to control the color scheme to make it opposite to the light and dark mode of the website. Please refer to the example.

## Custom Color

When you need to pass in custom colors, you can use `customColor` to pass in an array of colors. The length of the array is the same as the first value of the Loading `type`. For example, `1_0` requires passing in one color, `2_0` requires passing in two colors, and `4_0` requires passing in four colors. Please refer to the example.

Note: When using custom colors, `theme` and `inverse` will not take effect.

## Default Colors for Quadricolor

When using the quadricolor mode, the default colors used inside Loading are red (#DA1414), green (#11BB8D), purple (#7356BF), and yellow (#FFC043), which correspond to the STDF color system's error, success, purple, and yellow respectively. If you need to customize the colors, please pass in a `customColor` array of length 4. Please refer to the example.

## Animation Speed

The animation speed of Loading can be controlled by `speed`, with a base of 1 indicating normal speed. The larger the value of `speed`, the faster the animation speed. Please use a value greater than 0, but it is not recommended to use a too large a value, otherwise it may cause the animation to be too fast, which will increase power consumption and affect the user experience.

For some Loading animations that have special continuity between elements, the value of `speed` may be ignored and use the default value.

## Lazy Animation

Loading comes with a series of transition animations. In extreme cases, when there are a large number of transition effects on the page, considering device performance and animation frame rate issues, Loading uses `lazyAnimation` to enable lazy animation by default, which means that the Loading component **will pause the animation when it is not in the visible range on the page**. Of course, you can also set it individually.

## Acknowledgments

Some of the animation inspirations are from [德育处主任](https://gitee.com/k21vin/front-end-data-visualization/tree/master/src/views/Native/PureCSS/pages/Loading/components) and [LDRS](https://uiball.com/ldrs). Special thanks go to them.



================================================
FILE: docs/mds/components/loading/version.md
================================================
## 0.4.7

- [!tag|O|0|]去除 Loading 容器默认大小。

## 0.4.6

- [!tag|A|0|]新增 32 种 Loading 类型（1_22 - 1_53）。

## 0.0.6

- [!tag|A|0|]新增 8 种 Loading 类型（1_18、1_19、1_20、1_21、2_2、2_3、2_4、2_5）。



================================================
FILE: docs/mds/components/loading/version_en.md
================================================
## 0.4.7

- [!tag|O|0|]Remove default size of Loading container.

## 0.4.6

- [!tag|A|0|]Add 32 Loading type(1_22 - 1_53).

## 0.0.6

- [!tag|A|0|]Add 8 Loading type(1_18, 1_19, 1_20, 1_21, 2_2, 2_3, 2_4, 2_5).



================================================
FILE: docs/mds/components/mask/api.md
================================================
## Mask Props

| 名称         | 类型                                                                 | 默认值   | 必传 | 说明                         |
| ------------ | -------------------------------------------------------------------- | -------- | ---- | ---------------------------- |
| visible      | `boolean`                                                            | `false`  | N    | 是否显示。                   |
| opacity      | `'0.1'\|'0.2'\|'0.3'\|'0.4'\|'0.5'\|'0.6'\|'0.7'\|'0.8'\|'0.9'\|'1'` | `'0.5'`  | N    | 遮罩透明度。                 |
| duration     | `number`                                                             | `150`    | N    | 出现动画过渡时长，单位：ms。 |
| outDuration  | `number`                                                             | `0`      | N    | 消失动画过渡时长，单位：ms。 |
| inverse      | `boolean`                                                            | `false`  | N    | 遮罩背景是否反色。           |
| clickable    | `boolean`                                                            | `false`  | N    | 遮罩是否可点击穿透。         |
| backdropBlur | `'none'\|'xs'\|'sm'\|'md'\|'lg'\|'xl'\|'2xl'\|'3xl'`               | `'none'` | N    | 背景模糊度。                 |
| zIndex       | `number`                                                             | `500`    | N    | z-index。                    |

## Mask Events

| 名称        | 类型         | 参数 | 描述                                                |
| ----------- | ------------ | ---- | --------------------------------------------------- |
| onclickMask | `() => void` | -    | 点击遮罩时触发，注意 clickable 为 true 时不会触发。 |

## Mask Snippets

| 名称     | 类型                                                                | 参数 | 说明       |
| -------- | ------------------------------------------------------------------- | ---- | ---------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 遮罩内容。 |



================================================
FILE: docs/mds/components/mask/api_en.md
================================================
## Mask Props

| Name         | Type                                                                 | Default  | Required | Description                                  |
| ------------ | -------------------------------------------------------------------- | -------- | -------- | -------------------------------------------- |
| visible      | `boolean`                                                            | `false`  | N        | Whether to show the mask.                    |
| opacity      | `'0.1'\|'0.2'\|'0.3'\|'0.4'\|'0.5'\|'0.6'\|'0.7'\|'0.8'\|'0.9'\|'1'` | `'0.5'`  | N        | Opacity of the mask.                         |
| duration     | `number`                                                             | `150`    | N        | Duration of the show animation in ms.        |
| outDuration  | `number`                                                             | `0`      | N        | Duration of the hide animation in ms.        |
| inverse      | `boolean`                                                            | `false`  | N        | Whether to invert the mask background color. |
| clickable    | `boolean`                                                            | `false`  | N        | Whether the mask is click-through.           |
| backdropBlur | `'none'\|'xs'\|'sm'\|'md'\|'lg'\|'xl'\|'2xl'\|'3xl'`               | `'none'` | N        | Backdrop blur level.                         |
| zIndex       | `number`                                                             | `500`    | N        | z-index value.                               |

## Mask Events

| Name        | Type         | Parameters | Description                                                             |
| ----------- | ------------ | ---------- | ----------------------------------------------------------------------- |
| onclickMask | `() => void` | -          | Triggered when clicking the mask. Not triggered when clickable is true. |

## Mask Snippets

| Name     | Type                                                                | Parameters | Description   |
| -------- | ------------------------------------------------------------------- | ---------- | ------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Mask content. |



================================================
FILE: docs/mds/components/mask/FAQ.md
================================================



================================================
FILE: docs/mds/components/mask/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/mask/guide.md
================================================
## 使用

Mask 组件一般是用来结合 BottomSheet、Toast、Popup 等组件使用，用于遮挡下层内容，突出弹出层内容，或防止用户操作。

## 动画

遮罩动画效果为 fade，可参考 [svelte/transition/fade](https://svelte.dev/docs/svelte/svelte-transition#fade) 。

遮罩一般是放置于其他交互式组件下层，考虑到出现与消失不会太突兀，遮罩出现时有一个较短的动画（默认 150ms），一般与内容时长一样；而内容信息展示完后一般需要迅速关闭，所以退出动画默认为 0ms，当然也可以通过 `outDuration` 属性设置退出的动画时间。

## 点击穿透

Mask 可以通过 `clickable` 属性设置是否可点击穿透，当设置为 `true` 时，点击遮罩不会触发 `onclickMask` 事件。

## inverse

通常情况下，页面颜色是浅色系颜色，Mask 会使用黑色背景色，当页面使用暗模式时 Mask 会使用白色背景色。但在一些特殊场景可能会使用恰好相反的背景色，可以通过 inverse 来控制颜色，使其恰好与页面的亮暗模式相反，请参考示例。

Mask 可以通过 `inverse` 属性设置是否反色，当设置为 `true` 时，遮罩背景色为白色。

## zIndex

遮罩层是相对于浏览器窗口通过 fixed 定位的，默认的 `z-index` 为 500，可以通过 `zIndex` 属性设置。

使用到 Mask 的组件包括 BottomSheet、Toast、Popup 等，这些组件也有默认的 z-index，见下表。如果同时显示这些组件时请注意层级关系。

使用到 Mask 组件的默认 `z-index` 如下：

| 组件        | zIndex |
| ----------- | ------ |
| BottomSheet | 600    |
| Popup       | 600    |
| Toast       | 1000   |



================================================
FILE: docs/mds/components/mask/guide_en.md
================================================
## Usage

The Mask component is usually used in combination with other components such as Toast, BottomSheet or Popup to block out the underlying content, highlight the pop-up content or prevent user interaction.

## Animation

The animation effect of the mask is fade, which can be referred to [svelte/transition/fade](https://svelte.dev/docs/svelte/svelte-transition#fade).

Normally, the mask is placed below other interactive components, so considering the smoothness of appearance and disappearance, there is a short animation (default 150ms) when the mask appears, generally the same length as the content. After the content is displayed, it is generally necessary to close quickly, so the exit animation is 0ms by default, but of course, the exit animation time can also be set through the `outDuration` attribute.

## Click-through

The Mask can be set whether it can be clicked through by the `clickable` attribute. When it is set to `true`, clicking the mask will not trigger the `onclickMask` event.

## Inverse

Usually, the page color is in light color scheme, and the Mask uses a black background color. When the page uses a dark mode, the Mask will use a white background color. However, in some special scenarios, the background color is precisely opposite to the page (light/dark). The color can be controlled via `inverse` attribute to make it exactly opposite to the page's light/dark colors. Please refer to the example for details.

The Mask can be set whether to invert the color by using the `inverse` attribute. When it is set to `true`, the mask background color is white.

## zIndex

The mask layer is positioned fixed relative to the browser window, and the default `z-index` is 500, which can be set via the `zIndex` attribute.

The components that use the Mask include Toast, Popup, BottomSheet, etc., and these components also have default z-index as shown in the table below. If these components are displayed at the same time, please pay attention to the layer relationship.

The default `z-index` of components that use the Mask are as follows:

| Component   | zIndex |
| ----------- | ------ |
| BottomSheet | 600    |
| Popup       | 600    |
| Toast       | 1000   |



================================================
FILE: docs/mds/components/mask/version.md
================================================



================================================
FILE: docs/mds/components/mask/version_en.md
================================================



================================================
FILE: docs/mds/components/modal/api.md
================================================
## Modal Props

| 名称       | 类型                                                          | 默认值                   | 必传 | 说明           |
| ---------- | ------------------------------------------------------------- | ------------------------ | ---- | -------------- |
| visible    | `boolean`                                                     | `false`                  | N    | 是否显示。     |
| title      | `string`                                                      | 当前语言的 modal.title   | N    | 标题。         |
| titleAlign | `'left'\|'center'\|'right'`                                   | `'center'`               | N    | 标题对齐方式。 |
| content    | `string`                                                      | 当前语言的 modal.content | N    | 内容。         |
| showIcon   | `boolean`                                                     | `false`                  | N    | 是否显示图标。 |
| icon       | [`Icon`](https://stdf.design/components?nav=dialog&tab=1)   | `{}`                     | N    | 图标参数。     |
| showBtn    | `boolean`                                                     | `true`                   | N    | 是否显示按钮。 |
| btnText    | `string`                                                      | 当前语言的 modal.btnText | N    | 按钮文字。     |
| button     | [`Button`](https://stdf.design/components?nav=dialog&tab=1) | `{}`                     | N    | 按钮参数。     |
| popup      | [`Popup`](https://stdf.design/components?nav=dialog&tab=1)  | `{}`                     | N    | 弹出层参数。   |

## Modal Events

| 名称    | 类型         | 参数 | 描述             |
| ------- | ------------ | ---- | ---------------- |
| onclose | `() => void` | -    | 弹框关闭时触发。 |

## Modal Snippets

| 名称         | 类型                                                                | 参数 | 描述                      |
| ------------ | ------------------------------------------------------------------- | ---- | ------------------------- |
| contentChild | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 传入时渲染 content 内容。 |



================================================
FILE: docs/mds/components/modal/api_en.md
================================================
## Modal Props

| Name       | Type                                                          | Default                        | Required | Description                |
| ---------- | ------------------------------------------------------------- | ------------------------------ | -------- | -------------------------- |
| visible    | `boolean`                                                     | `false`                        | N        | Whether to show the modal. |
| title      | `string`                                                      | Current language modal.title   | N        | Title text.                |
| titleAlign | `'left'\|'center'\|'right'`                                   | `'center'`                     | N        | Title alignment.           |
| content    | `string`                                                      | Current language modal.content | N        | Content text.              |
| showIcon   | `boolean`                                                     | `false`                        | N        | Whether to show icon.      |
| icon       | [`Icon`](https://stdf.design/components?nav=dialog&tab=1)   | `{}`                           | N        | Icon props.                |
| showBtn    | `boolean`                                                     | `true`                         | N        | Whether to show button.    |
| btnText    | `string`                                                      | Current language modal.btnText | N        | Button text.               |
| button     | [`Button`](https://stdf.design/components?nav=dialog&tab=1) | `{}`                           | N        | Button props.              |
| popup      | [`Popup`](https://stdf.design/components?nav=dialog&tab=1)  | `{}`                           | N        | Popup props.               |

## Modal Events

| Name    | Type         | Parameters | Description                  |
| ------- | ------------ | ---------- | ---------------------------- |
| onclose | `() => void` | -          | Triggered when modal closes. |

## Modal Snippets

| Name         | Type                                                                | Parameters | Description                              |
| ------------ | ------------------------------------------------------------------- | ---------- | ---------------------------------------- |
| contentChild | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Render the content when it is passed in. |



================================================
FILE: docs/mds/components/modal/FAQ.md
================================================



================================================
FILE: docs/mds/components/modal/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/modal/guide.md
================================================
## 使用

Modal 弹框组件一般用于展示一些需要用户明确知悉的内容或步骤，为避免误触，点击遮罩默认不会关闭。相比 Toast 用户感知度会更强，相比可以完成特定交互操作的 Dialog 又更简单一些。

## 说明

Modal 弹框组件是在 Popup 基础上封装的，通过预先定义一些 Popup 的 Props 实现，因此可以通过传入 Popup 的属性来实现不同的效果。比如示例中通过设置 popup 的 easeType 换了一种缓动效果。

而 Modal 内部又使用了 Icon 和 Button 组件，可以通过传入 Icon 和 Button 的 Props 来实现不同的效果。比如示例中通过设置 Button 的 radius 自定义按钮的圆角风格。

## contentChild

Modal 的内容可以通过 contentChild 传入，当需要显示复杂内容时，可以通过 contentChild 渲染，此时 content 会失效。

## 关闭

Modal 默认不会自动关闭，需要通过点击内部按钮来关闭，当不显示按钮时默认点击遮罩也会关闭，或者通过改变外部的 visible 来关闭。当然这些参数都可以通过传入的 Props 来控制。



================================================
FILE: docs/mds/components/modal/guide_en.md
================================================
## Usage

The Modal dialog component is generally used to display important information or steps that users need to be aware of. To avoid accidental clicks, clicking on the mask does not close the dialog by default. Compared to Toast, users will have a stronger sense of awareness, and compared to Dialog, it is simpler to implement specific interactive operations.

## Description

The Modal dialog component is based on Popup and is implemented by defining some of Popup's Props in advance. Therefore, different effects can be achieved by passing in Popup's attributes. For example, in the example, a different easing effect is achieved by setting the easeType of popup.

Modal also uses the Icon and Button components internally, and different effects can be achieved by passing in the Props of Icon and Button. For example, in the example, the radius of the Button is customized to achieve a custom button style.

## ContentChild

The content of the Modal can be passed in through the contentChild property. When complex content needs to be displayed, it can be rendered through contentChild, at this time content will be invalid.

## Close

The Modal by default will not automatically close and needs to be closed by clicking the internal button. When the button is not displayed, clicking the mask will close the Modal by default, or you can close it by changing the visible property externally. Of course, these parameters can be controlled through the Props passed in.



================================================
FILE: docs/mds/components/modal/version.md
================================================



================================================
FILE: docs/mds/components/modal/version_en.md
================================================



================================================
FILE: docs/mds/components/navBar/api.md
================================================
## NavBar Props

| 名称       | 类型                                                                      | 默认值                  | 必传 | 说明                                                       |
| ---------- | ------------------------------------------------------------------------- | ----------------------- | ---- | ---------------------------------------------------------- |
| title      | `string`                                                                  | 当前语言的 navBar.title | N    | 标题。                                                     |
| titleAlign | `'left'\|'center'\|'right'`                                               | `'left'`                | N    | 标题对齐方式。                                             |
| left       | `'back'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'back'`                | N    | 左侧内容，`'back'` 返回图标，`null` 无内容，否则渲染图标。 |
| rights     | [`Icon[]`](https://stdf.design/components?nav=icon&tab=1)               | `[]`                    | N    | 右侧内容，Icon Props 组成的数组，建议不超过三个。          |
| line       | `boolean`                                                                 | `true`                  | N    | 是否显示底部分割线。                                       |
| injClass   | `string`                                                                  | `''`                    | N    | 注入 CSS 名称。                                            |
| love       | `boolean`                                                                 | `false`                 | N    | 是否开启关爱版。                                           |

## NavBar Events

| 名称         | 类型                      | 参数                   | 说明               |
| ------------ | ------------------------- | ---------------------- | ------------------ |
| onclickLeft  | `() => void`              | -                      | 点击左侧图标触发。 |
| onclickRight | `(index: number) => void` | index - 点击图标索引值 | 点击右侧图标触发。 |

## NavBar Snippets

| 名称       | 类型                                                                | 参数 | 说明                 |
| ---------- | ------------------------------------------------------------------- | ---- | -------------------- |
| titleChild | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 传入时渲染标题区域。 |
| leftChild  | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 传入时渲染左侧区域。 |
| rightChild | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 传入时渲染右侧区域。 |



================================================
FILE: docs/mds/components/navBar/api_en.md
================================================
## NavBar Props

| Name       | Type                                                                      | Default                       | Required | Description                                                                         |
| ---------- | ------------------------------------------------------------------------- | ----------------------------- | -------- | ----------------------------------------------------------------------------------- |
| title      | `string`                                                                  | Current language navBar.title | N        | Title text.                                                                         |
| titleAlign | `'left'\|'center'\|'right'`                                               | `'left'`                      | N        | Title alignment.                                                                    |
| left       | `'back'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'back'`                      | N        | Left content, `'back'` for back icon, `null` for no content, otherwise render icon. |
| rights     | [`Icon[]`](https://stdf.design/components?nav=icon&tab=1)               | `[]`                          | N        | Right content array of Icon Props, recommend no more than 3 icons.                  |
| line       | `boolean`                                                                 | `true`                        | N        | Whether to show bottom divider line.                                                |
| injClass   | `string`                                                                  | `''`                          | N        | Inject CSS class name.                                                              |
| love       | `boolean`                                                                 | `false`                       | N        | Whether to enable care version.                                                     |

## NavBar Events

| Name         | Type                      | Parameters                 | Description                         |
| ------------ | ------------------------- | -------------------------- | ----------------------------------- |
| onclickLeft  | `() => void`              | -                          | Triggered when clicking left icon.  |
| onclickRight | `(index: number) => void` | index - Clicked icon index | Triggered when clicking right icon. |

## NavBar Snippets

| Name       | Type                                                                | Parameters | Description                     |
| ---------- | ------------------------------------------------------------------- | ---------- | ------------------------------- |
| titleChild | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Renders title area when passed. |
| leftChild  | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Renders left area when passed.  |
| rightChild | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Renders right area when passed. |



================================================
FILE: docs/mds/components/navBar/FAQ.md
================================================



================================================
FILE: docs/mds/components/navBar/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/navBar/guide.md
================================================
> NavBar 使用了图标 ri-arrow-left-s-line，请确保项目的 symbol.svg 文件中包含这些图标。详细信息请参考 [STDF-指南 - 图标](https://stdf.design/guide/icon)。

## 说明

移动端的 NavBar 一般用于页面顶部显示当前页面与路由跳转操作。STDF 的 NavBar 由左中右三个部分组成，且每个部分都支持 Snippet 渲染，而最外层元素的 Class 支持 injClass（class 注入）。

## 拓展

现有参数已经能满足绝大部分业务场景，比如根据页面上下滚动实时改变 NavBar 背景透明度与文字颜色这种常用场景，就可以通过 injClass 实现。如果还不满足你的需求，结合 Snippet 与 injClass，理论上 NavBar 可以定制为你想要的任何样式，甚至不仅仅把它作为顶部的导航栏来使用。

需要提醒的是，此处的拓展只是提供一种方法与思路，过多的自定义可能已经比自己写一个组件显得更加复杂，反而失去了使用组件库的意义。



================================================
FILE: docs/mds/components/navBar/guide_en.md
================================================
> NavBar uses the icon ri-arrow-left-s-line, please ensure that the symbol.svg file in your project includes this icon. For details, please refer to [STDF-Guide-Icon](https://stdf.design/guide/icon).

## Explanation

On mobile devices, the NavBar is generally used to display the current page and to perform routing operations at the top of the page. STDF's NavBar consists of three parts: left, center, and right, and each part supports Snippet rendering. The class of the outermost element also supports injClass (class injection).

## Extension

The existing parameters are sufficient to meet most business scenarios. For example, the common scene of changing the transparency of the NavBar background and text color based on the scrolling of the page can be achieved through injClass. If you are still not satisfied with your needs, combining Snippet and injClass, theoretically the NavBar can be customized to any style you want, not only for use as a top navigation bar.

It should be noted that this extension only provides a method and idea. Too much customization may already be more complex than writing a component yourself, and may lose the meaning of using a component library.



================================================
FILE: docs/mds/components/navBar/version.md
================================================
## 1.0.3

- [!tag|A|0|]新增 titleAlign 属性。



================================================
FILE: docs/mds/components/navBar/version_en.md
================================================
## 1.0.3

- [!tag|A|0|]Add titleAlign property.



================================================
FILE: docs/mds/components/noticeBar/api.md
================================================
## NoticeBar Props

| 名称      | 类型                                                              | 默认值    | 必传 | 说明                          |
| --------- | ----------------------------------------------------------------- | --------- | ---- | ----------------------------- |
| textList  | `string[]`                                                        | `[]`      | Y    | 通告内容组成的数组。          |
| leftIcon  | `null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=0) | `{}`      | N    | 左侧内容。                    |
| rightIcon | `'close'`\|`'arrow'`\|`null`                                      | `'close'` | N    | 右侧内容。                    |
| fontSize  | `'xs'\|'sm'\|'base'\|'lg'`                                        | `'sm'`    | N    | 通告字体大小。                |
| space     | `number`                                                          | `100`     | N    | 通告间距，单位是 px。         |
| speed     | `number`                                                          | `30`      | N    | 横向滚动速度，单位是 px/s。   |
| vertical  | `boolean`                                                         | `false`   | N    | 是否垂直滚动。                |
| duration  | `100`\|`300`\|`500`\|`700`\|`1000`                                | `500`     | N    | 垂直滚动过渡时间，单位是 ms。 |
| interval  | `number`                                                          | `4`       | N    | 垂直滚动间隔时间，单位是 s。  |
| injClass  | `string`                                                          | `''`      | N    | 注入 CSS 名称。               |

## NoticeBar Events

| 名称         | 类型         | 参数 | 描述               |
| ------------ | ------------ | ---- | ------------------ |
| onclickRight | `() => void` | -    | 点击右侧区域触发。 |

## NoticeBar Snippets

| 名称       | 类型                                                                | 参数 | 说明                     |
| ---------- | ------------------------------------------------------------------- | ---- | ------------------------ |
| leftChild  | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 传入时渲染左侧内容区域。 |
| rightChild | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 传入时渲染右侧内容区域。 |



================================================
FILE: docs/mds/components/noticeBar/api_en.md
================================================
## NoticeBar Props

| Name      | Type                                                              | Default   | Required | Description                                   |
| --------- | ----------------------------------------------------------------- | --------- | -------- | --------------------------------------------- |
| textList  | `string[]`                                                        | `[]`      | Y        | Array of announcement contents.               |
| leftIcon  | `null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=0) | `{}`      | N        | Left content.                                 |
| rightIcon | `'close'`\|`'arrow'`\|`null`                                      | `'close'` | N        | Right content.                                |
| fontSize  | `'xs'\|'sm'\|'base'\|'lg'`                                        | `'sm'`    | N        | Font size of the announcement.                |
| space     | `number`                                                          | `100`     | N        | Space between announcements in px.            |
| speed     | `number`                                                          | `30`      | N        | Horizontal scrolling speed in px/s.           |
| vertical  | `boolean`                                                         | `false`   | N        | Whether to scroll vertically.                 |
| duration  | `100`\|`300`\|`500`\|`700`\|`1000`                                | `500`     | N        | Vertical scrolling transition duration in ms. |
| interval  | `number`                                                          | `4`       | N        | Vertical scrolling interval time in seconds.  |
| injClass  | `string`                                                          | `''`      | N        | Injected CSS class name.                      |

## NoticeBar Events

| Name         | Type         | Params | Description                           |
| ------------ | ------------ | ------ | ------------------------------------- |
| onclickRight | `() => void` | -      | Triggered when right area is clicked. |

## NoticeBar Snippets

| Name       | Type                                                                | Params | Description                           |
| ---------- | ------------------------------------------------------------------- | ------ | ------------------------------------- |
| leftChild  | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -      | Renders left content area if passed.  |
| rightChild | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -      | Renders right content area if passed. |



================================================
FILE: docs/mds/components/noticeBar/FAQ.md
================================================



================================================
FILE: docs/mds/components/noticeBar/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/noticeBar/guide.md
================================================
> NoticeBar 使用了图标 ri-volume-down-line 和 ri-close-line，请确保项目的 symbol.svg 文件中包含这些图标。详细信息请参考 [STDF-指南 - 图标](https://stdf.design/guide/icon)。

## 说明

当横向放置时，不论内容有几条，只要所有内容加上内容之间的间隔长度之和超过容器宽度，NoticeBar 将会自动横向滚动，否则不滚动。

垂直放置时，内容超过一条时将会自动垂直滚动，单条内容过长将会溢出显示。

## leftIcon 与 rightIcon

左侧区域 leftIcon 除了默认的小喇叭图标，可以传入 Icon Props 实现其他图标显示，还可以自定义任何内容，通过 leftChild 这个 Snippet 实现，而右侧区域 rightIcon 只允许关闭、箭头、不显示三种情况，也可以通过 rightChild 这个 Snippet 实现自定义内容，请参考示例。

## onclickRight 事件

当点击右侧区域时，如果 rightIcon 为 close 会关闭当前通告栏；而 rightIcon 无论是 close 还是 arrow 都会派发 onclickRight 事件，可以通过监听该事件来实现自定义的业务逻辑。

## CSS 注入

通过 injClass 参数可以向组件内部最外层元素注入 CSS 名称（不仅限于 Tailwind CSS），这将使组件样式有更多自定义可能性，示例中通过 injClass 实现了自定义背景色与文字颜色。

若注入的 class 没生效，请在注入的 class 名称前添加“!” ，可参考 [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier)。



================================================
FILE: docs/mds/components/noticeBar/guide_en.md
================================================
> NoticeBar uses icons ri-volume-down-line and ri-close-line. Please ensure these icons are included in your project's symbol.svg file. For more details, please refer to [STDF-Guide-Icon](https://stdf.design/guide/icon).

## Description

When placed horizontally, regardless of the number of content items, NoticeBar will automatically scroll horizontally if the total length of all content plus the spacing between them exceeds the container width. Otherwise, it will not scroll.

When placed vertically, it will automatically scroll vertically if there is more than one content item. Single content items that are too long will overflow.

## leftIcon and rightIcon

The left area (leftIcon), besides the default speaker icon, can display other icons by passing Icon Props. It can also be customized with any content through the leftChild Snippet. The right area (rightIcon) only allows three states: close, arrow, or hidden. It can also be customized through the rightChild Snippet. Please refer to the examples.

## onclickRight Event

When clicking the right area, if rightIcon is set to close, it will close the current notice bar. Whether rightIcon is set to close or arrow, it will dispatch the onclickRight event, which can be listened to implement custom business logic.

## CSS Injection

Through the injClass parameter, you can inject CSS class names (not limited to Tailwind CSS) into the component's outermost element. This provides more possibilities for custom styling. In the example, injClass is used to implement custom background and text colors.

If the injected class doesn't take effect, please add "!" before the class name. You can refer to [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier).



================================================
FILE: docs/mds/components/noticeBar/version.md
================================================



================================================
FILE: docs/mds/components/noticeBar/version_en.md
================================================



================================================
FILE: docs/mds/components/numKeyboard/api.md
================================================
## NumKeyboard Props

| 名称         | 类型                                                        | 默认值                 | 必传 | 说明                 |
| ------------ | ----------------------------------------------------------- | ---------------------- | ---- | -------------------- |
| value        | `string`                                                    | `''`                   | N    | 输入内容。           |
| type         | `'button'`\|`'block'`                                       | `'button'`             | N    | 键盘样式类型。       |
| visible      | `boolean`                                                   | `false`                | N    | 是否显示键盘。       |
| height       | `'8'\|'10'\|'12'\|'14'\|'16'\|'20'`                         | `'12'`                 | N    | 按键高度。           |
| space        | `'0'\|'1'\|'2'\|'3'\|'4'`                                   | `'2'`                  | N    | 按键间距。           |
| p            | `'0'\|'1'\|'2'\|'3'\|'4'`                                   | `'2'`                  | N    | 键盘内边距。         |
| reverse      | `boolean`                                                   | `false`                | N    | 数字是否上下反向。   |
| done         | `boolean`                                                   | `true`                 | N    | 是否显示完成按钮。   |
| dot          | `boolean`                                                   | `true`                 | N    | 是否显示小数点。     |
| close        | `boolean`                                                   | `false`                | N    | 是否显示关闭按钮。   |
| doneText     | `string`                                                    | 当前语言的 common.done | N    | 完成按钮文案。       |
| doneDisabled | `boolean`                                                   | `false`                | N    | 完成按钮是否禁用。   |
| radius       | `'none'\|'sm'\|'md'\|'lg'\|'xl'\|'2xl'\|'3xl'\|'full'`      | `'sm'`                 | N    | 按键圆角。           |
| clear        | `boolean`                                                   | `false`                | N    | 打开时是否清空内容。 |
| panelClass   | `string`                                                    | `''`                   | N    | 键盘面板注入 Class。 |
| keyClass     | `string`                                                    | `''`                   | N    | 按键注入 Class。     |
| doneClass    | `string`                                                    | `''`                   | N    | 完成按键注入 Class。 |
| popup        | [`Popup`](https://stdf.design/components?nav=popup&tab=1) | `{}`                   | N    | 弹出层参数。         |

## NumKeyboard Events

| 名称    | 类型                       | 参数                     | 描述                   |
| ------- | -------------------------- | ------------------------ | ---------------------- |
| onclick | `(key: string) => void`    | key - 本次点击的键盘 key | 每次点击任意按键触发。 |
| onopen  | `(height: number) => void` | height - 键盘高度        | 键盘打开时触发。       |
| onclose | `() => void`               | -                        | 键盘关闭时触发。       |



================================================
FILE: docs/mds/components/numKeyboard/api_en.md
================================================
## NumKeyboard Props

| Name         | Type                                                        | Default                        | Required | Description                         |
| ------------ | ----------------------------------------------------------- | ------------------------------ | -------- | ----------------------------------- |
| value        | `string`                                                    | `''`                           | N        | Input content.                      |
| type         | `'button'`\|`'block'`                                       | `'button'`                     | N        | Keyboard style type.                |
| visible      | `boolean`                                                   | `false`                        | N        | Whether to show keyboard.           |
| height       | `'8'\|'10'\|'12'\|'14'\|'16'\|'20'`                         | `'12'`                         | N        | Key height.                         |
| space        | `'0'\|'1'\|'2'\|'3'\|'4'`                                   | `'2'`                          | N        | Key spacing.                        |
| p            | `'0'\|'1'\|'2'\|'3'\|'4'`                                   | `'2'`                          | N        | Keyboard padding.                   |
| reverse      | `boolean`                                                   | `false`                        | N        | Whether to reverse number order.    |
| done         | `boolean`                                                   | `true`                         | N        | Whether to show done button.        |
| dot          | `boolean`                                                   | `true`                         | N        | Whether to show decimal point.      |
| close        | `boolean`                                                   | `false`                        | N        | Whether to show close button.       |
| doneText     | `string`                                                    | Current language's common.done | N        | Done button text.                   |
| doneDisabled | `boolean`                                                   | `false`                        | N        | Whether to disable done button.     |
| radius       | `'none'\|'sm'\|'md'\|'lg'\|'xl'\|'2xl'\|'3xl'\|'full'`      | `'sm'`                         | N        | Key border radius.                  |
| clear        | `boolean`                                                   | `false`                        | N        | Whether to clear content when open. |
| panelClass   | `string`                                                    | `''`                           | N        | Inject class for keyboard panel.    |
| keyClass     | `string`                                                    | `''`                           | N        | Inject class for keys.              |
| doneClass    | `string`                                                    | `''`                           | N        | Inject class for done button.       |
| popup        | [`Popup`](https://stdf.design/components?nav=popup&tab=1) | `{}`                           | N        | Popup parameters.                   |

## NumKeyboard Events

| Name    | Type                       | Parameters                 | Description                        |
| ------- | -------------------------- | -------------------------- | ---------------------------------- |
| onclick | `(key: string) => void`    | key - Clicked keyboard key | Triggered when any key is clicked. |
| onopen  | `(height: number) => void` | height - Keyboard height   | Triggered when keyboard opens.     |
| onclose | `() => void`               | -                          | Triggered when keyboard closes.    |



================================================
FILE: docs/mds/components/numKeyboard/FAQ.md
================================================



================================================
FILE: docs/mds/components/numKeyboard/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/numKeyboard/guide.md
================================================
> NumKeyboard 使用了图标 ri-delete-back-2-line 和 ri-skip-down-line，请确保项目的 symbol.svg 文件中包含这些图标。详细信息请参考 [STDF-指南 - 图标](https://stdf.design/guide/icon)。

## 说明

NumKeyboard 组件是一个虚拟的数字键盘，一般用于输入整数或小数。内部使用了网格布局，布局方式只有 3\*4 或 4\*4 两种，当不显示完成按键时，就只有 3 列，否则就是 4 列。

## 按键

NumKeyboard 组件的按键有 5 种类型，分别是 0-9 数字、删除、小数点、完成、关闭，其中 0-9 数字、删除是必须的，完成、删除、关闭是非必须的。

非必须按键的优先级为：完成 > 小数点 > 关闭，所以当同时需要显示小数点和关闭时，由于关闭的优先级低于小数点，所以关闭按钮将不会显示，如果需要强制显示关闭按钮，只能关闭小数点的显示。请参考示例。

## reverse

通常情况，我们在移动设备上习惯的数字键盘布局是从上到下的顺序，但是在传统物理键盘上数字键盘是按照从下到上的顺序排列的，考虑部分特殊行业人群的使用习惯，NumKeyboard 组件提供了 reverse 参数，当 reverse 为 true 时，数字键盘将会按照从下到上的顺序排列。

## doneDisabled

当 doneDisabled 为 true 时，完成按钮将会被禁用，此时完成按钮的文案将会变成灰色，且不可点击。可用于根据输入内容动态控制业务流程。

## 按键文字大小

按键文字大小会动态地跟随按键的高度变化。

## 键盘高度

移动端使用到键盘的地方需要注意键盘的高度，因为键盘可能会遮盖掉页面上需要显示输入内容的区域，所以 NumKeyboard 组件在打开的时候会自动计算键盘的高度，通过 onopen 事件派发出去，开发者可以根据这个值来处理键盘遮挡的问题。

## CSS 注入

通过 injClass 参数可以向 NumKeyboard 的三个地方注入 CSS 名称（不仅限于 Tailwind CSS），这将使组件样式有更多自定义可能性，示例中通过 injClass 实现了自定义背景色与文字颜色。

panelClass 注入后作用到键盘面板，keyClass 注入后作用到所有按键，doneClass 注入后作用到完成按键。

若注入的 class 没生效，请在注入的 class 名称前添加“!” ，可参考 [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier)。

## popup

NumKeyboard 是在 Popup 的基础上封装的，通过预先定义一些 Popup 的 Props 实现，因此可以通过传入 Popup 的属性来实现不同的效果。比如示例中通过设置 popup 改变了过渡动画和背景透明度。



================================================
FILE: docs/mds/components/numKeyboard/guide_en.md
================================================
> NumKeyboard uses the icons ri-delete-back-2-line and ri-skip-down-line, please ensure that the symbol.svg file in your project includes these icons. For details, please refer to [STDF-Guide-Icon](https://stdf.design/guide/icon).

## Description

The NumKeyboard component is a virtual numeric keyboard used for inputting integers or decimals. It uses a grid layout, with two layout options: 3\*4 or 4\*4. If the completion key is not displayed, there will only be 3 columns; otherwise, there will be 4 columns.

## Keys

The NumKeyboard component has 5 types of keys: digits 0-9, delete, decimal point, completion, and close. Digits 0-9 and delete are required, while completion, delete, and close are optional.

The priority of optional keys is as follows: completion > decimal point > close. Therefore, if both the decimal point and close keys need to be displayed, the close button will not be shown, as the close key has a lower priority than the decimal point. If the close button needs to be forcibly shown, the display of the decimal point will need to be disabled. Please refer to the example.

## Reverse

Normally, on mobile devices, we are accustomed to the layout of the numeric keyboard being arranged from top to bottom. However, on traditional physical keyboards, the numeric keypad is arranged from bottom to top. To accommodate the usage habits of certain industries, the NumKeyboard component provides a reverse parameter. When reverse is set to true, the numeric keyboard will be arranged from bottom to top.

## doneDisabled

When doneDisabled is set to true, the completion button will be disabled. In this case, the completion button will appear grayed out and cannot be clicked. This can be used to dynamically control the business flow based on the input content.

## Key Text Size

The key text size will dynamically adjust according to the height of the key.

## Keyboard Height

When using the keyboard on a mobile device, it is important to consider the height of the keyboard. The keyboard may cover the area where input content needs to be displayed on the page. Therefore, the NumKeyboard component automatically calculates the height of the keyboard when it is opened and dispatches it through the onopen event. Developers can use this value to handle the issue of keyboard covering content.

## CSS Injection

The injClass parameter can be used to inject CSS class names (not limited to Tailwind CSS) into three parts of the NumKeyboard. This allows for more customization possibilities for the component's style. In the example, custom background color and text color are achieved through injClass.

After the panelClass is injected, it will affect the keyboard panel. After the keyClass is injected, it will affect all keys. After the doneClass is injected, it will affect the completion key.

If the injected class does not take effect, please prepend "!" to the class name being injected. You can refer to the [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier) for more information.

## Popup

The NumKeyboard is built on top of the Popup component. Different effects can be achieved by passing in Popup properties. For example, in the example, the transition animation and background transparency are changed by setting popup.



================================================
FILE: docs/mds/components/numKeyboard/version.md
================================================
## 1.0.3

- [!tag|A|0|]新增 `value` 与 `clear` 属性，关联 Issue [#36](https://github.com/any-tdf/stdf/issues/36)。[!issue|sbscan|]
- [!tag|O|0|]输入值不再通过 `onclick` 事件获取，而是通过 `value` 绑定。



================================================
FILE: docs/mds/components/numKeyboard/version_en.md
================================================
## 1.0.3

- [!tag|A|0|]Add `value` and `clear` properties, related to Issue [#36](https://github.com/any-tdf/stdf/issues/36). [!issue|sbscan|]
- [!tag|O|0|]Input value is no longer obtained through the `onclick` event, but through the `value` binding.



================================================
FILE: docs/mds/components/pagination/api.md
================================================
## Pagination Props

| 名称             | 类型                                     | 默认值                                   | 必传 | 说明                 |
| ---------------- | ---------------------------------------- | ---------------------------------------- | ---- | -------------------- |
| total            | `number`                                 | `0`                                      | Y    | 总条数。             |
| pageSize         | `number`                                 | `10`                                     | N    | 每页条数。           |
| current          | `number`                                 | `1`                                      | N    | 当前页。             |
| maxShowPage      | `5\|7\|9\|11`                            | `7`                                      | N    | 最大显示页码数。     |
| radius           | `'none'\|'sm'\|'md'\|'lg'\|'xl'\|'full'` | `'md'`                                   | N    | 圆角风格。           |
| type             | `'border'\|'block'\|'bold'`              | `'bold'`                                 | N    | 高亮页码类型。       |
| pageCol          | `number`                                 | `3`                                      | N    | 省略页码列数。       |
| showNextOmitPage | `boolean`                                | `false`                                  | N    | 是否显示后省略页码。 |
| showPreOmitPage  | `boolean`                                | `false`                                  | N    | 是否显示前省略页码。 |
| injClass         | `string`                                 | `''`                                     | N    | 注入 CSS 名称。。    |
| noDataText       | `string`                                 | 当前语言的 common.noData                 | N    | 无数据显示文本。     |
| onePageText      | `string`                                 | 当前语言的 pagination.defaultOnlyOnePage | N    | 仅一页显示文本。     |
| continuous       | `boolean`                                | `false`                                  | N    | 是否是连续模式。     |

## Pagination Events

| 名称     | 类型                        | 参数               | 描述               |
| -------- | --------------------------- | ------------------ | ------------------ |
| onchange | `(current: number) => void` | current - 当前页码 | 页码变化时触发。   |
| onnext   | `(current: number) => void` | current - 当前页码 | 点击下一页时触发。 |
| onpre    | `(current: number) => void` | current - 当前页码 | 点击上一页时触发。 |



================================================
FILE: docs/mds/components/pagination/api_en.md
================================================
## Pagination Props

| Name             | Type                                     | Default                                          | Required | Description                                  |
| ---------------- | ---------------------------------------- | ------------------------------------------------ | -------- | -------------------------------------------- |
| total            | `number`                                 | `0`                                              | Y        | Total number of items.                       |
| pageSize         | `number`                                 | `10`                                             | N        | Number of items per page.                    |
| current          | `number`                                 | `1`                                              | N        | Current page number.                         |
| maxShowPage      | `5\|7\|9\|11`                            | `7`                                              | N        | Maximum number of page numbers to display.   |
| radius           | `'none'\|'sm'\|'md'\|'lg'\|'xl'\|'full'` | `'md'`                                           | N        | Border radius style.                         |
| type             | `'border'\|'block'\|'bold'`              | `'bold'`                                         | N        | Highlighted page number style.               |
| pageCol          | `number`                                 | `3`                                              | N        | Number of columns for omitted page numbers.  |
| showNextOmitPage | `boolean`                                | `false`                                          | N        | Whether to show omitted page numbers after.  |
| showPreOmitPage  | `boolean`                                | `false`                                          | N        | Whether to show omitted page numbers before. |
| injClass         | `string`                                 | `''`                                             | N        | Inject CSS class name.                       |
| noDataText       | `string`                                 | Current language's common.noData                 | N        | Text to display when no data.                |
| onePageText      | `string`                                 | Current language's pagination.defaultOnlyOnePage | N        | Text to display when only one page.          |
| continuous       | `boolean`                                | `false`                                          | N        | Whether to use continuous mode.              |

## Pagination Events

| Name     | Type                        | Parameters                    | Description                            |
| -------- | --------------------------- | ----------------------------- | -------------------------------------- |
| onchange | `(current: number) => void` | current - Current page number | Triggered when page number changes.    |
| onnext   | `(current: number) => void` | current - Current page number | Triggered when clicking next page.     |
| onpre    | `(current: number) => void` | current - Current page number | Triggered when clicking previous page. |



================================================
FILE: docs/mds/components/pagination/FAQ.md
================================================



================================================
FILE: docs/mds/components/pagination/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/pagination/guide.md
================================================
> Pagination 使用了图标 ri-more-line 和 ri-more-fill，请确保项目的 symbol.svg 文件中包含这些图标。详细信息请参考 [STDF-指南 - 图标](https://stdf.design/guide/icon)。

## 设计思路

私以为，分页不应该是上滑加载下一页，这种交互会让用户无心理预期而产生不适，所以 STDF 的分页组件交互默认满足以下几个条件：

- 页码变化事件必须是用户主动触发。
- 无论何时都须同时显示上一页、下一页、首页、尾页、当前页，用户对全部数据有预期且可直接点击跳转到这些关键页码。
- 移动端横向显示区域有限，即便如此，也可以通过点击省略页码跳转到任意页码。

当然，你也可以配置为**连续模式**，即只允许点击上一页、下一页，比如一些后端接口必须根据上一页数据查询下一页数据的情况。但这样无疑会降低用户体验。

> To be in charge, the user must be informed. When, for example, the user initiates an operation, immediate feedback confirms that the operation is being carried out, and (eventually) then it’s finished… This communication should be brief, direct, and expressed in the user’s vocabulary rather than the programmer’s. (Apple Human Interface Guidelines)

## 事件监听

Pagination 组件对外暴露了三个事件：onchange、onnext、onpre，分别对应页码变化、下一页、上一页。onnext 和 onpre 事件都会触发 onchange 事件，请按需监听。

## total

Pagination 组件内将不显示 total 数据，请根据具体业务决定是否在页面内显示。

## current

current 为当前页码，内部默认从 1 开始计数，外部也可传入一个初始页码。

## maxShowPage

maxShowPage 表示最大显示页码数，即算上首页、尾页、显示页、省略号等在内一起算的数量，可选值为 5、7、9、11。此数值越大同时显示的页码越多，但也会导致单项宽度变小，影响用户操作，请根据具体业务决定。

## 省略页码

当总页码数大于 maxShowPage 时，就会有省略页码，省略页码分为前省略页码和后省略页码。当总页码数不是很多时，同时只会省略前后页码中的一个，当总页码数很多时，同时会省略前后页码。

所有省略的页码都可以通过点击省略号展开，展开区域支持上下滚动，且支持通过 pageCol 属性控制每行显示的页码数量。**并支持点击任意页码跳转到该页码。**

如果担心用户首次使用时无法知晓此交互，可以根据具体业务，比如用户首次使用时且总页码数大于 maxShowPage 时，通过传入 showNextOmitPage 默认将后省略页码展开，加以引导。

## type

type 表示高亮页码类型，可选值为 border、block、bold。border 表示高亮页码为边框，block 表示高亮页码为块，bold 表示高亮页码加粗且弱化其他页码。

## CSS 注入

通过 injClass 参数可以向组件内部外层注入 CSS 名称（不仅限于 Tailwind CSS），这将使组件样式有更多自定义可能性，示例中通过 injClass 实现了自定义圆角风格、两边间距、阴影等。

若注入的 CSS 没生效，请在注入的 CSS 名称前添加“!” ，可参考 [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier)。



================================================
FILE: docs/mds/components/pagination/guide_en.md
================================================
> Pagination uses the icons ri-more-line and ri-more-fill, please ensure that the symbol.svg file in your project includes these icons. For details, please refer to [STDF-Guide-Icon](https://stdf.design/guide/icon).

## Design Concept

In my opinion, pagination should not be based on scrolling up to load the next page. This interaction can cause user uncomfortable as there is no psychological expectation. Therefore, the STDF pagination component meet the following conditions by default:

- The page change event must be triggered by the user.
- The previous page, next page, first page, last page, and current page must always be displayed, and the user can directly click to jump to these key page numbers.
- On mobile devices, the horizontal display area is limited. Nevertheless, users can still click on the ellipsis to jump to any page number.

Of course, you can also configure it to **continuous mode**, that is, you are only allowed to click on the previous page and the next page. For example, some backend APIs must query the next page of data based on the previous page. But this will undoubtedly reduce the user experience.

> To be in charge, the user must be informed. When, for example, the user initiates an operation, immediate feedback confirms that the operation is being carried out, and (eventually) then it’s finished… This communication should be brief, direct, and expressed in the user’s vocabulary rather than the programmer’s. (Apple Human Interface Guidelines)

## Event Listening

The Pagination component exposes three events to the outside: onchange, onnext, and onpre, corresponding to page number changes, next page, and previous page, respectively. The onnext and onpre events will also trigger the onchange event, so listen as needed.

## total

The total data will not be displayed inside the Pagination component, so decide whether to display it on the page based on specific business requirements.

## current

Current represents the current page number, which is counted from 1 internally by default. An initial page number can also be passed in from the outside.

## maxShowPage

MaxShowPage represents the maximum number of displayed page numbers, including the first page, last page, displayed page, ellipsis, and so on. The optional values are 5, 7, 9, and 11. The larger the value, the more page numbers will be displayed at the same time, but the width of each item will be smaller, affecting user operations. Decide based on specific business requirements.

## Ellipsis Page Number

When the total number of pages is greater than maxShowPage, there will be ellipsis page numbers, which are divided into front ellipsis page numbers and back ellipsis page numbers. When the total number of pages is not very large, only one of the front and back ellipsis page numbers will be omitted at the same time. When the total number of pages is very large, both the front and back ellipsis page numbers will be omitted at the same time.

All omitted page numbers can be expanded by clicking on the ellipsis, and the expandable area supports scrolling up and down. The number of page numbers displayed per row can be controlled by the pageCol property. **And clicking on any page number in the expanded area will jump to that page number.**

If you are concerned that users may not understand this interaction when they use it for the first time, and the total number of pages is greater than maxShowPage, you can pass in showNextOmitPage by default to expand the back ellipsis page numbers and guide them.

## Type

Type represents the type of highlighted page numbers, with optional values of border, block, and bold. Border represents that the highlighted page number is the border, block represents that the highlighted page number is the block, and bold represents that the highlighted page number is bold and the other page numbers are weakened.

## CSS Injection

The injClass parameter can be used to inject a CSS class name (not limited to Tailwind CSS) into the outer layer of the component, which will provide more possibilities for customizing the component style. In the example, custom rounded corners, spacing on both sides, shadows, and other styles are achieved through injClass.

If the injected CSS does not take effect, add "!" in front of the injected CSS class name, as shown in the [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier).



================================================
FILE: docs/mds/components/pagination/version.md
================================================
## 0.4.7

- [!tag|B|1|]修复总页码数没有实时响应的问题。

## 0.4.5

- [!tag|B|1|]修复页码显示错乱问题，关联 [#22](https://github.com/any-tdf/stdf/pull/22) 。[!contribute|lemonTree345|]

## 0.1.3

- [!tag|A|0|]支持是否使用连续模式，即只允许点击上一页、下一页。

## 0.1.2

- [!tag|O|0|]细节优化。当 type 为 bold 且展开此省略页码时，省略号 Icon 也会加粗，使其与高亮页码文字样式逻辑匹配。



================================================
FILE: docs/mds/components/pagination/version_en.md
================================================
## 0.4.7

- [!tag|B|1|]Fixed total page number not updating in real time.

## 0.4.5

- [!tag|B|1|]Fixed the problem of incorrect page number display. Related to [#22](https://github.com/any-tdf/stdf/pull/22). [!contribute|lemonTree345|]

## 0.1.3

- [!tag|A|0|]Supports whether to use continuous mode, that is, only allows clicking the previous page and the next page.

## 0.1.2

- [!tag|O|0|]Fine-tune details. When type is set to bold and the ellipsis page numbers are expanded, the ellipsis icon will also be bold, matching the style logic of the highlighted page number text.



================================================
FILE: docs/mds/components/picker/api.md
================================================
## Picker Props

| 名称               | 类型                                                        | 默认值                           | 必传 | 说明                                       |
| ------------------ | ----------------------------------------------------------- | -------------------------------- | ---- | ------------------------------------------ |
| visible            | `boolean`                                                   | `false`                          | N    | 是否显示。                                 |
| datas              | `PickerDatas[]\|PickerDataChild[]`                          | `[]`                             | Y    | 所有列数据，参考 Picker datas Props。      |
| autoScrollToLast   | `boolean`                                                   | `true`                           | N    | 是否自动滚动到上次的选中项。               |
| cancelText         | `string`                                                    | 当前语言的 picker.defaultCancel  | N    | 取消选项文本。                             |
| confirmText        | `string`                                                    | 当前语言的 picker.defaultConfirm | N    | 确定选项文本。                             |
| title              | `string`                                                    | 当前语言的 picker.defaultTitle   | N    | 中间标题文本。                             |
| isLinkage          | `boolean`                                                   | `false`                          | N    | 是否多级联动。                             |
| linkageInitIndexs  | `number[]`                                                  | `[]`                             | N    | 多级联动时，设置初始选中项。               |
| linkageShowRows    | `number[]`                                                  | `[]`                             | N    | 多级联动时，设置每列显示行数。             |
| linkageFlexs       | `number[]`                                                  | `[]`                             | N    | 多级联动时，设置每列的宽度。               |
| linkageAligns      | `('left'\|'center'\|'right')[]`                             | `[]`                             | N    | 多级联动时，设置每列的对齐方式。           |
| linkageLabelKeys   | `string[]`                                                  | `[]`                             | N    | 多级联动时，自定义每列 label 的 Key。      |
| linkageChildrenKey | `string`                                                    | `'children'`                     | N    | 多级联动时，自定义上下级 children 的 key。 |
| popup              | [`Popup`](https://stdf.design/components?nav=popup&tab=1) | `{}`                             | N    | 弹出层参数。                               |

## Picker Events

| 名称      | 类型                                                             | 参数                                                                        | 描述                 |
| --------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------- | -------------------- |
| onclose   | `() => void`                                                     |                                                                             | 关闭时触发。         |
| oncancel  | `() => void`                                                     |                                                                             | 点击左侧取消时触发。 |
| onconfirm | `(items: { [key: string]: string }[], indexs: number[]) => void` | items - 选定多列数据组成的数组；<br />indexs - 选定多列数据索引组成的数组。 | 点击右侧确定时触发。 |

## PickerDatas Props

| 名称         | 类型                          | 默认值     | 必传 | 说明                  |
| ------------ | ----------------------------- | ---------- | ---- | --------------------- |
| data         | `{ [key: string]: string }[]` | `[]`       | Y    | 列数据。              |
| showRow      | `3`\|`5`\|`7`                 | `5`        | N    | 列显示行数。          |
| initIndex    | `number`                      | `0`        | N    | 列初始选中项。        |
| useAnimation | `boolean`                     | `true`     | N    | 滚动是否使用动画。    |
| labelKey     | `string`                      | `'label'`  | N    | 自定义 label 的 key。 |
| flex         | `number`                      | `1`        | N    | 多列时此列宽度。      |
| align        | `'left'\|'center'\|'right'`   | `'center'` | N    | 多列时此列对齐方式。  |

## PickerDataChild Props

| 名称          | 类型                                   | 默认值    | 必传 | 说明                  |
| ------------- | -------------------------------------- | --------- | ---- | --------------------- |
| children      | `PickerDatas[]`                        | `[]`      | Y    | 子数据。              |
| [key: string] | `string\|PickerDataChild[]\|undefined` | `'label'` | N    | 自定义 label 的 key。 |
|               |



================================================
FILE: docs/mds/components/picker/api_en.md
================================================
## Picker Props

| Name               | Type                                                        | Default                                | Required | Description                                                |
| ------------------ | ----------------------------------------------------------- | -------------------------------------- | -------- | ---------------------------------------------------------- |
| visible            | `boolean`                                                   | `false`                                | N        | Whether to show the picker.                                |
| datas              | `PickerDatas[]\|PickerDataChild[]`                          | `[]`                                   | Y        | All column data, refer to Picker datas Props.              |
| autoScrollToLast   | `boolean`                                                   | `true`                                 | N        | Whether to automatically scroll to the last selected item. |
| cancelText         | `string`                                                    | Current language picker.defaultCancel  | N        | Cancel button text.                                        |
| confirmText        | `string`                                                    | Current language picker.defaultConfirm | N        | Confirm button text.                                       |
| title              | `string`                                                    | Current language picker.defaultTitle   | N        | Title text.                                                |
| isLinkage          | `boolean`                                                   | `false`                                | N        | Whether to enable multi-level linkage.                     |
| linkageInitIndexs  | `number[]`                                                  | `[]`                                   | N        | Initial selected indexes for multi-level linkage.          |
| linkageShowRows    | `number[]`                                                  | `[]`                                   | N        | Number of rows to display for each column in linkage mode. |
| linkageFlexs       | `number[]`                                                  | `[]`                                   | N        | Width of each column in linkage mode.                      |
| linkageAligns      | `('left'\|'center'\|'right')[]`                             | `[]`                                   | N        | Alignment of each column in linkage mode.                  |
| linkageLabelKeys   | `string[]`                                                  | `[]`                                   | N        | Custom label keys for each column in linkage mode.         |
| linkageChildrenKey | `string`                                                    | `'children'`                           | N        | Custom children key for parent-child data in linkage mode. |
| popup              | [`Popup`](https://stdf.design/components?nav=popup&tab=1) | `{}`                                   | N        | Popup parameters.                                          |

## Picker Events

| Name      | Type                                                             | Parameters                                                                      | Description                      |
| --------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------- | -------------------------------- |
| onclose   | `() => void`                                                     |                                                                                 | Triggered when closing.          |
| oncancel  | `() => void`                                                     |                                                                                 | Triggered when clicking cancel.  |
| onconfirm | `(items: { [key: string]: string }[], indexs: number[]) => void` | items - Array of selected column data;<br />indexs - Array of selected indexes. | Triggered when clicking confirm. |

## PickerDatas Props

| Name         | Type                          | Default    | Required | Description                              |
| ------------ | ----------------------------- | ---------- | -------- | ---------------------------------------- |
| data         | `{ [key: string]: string }[]` | `[]`       | Y        | Column data.                             |
| showRow      | `3`\|`5`\|`7`                 | `5`        | N        | Number of rows to display.               |
| initIndex    | `number`                      | `0`        | N        | Initial selected index.                  |
| useAnimation | `boolean`                     | `true`     | N        | Whether to use animation when scrolling. |
| labelKey     | `string`                      | `'label'`  | N        | Custom label key.                        |
| flex         | `number`                      | `1`        | N        | Column width in multi-column mode.       |
| align        | `'left'\|'center'\|'right'`   | `'center'` | N        | Column alignment in multi-column mode.   |

## PickerDataChild Props

| Name          | Type                                   | Default   | Required | Description       |
| ------------- | -------------------------------------- | --------- | -------- | ----------------- |
| children      | `PickerDatas[]`                        | `[]`      | Y        | Child data.       |
| [key: string] | `string\|PickerDataChild[]\|undefined` | `'label'` | N        | Custom label key. |
|               |



================================================
FILE: docs/mds/components/picker/FAQ.md
================================================



================================================
FILE: docs/mds/components/picker/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/picker/guide.md
================================================
## 使用场景

Picker 组件用于选择单条或多条数据，数据量较大或无法确定长度的动态数据。Picker 组件的数据源可以是静态数据，也可以是动态数据。

## 传入数据

非多级联动时，传入的数据 datas 是一个数组，数组中的每一项都是一个对象，对象中的属性参考 PickerDatas Props。其中 data 才是每一列的数据，每一列的数据都是一个数组。

多级联动时，传入的数据与非联动的结构将完全不一样，传入的是一个多层级的数组，由 Picker 内部自动处理。请参考示例。

注意：多级联动使用时，请在传入数据之前先明确数据层级，且**保证每一条数据层级相同**，缺失的请用空数据或其他补齐。

## 返回数据

Picker 组件返回的数据有两项，一项是选定的多列数据组成的数组 items，另一项是选定的多列数据的索引组成的数组 indexs，请按照需求选择使用。

其中 items 每一项的数据结构与传入的数据结构一致，也方便开发者直接使用。

## 使用优化

实际开发中，多数情况下 Picker 的数据都是动态获取的，通常是通过接口获取，一般我们需要对传入的数据进行循环处理，以便于 Picker 组件能够正常使用。但这是一个比较繁琐且没必要的过程，因此 STDF 对 Picker 组件的入参作了一些优化，使得开发者可以直接传入接口返回的数据，而不需要做循环处理。

非多级联动时：

- 可以通过 PickerDatas Props 中的 labelKey 自定义传入的每列数据 label 属性名，如果不传入则默认使用 'label'，请参考示例。

多级联动时：

- 可以通过 linkageLabelKeys 自定义对应的每级数据的 label 属性名，如果不传入则默认使用 'label'，请参考示例。
- 可以通过 linkageChildrenKey 自定义上下级数据的 children 属性名，如果不传入则默认使用 'children'，请参考示例。

## 特别说明

多级联动使用时，请在**传入数据之前先明确数据层级**，传入 linkageInitIndexs、linkageShowRows、linkageFlexs、linkageAligns、linkageLabelKeys 的长度必须与数据层级一致。

## 说明

Picker 选择器是在 Popup 基础上封装的，通过预先定义一些 Popup 的 Props 实现，因此可以通过传入 Popup 的属性来实现不同的效果。比如示例中通过设置 popup 的 radius 改变圆角风格。

## Radio、ActionSheet、IndexBar、Picker、AsyncPicker 区别

Radio、Checkbox、ActionSheet、IndexBar、Picker、AsyncPicker 组件本质都是给出一系列数据，让用户进行数据选择或执行一些操作，但在使用上有一些区别：

- Radio 一般用于单选数据，数据量固定且较少，需要在 UI 界面上直接展示选项，方便用户在界面交互时对备选数据有个概览，比如性别选择。
- Checkbox 使用场景类似 Radio，但是可以多选。
- ActionSheet 一般用于选择之后立即执行一些操作，选项固定且较少，但不需要在 UI 界面上直接展示选项，比如做一些删除、修改等操作。
- IndexBar 一般用于选择单条数据，数据量非常大的动态数据，且已经对数据进行了分类索引，一般会用整个页面来展示。
- Picker 一般用于选择单条或多条数据，数据量较大或无法确定长度的动态数据，或用于一些联动数据的选择。**无论是否联动，数据在传入时已经是确定的。**
- AsyncPicker 一般用于选择多条数据，下级数据是根据上级数据动态获取的，比如服务端接口单次只返回一级数据，需要根据用户选择的一级数据再次请求接口获取下级数据。



================================================
FILE: docs/mds/components/picker/guide_en.md
================================================
## Usage Scenario

The Picker component is used to select one or more pieces of data from a large amount of dynamic data that may have an unspecified length. The data source for the Picker component can be static data or dynamic data.

## Incoming Data

When there is no multi-level linkage, the incoming data `datas` is an array. Each item in the array is an object, and the properties of the object reference the `PickerDatas Props`. The `data` is the data for each column, and the data for each column is an array.

When there is multi-level linkage, the incoming data structure will be completely different from non-linked structures. You need to pass in a multi-level array that the Picker component processes automatically. Refer to the example for details.

Note: When using multi-level linkage, make sure to specify the data hierarchy before passing in the data and ensure that the hierarchy of each data is the same. If any data is missing, please fill it in with empty data or other data to ensure uniformity.

## Return Data

The Picker component returns two sets of data. One is an array of selected data from multiple columns, and the other is an array of indexes of the selected data from multiple columns. Please select the data sets to use according to your needs.

Each item in `items` has the same data structure as in the input data, which is also convenient for developers to use directly.

## Usage Optimization

In actual development, the data used for the Picker is usually obtained dynamically, often through an interface. Usually, we need to loop through the incoming data to enable the Picker component to function properly. However, this is a cumbersome and unnecessary process. Therefore, some optimization has been made to the input parameters of the Picker component to enable developers to directly pass in the data returned by the interface without undergoing a looping process.

When there is no multi-level linkage:

- You can customize the `label` property name for the column data passed in through the `PickerDatas Props` with `labelKey`. If not passed in, it defaults to `'label'`. See the example for details.

When there is multi-level linkage:

- You can customize each level's `label` property name with `linkageLabelKeys`. If not passed in, it defaults to `'label'`. See the example for details.
- You can customize the `children` property name for the upper and lower level data with `linkageChildrenKey`. If not passed in, it defaults to `'children'`. See the example for details.

## Special Instructions

When using multi-level linkage, make sure to specify the data hierarchy before passing in the data. The lengths of `linkageInitIndexs`, `linkageShowRows`, `linkageFlexs`, `linkageAligns`, and `linkageLabelKeys` must be the same as the data hierarchy.

## Description

The Picker selector is based on Popup and encapsulated by predefining some Popup Props, so different effects can be achieved by passing in Popup attributes. For example, changing the rounded corner style by setting the `radius` of `popup`.

## Differences Between Radio, ActionSheet, IndexBar, Picker, and AsyncPicker

Radio, Checkbox, ActionSheet, IndexBar, Picker, and AsyncPicker components are essentially used to provide a series of data for users to choose from or to perform certain operations. However, there are some differences in usage:

- Radio is generally used for single-choice data. The amount of data is fixed and relatively small, and options need to be displayed directly in the UI interface to facilitate the user to have an overview of the options during UI interaction, for example, gender selection.
- Checkbox has a similar usage scenario to radio, but allows multiple selections.
- ActionSheet is generally used for immediate execution of certain operations after selection. The options are fixed and relatively small, but do not need to be displayed directly in the UI interface, for example, performing some delete or modification operations.
- IndexBar is generally used to select a single piece of data from a large amount of dynamic data that has already been categorized and indexed, and a whole page is usually used for display.
- Picker is generally used to select one or more pieces of data from dynamic data with a larger quantity or an undefined length, or for the selection of some linked data. The data is determined when it is passed in, regardless of whether there is linkage or not.
- AsyncPicker is generally used to select multiple pieces of data. The next-level data is obtained dynamically based on the upper-level data. For example, the server interface only returns one level of data at a time, and it is necessary to request the interface again to obtain the next-level data based on the upper-level data selected by the user.



================================================
FILE: docs/mds/components/picker/version.md
================================================



================================================
FILE: docs/mds/components/picker/version_en.md
================================================



================================================
FILE: docs/mds/components/placeholder/api.md
================================================
## Placeholder Props

| 名称     | 类型                                                             | 默认值   | 必传 | 说明            |
| -------- | ---------------------------------------------------------------- | -------- | ---- | --------------- |
| py       | `'0'\|'1'\|'2'\|'3'\|'4'\|'8'`                                   | `'4'`    | N    | 上下内边距。    |
| height   | `'full'\|'1'\|'2'\|'4'\|'8'\|'16'\|'24'\|'32'\|'48'\|'64'\|'96'` | `'full'` | N    | 高度。          |
| radius   | `'none'\|'sm'\|'md'\|'xl'\|'2xl'\|'3xl'\|'full'`                 | `'md'`   | N    | 圆角风格。      |
| shadow   | `'none'\|'xs'\|'sm'\|'md'\|'lg'\|'xl'\|'2xl'`                    | `'none'` | N    | 阴影风格。      |
| injClass | `string`                                                         | `''`     | N    | 注入 CSS 名称。 |

## Placeholder Snippets

| 名称     | 类型                                                                | 参数 | 说明               |
| -------- | ------------------------------------------------------------------- | ---- | ------------------ |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | Placeholder 内容。 |



================================================
FILE: docs/mds/components/placeholder/api_en.md
================================================
## Placeholder Props

| Name     | Type                                                             | Default  | Required | Description              |
| -------- | ---------------------------------------------------------------- | -------- | -------- | ------------------------ |
| py       | `'0'\|'1'\|'2'\|'3'\|'4'\|'8'`                                   | `'4'`    | N        | Vertical padding.        |
| height   | `'full'\|'1'\|'2'\|'4'\|'8'\|'16'\|'24'\|'32'\|'48'\|'64'\|'96'` | `'full'` | N        | Height.                  |
| radius   | `'none'\|'sm'\|'md'\|'xl'\|'2xl'\|'3xl'\|'full'`                 | `'md'`   | N        | Border radius style.     |
| shadow   | `'none'\|'xs'\|'sm'\|'md'\|'lg'\|'xl'\|'2xl'`                    | `'none'` | N        | Shadow style.            |
| injClass | `string`                                                         | `''`     | N        | Injected CSS class name. |

## Placeholder Snippets

| Name     | Type                                                                | Parameters | Description          |
| -------- | ------------------------------------------------------------------- | ---------- | -------------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Placeholder content. |



================================================
FILE: docs/mds/components/placeholder/FAQ.md
================================================



================================================
FILE: docs/mds/components/placeholder/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/placeholder/guide.md
================================================
## 说明

Placeholder 组件用于占位，用于表示此位置的一些内容。



================================================
FILE: docs/mds/components/placeholder/guide_en.md
================================================
## Description

The Placeholder component is used to occupy a space and can be used to represent some content in this space.



================================================
FILE: docs/mds/components/placeholder/version.md
================================================



================================================
FILE: docs/mds/components/placeholder/version_en.md
================================================



================================================
FILE: docs/mds/components/popup/api.md
================================================
## Popup Props

| 名称               | 类型                                                                               | 默认值       | 必传 | 说明                                                                                         |
| ------------------ | ---------------------------------------------------------------------------------- | ------------ | ---- | -------------------------------------------------------------------------------------------- |
| visible            | `boolean`                                                                          | `false`      | N    | 是否显示。                                                                                   |
| size               | `number`                                                                           | `40`         | N    | 弹出层大小，值为 0 时由内部元素决定。                                                        |
| position           | `'center'\|'top'\|'bottom'\|'left'\|'right'`                                       | `'bottom'`   | N    | 显示位置。                                                                                   |
| duration           | `number`                                                                           | `450`        | N    | 出现动画过渡时间，单位：ms。                                                                 |
| outDuration        | `number`                                                                           | `240`        | N    | 退出动画过渡时间，单位：ms。                                                                 |
| easeType           | [`SvelteEasing`](https://svelte.dev/docs#run-time-svelte-easing)                   | `'cubicOut'` | N    | 出现动画，共 31 个值，参考 [svelte/easing](https://svelte.dev/docs#run-time-svelte-easing)。 |
| easeOutType        | [`SvelteEasing`](https://svelte.dev/docs#run-time-svelte-easing)                   | `'cubicOut'` | N    | 退出动画，共 31 个值，参考 [svelte/easing](https://svelte.dev/docs#run-time-svelte-easing)。 |
| px                 | `'0'\|'1'\|'2'\|'3'\|'4'\|'5'\|'6'\|'8'\|'10'\|'12'\|'16'\|'20'`                   | `'0'`        | N    | 左右间距。                                                                                   |
| py                 | `'0'\|'1'\|'2'\|'3'\|'4'\|'5'\|'6'\|'8'\|'10'\|'12'\|'16'\|'24'\|'32'\|'48'\|'64'` | `'0'`        | N    | 上下间距。                                                                                   |
| mask               | [`Mask`](https://stdf.design/components?nav=mask&tab=1)                          | `{}`         | N    | 遮罩层参数。                                                                                 |
| maskClosable       | `boolean`                                                                          | `true`       | N    | 点击遮罩层是否关闭。                                                                         |
| radiusPosition     | `'all'\|'top'\|'bottom'\|'left'\|'right'`                                          | `'top'`      | N    | 圆角位置。                                                                                   |
| radius             | `'none'\|'sm'\|'md'\|'lg'\|'xl'\|'2xl'\|'3xl'\|'full'`                             | `'none'`     | N    | 圆角大小。                                                                                   |
| transitionDistance | `number`                                                                           | `0`          | N    | 动画距离，当弹出层大小由内部元素决定时生效。                                                 |
| transparent        | `boolean`                                                                          | `false`      | N    | 背景是否透明。                                                                               |
| allowBodyScroll    | `boolean`                                                                          | `true`       | N    | 弹出层显示时是否允许 body 滚动。                                                             |
| zIndex             | `number`                                                                           | `600`        | N    | z-index。                                                                                    |
| dynamicFixed       | `boolean`                                                                          | `true`       | N    | 是否动态固定。                                                                               |
| hideScrollbar      | `boolean`                                                                          | `false`      | N    | 是否隐藏滚动区域滚动条。                                                                     |

## Popup Events

| 名称        | 类型         | 参数 | 描述                                                        |
| ----------- | ------------ | ---- | ----------------------------------------------------------- |
| onclickMask | `() => void` | -    | 点击弹出层遮罩时触发，即使 maskClosable 为 false 也会触发。 |
| onclose     | `() => void` | -    | 弹出层关闭时触发。                                          |

## Popup Snippets

| 名称     | 类型                                                                | 参数 | 说明         |
| -------- | ------------------------------------------------------------------- | ---- | ------------ |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | Popup 内容。 |

## SvelteEasing

```javascript
type SvelteEasing =
    | 'backIn'
    | 'backInOut'
    | 'backOut'
    | 'bounceIn'
    | 'bounceInOut'
    | 'bounceOut'
    | 'circIn'
    | 'circInOut'
    | 'circOut'
    | 'cubicIn'
    | 'cubicInOut'
    | 'cubicOut'
    | 'elasticIn'
    | 'elasticInOut'
    | 'elasticOut'
    | 'expoIn'
    | 'expoInOut'
    | 'expoOut'
    | 'linear'
    | 'quadIn'
    | 'quadInOut'
    | 'quadOut'
    | 'quartIn'
    | 'quartInOut'
    | 'quartOut'
    | 'quintIn'
    | 'quintInOut'
    | 'quintOut'
    | 'sineIn'
    | 'sineInOut'
    | 'sineOut';
```



================================================
FILE: docs/mds/components/popup/api_en.md
================================================
## Popup Props

| Name               | Type                                                                               | Default      | Required | Description                                                                                                     |
| ------------------ | ---------------------------------------------------------------------------------- | ------------ | -------- | --------------------------------------------------------------------------------------------------------------- |
| visible            | `boolean`                                                                          | `false`      | N        | Whether to show the popup.                                                                                      |
| size               | `number`                                                                           | `40`         | N        | Popup size. When value is 0, size is determined by inner elements.                                              |
| position           | `'center'\|'top'\|'bottom'\|'left'\|'right'`                                       | `'bottom'`   | N        | Display position.                                                                                               |
| duration           | `number`                                                                           | `450`        | N        | Enter animation transition duration in ms.                                                                      |
| outDuration        | `number`                                                                           | `240`        | N        | Exit animation transition duration in ms.                                                                       |
| easeType           | [`SvelteEasing`](https://svelte.dev/docs#run-time-svelte-easing)                   | `'cubicOut'` | N        | Enter animation type, 31 values available, see [svelte/easing](https://svelte.dev/docs#run-time-svelte-easing). |
| easeOutType        | [`SvelteEasing`](https://svelte.dev/docs#run-time-svelte-easing)                   | `'cubicOut'` | N        | Exit animation type, 31 values available, see [svelte/easing](https://svelte.dev/docs#run-time-svelte-easing).  |
| px                 | `'0'\|'1'\|'2'\|'3'\|'4'\|'5'\|'6'\|'8'\|'10'\|'12'\|'16'\|'20'`                   | `'0'`        | N        | Horizontal padding.                                                                                             |
| py                 | `'0'\|'1'\|'2'\|'3'\|'4'\|'5'\|'6'\|'8'\|'10'\|'12'\|'16'\|'24'\|'32'\|'48'\|'64'` | `'0'`        | N        | Vertical padding.                                                                                               |
| mask               | [`Mask`](https://stdf.design/components?nav=mask&tab=1)                          | `{}`         | N        | Mask layer parameters.                                                                                          |
| maskClosable       | `boolean`                                                                          | `true`       | N        | Whether clicking mask layer closes popup.                                                                       |
| radiusPosition     | `'all'\|'top'\|'bottom'\|'left'\|'right'`                                          | `'top'`      | N        | Border radius position.                                                                                         |
| radius             | `'none'\|'sm'\|'md'\|'lg'\|'xl'\|'2xl'\|'3xl'\|'full'`                             | `'none'`     | N        | Border radius size.                                                                                             |
| transitionDistance | `number`                                                                           | `0`          | N        | Animation distance when popup size is determined by inner elements.                                             |
| transparent        | `boolean`                                                                          | `false`      | N        | Whether background is transparent.                                                                              |
| allowBodyScroll    | `boolean`                                                                          | `true`       | N        | Whether to allow body scrolling when popup is shown.                                                            |
| zIndex             | `number`                                                                           | `600`        | N        | z-index value.                                                                                                  |
| dynamicFixed       | `boolean`                                                                          | `true`       | N        | Whether to use dynamic fixed positioning.                                                                       |
| hideScrollbar      | `boolean`                                                                          | `false`      | N        | Whether to hide scrollbar in scroll area.                                                                       |

## Popup Events

| Name        | Type         | Params | Description                                                        |
| ----------- | ------------ | ------ | ------------------------------------------------------------------ |
| onclickMask | `() => void` | -      | Triggered when clicking mask layer, even if maskClosable is false. |
| onclose     | `() => void` | -      | Triggered when popup closes.                                       |

## Popup Snippets

| Name     | Type                                                                | Parameters | Description    |
| -------- | ------------------------------------------------------------------- | ---------- | -------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Popup content. |

## SvelteEasing

```javascript
type SvelteEasing =
    | 'backIn'
    | 'backInOut'
    | 'backOut'
    | 'bounceIn'
    | 'bounceInOut'
    | 'bounceOut'
    | 'circIn'
    | 'circInOut'
    | 'circOut'
    | 'cubicIn'
    | 'cubicInOut'
    | 'cubicOut'
    | 'elasticIn'
    | 'elasticInOut'
    | 'elasticOut'
    | 'expoIn'
    | 'expoInOut'
    | 'expoOut'
    | 'linear'
    | 'quadIn'
    | 'quadInOut'
    | 'quadOut'
    | 'quartIn'
    | 'quartInOut'
    | 'quartOut'
    | 'quintIn'
    | 'quintInOut'
    | 'quintOut'
    | 'sineIn'
    | 'sineInOut'
    | 'sineOut';
```



================================================
FILE: docs/mds/components/popup/FAQ.md
================================================



================================================
FILE: docs/mds/components/popup/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/popup/guide.md
================================================
## Popup 与 BottomSheet

在 STDF 的设计思路内，BottomSheet 与 Popup 都属于界面内的浮动交互，一般用于在页面内进行一些二级操作场景，在组件使用上有一些相似之处。**但弹出层 Popup 是「层」的概念，而底部浮窗 BottomSheet 是「窗」的概念**。

Popup 作为弹出层，内部一般不宜做比较复杂步骤的交互，默认点击遮罩层就可以关闭，但可以自定义弹出的位置、大小、过渡动画、方向、样式等多项参数。**重样式轻逻辑。**

BottomSheet 作为底部浮窗，就只能从底部弹出。「浮」体现在可以通过滑动其内部的头部区域来控制其固定高度；而「窗」区别于「层」的是，BottomSheet 有自己的头部区域，可以自定义头部内容，并派发出关闭、返回、滑动等类似窗口交互的事件，可以用于一些相对复杂的交互场景，默认点击遮罩不可关闭。**重逻辑轻样式。**

## size

弹出层的大小由 size 决定，表示占据整个页面大小的百分比，当位置为 top、bottom、center 时表示弹出层的高占据视窗高度的比例，当位置为 left 和 right 时表示弹出层的宽占据视窗宽度的比例。值为 0 时弹出层不再固定宽高，而是由内部元素的宽或高决定。

## 动画

弹出层出现与退出的过渡动画类型由 easeType 决定，默认值为 cubicOut，可选值有 31 个（一个线性动画 linear 与下面 30 种非线性动画），具体值可参考 [svelte/easing](https://svelte.dev/docs#run-time-svelte-easing)，具体非线性动效可参考 [ease visualiser](https://svelte.dev/examples/easing)。而动画出现与退出的时间由 duration 与 outDuration 决定。

| ease    | in        | out        | inOut        |
| ------- | --------- | ---------- | ------------ |
| back    | backIn    | backOut    | backInOut    |
| bounce  | bounceIn  | bounceOut  | bounceInOut  |
| circ    | circIn    | circOut    | circInOut    |
| cubic   | cubicIn   | cubicOut   | cubicInOut   |
| elastic | elasticIn | elasticOut | elasticInOut |
| expo    | expoIn    | expoOut    | expoInOut    |
| quad    | quadIn    | quadOut    | quadInOut    |
| quart   | quartIn   | quartOut   | quartInOut   |
| quint   | quintIn   | quintOut   | quintInOut   |
| sine    | sineIn    | sineOut    | sineInOut    |

## 间距

当弹出层位置是 top、bottom、center 时，弹出层的宽度会占据整个视窗宽度，此时若需要弹出层的左右两侧有间距，则可通过 px 这个 Props 来设置。当弹出层位置是 left、right 时，弹出层的高度会占据整个视窗高度，此时若需要弹出层的上下两侧有间距，则可以通过 py 来设置。请参考示例。

## transitionDistance

一般来说，如果不确定弹出层内容的宽高（比如动态展示协议）或预计内容会很多，请尽量使用固定大小限制弹出层大小，使内部元素滚动展示。此时，弹出层出现时，会从页面可视区域外向可视区域内移入，移动距离就是弹出层的大小。

当弹出层内容的宽高确定时，可以设置弹出层的 size 为 0，弹出层大小由内部元素决定，但组件无法提前获悉弹出层的宽高，因此无法执行弹出层的动画效果，此时就需要外部传入 transitionDistance 即弹出层的宽或高（位置为 top 和 bottom 时需要传入高，位置为 left 和 right 时需要传入宽）来固定动画执行的距离，单位为 px。此值无需严格准确，只要保证动画执行的距离合适即可。

由于位置为 center 时动画效果为缩放，无论弹出层的宽高为多少都无需传入 transitionDistance。

## 背景色

弹出层的背景色会自动适配亮暗模式，当 transparent 为 true 时，弹出层的背景色为透明，可以满足其他不需要背景色的需求。

## 事件

弹出层默认点击遮罩会关闭，若不需要此功能，可以设置 maskClosable 为 false。另外支持通过 onclose 来监听弹出层退出事件，而 onclickMask 事件则是点击遮罩层时触发，即使 maskClosable 为 false 也会触发。

## 优化

由于移动端的 Safari、Chrome 或其他一些浏览器滚动页面时会动态显示工具栏或地址栏（多此一举），导致页面的高度也会动态变化，Popup 针对这一情况也做了优化。当 dynamicFixed 为 true 时滚动页面时会动态地更新页面高度，相对应地弹出层相对于页面的位置也会动态更新。

当然，这个滚动监听会有微弱的性能损失，如果你的项目中不需要此功能（比如在可控的 webview 内使用），可以设置 dynamicFixed 为 false 来关闭。



================================================
FILE: docs/mds/components/popup/guide_en.md
================================================
## Popup vs. BottomSheet

In the STDF design philosophy, both BottomSheet and Popup are floating interactions within the interface, generally used for secondary operations within a page. There are some similarities in the use of the components. However, the Popup is a "layer" concept, while the BottomSheet is a "window" concept.

As a pop-up layer, the Popup is generally not suitable for complex step-by-step interactions. Clicking the mask layer should close the Popup by default, but you can customize the position, size, transition animation, direction, style, and other parameters of the Popup. **The emphasis is on style rather than logic.**

As a bottom floating window, the BottomSheet can only be popped up from the bottom. The "floating" means that its fixed height can be controlled by sliding its inner header area. Unlike the Popup's "layer" concept, the BottomSheet has its own header area, which allows custom header content and dispatches close, return, slide, and other window-like interactive events. It can be used for relatively complex interaction scenarios, and by default, clicking the mask cannot close the BottomSheet. **The emphasis is on logic rather than style.**

## size

The size of the popup is determined by the size property, which represents the percentage of the entire page size. When the position is top, bottom or center, it represents the proportion of the popup's height to the viewport height. When the position is left or right, it represents the proportion of the popup's width to the viewport width. When the value is 0, the size of the popup is no longer fixed, but determined by the width or height of the internal elements.

## Animation

The transition animation type when the Popup appears and exits is determined by the easeType property, with a default value of cubicOut. There are 31 optional values (including a linear animation and 30 non-linear animations), specifically documented at [svelte/easing](https://svelte.dev/docs#run-time-svelte-easing), and the specific non-linear effects can be seen at the [ease visualizer](https://svelte.dev/examples/easing). The duration of the animation appearing and exiting is determined by the duration and outDuration properties.

| ease    | in        | out        | inOut        |
| ------- | --------- | ---------- | ------------ |
| back    | backIn    | backOut    | backInOut    |
| bounce  | bounceIn  | bounceOut  | bounceInOut  |
| circ    | circIn    | circOut    | circInOut    |
| cubic   | cubicIn   | cubicOut   | cubicInOut   |
| elastic | elasticIn | elasticOut | elasticInOut |
| expo    | expoIn    | expoOut    | expoInOut    |
| quad    | quadIn    | quadOut    | quadInOut    |
| quart   | quartIn   | quartOut   | quartInOut   |
| quint   | quintIn   | quintOut   | quintInOut   |
| sine    | sineIn    | sineOut    | sineInOut    |

## Spacing

When the position of the popup layer is top, bottom, or center, and the width of the popup layer takes up the entire viewport, you can use the `px` prop to set the left and right spacing. When the position of the popup layer is left or right, and the height of the popup layer takes up the entire viewport, you can use the `py` prop to set the top and bottom spacing. Please refer to the example.

## Transition Distance

When the size of the popup layer content is not certain, or a large amount of content is expected (such as displaying agreements dynamically), it is recommended to use a fixed size to limit the size of the popup layer, allowing the internal elements to scroll. In this case, when the popup layer appears, it will move from outside the visible area of the page into the visible area, and the distance moved will be the size of the popup layer.

When the width and height of the popup layer content are determined, you can set the `size` of the popup layer to 0, and the size will be determined by the internal elements. However, the component cannot obtain the width and height of the popup layer in advance, which causes the animation effect to not be executed. In this case, transitionDistance needs to be provided externally to specify the width or height of the popup layer (height needs to be provided for the top and bottom positions, while width needs to be provided for the left and right positions) to fix the animation distance, in pixels. It doesn't need to be exact, as long as the animation distance is appropriate.

Note that when the position of the popup layer is center, the animation effect is scaling, so `transitionDistance` does not need to be provided regardless of the size of the popup layer.

## Background Color

The background color of the popup layer will automatically adapt to the light and dark background. When `transparent` is set to true, the background color of the popup layer will be transparent, which can satisfy needs where no background color is required.

## Events

By default, clicking on the mask of the popup layer will close it. If this function is not required, you can set `maskClosable` to false. Additionally, `onclose` is supported to listen for the exit event of the popup layer, while `onclickMask` is triggered when the mask layer is clicked. Even if `maskClosable` is set to false, this event will still be triggered.

## Optimization

Popup has also been optimized to dynamically update the page height and the position of the popup layer relative to the page with `dynamicFixed` set to true when scrolling the page in mobile versions of Safari, Chrome, or other browsers. However, this scroll listener will have a slight performance loss. If this feature is not needed in your project (such as when using a controllable webview), you can set `dynamicFixed` to false to disable it.



================================================
FILE: docs/mds/components/popup/version.md
================================================



================================================
FILE: docs/mds/components/popup/version_en.md
================================================



================================================
FILE: docs/mds/components/progress/api.md
================================================
## Progress Props

| 名称            | 类型                                 | 默认值    | 必传 | 说明                                              |
| --------------- | ------------------------------------ | --------- | ---- | ------------------------------------------------- |
| percent         | `number`                             | `66`      | N    | 百分比。                                          |
| percentPosition | `'inner'\|'right'\|'block'\|null`    | `'right'` | N    | 百分比位置。                                      |
| height          | `'1'\|'2'\|'3'\|'4'`                 | `'2'`     | N    | 高度。                                            |
| radius          | `'full'\|'middle'\|'none'`           | `'full'`  | N    | 圆角风格。                                        |
| inactive        | `boolean`                            | `false`   | N    | 是否置灰。                                        |
| overflowPercent | `number`                             | `10`      | N    | percentPosition 为 `'inner'` 时，文字溢出的阀值。 |
| duration        | `'150'\|'300'\|'500'\|'700'\|'1000'` | `'300'`   | N    | 动画过度时间（ms）。                              |
| injClass        | `string`                             | `''`      | N    | 激活进度条注入 Class 名称。                       |
| trackInjClass   | `string`                             | `''`      | N    | 轨道条注入 Class 名称。                           |

## Progress Snippets

| 名称     | 类型                                                                | 参数 | 说明                 |
| -------- | ------------------------------------------------------------------- | ---- | -------------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 传入时渲染文字内容。 |



================================================
FILE: docs/mds/components/progress/api_en.md
================================================
## Progress Props

| Name            | Type                                 | Default   | Required | Description                                                       |
| --------------- | ------------------------------------ | --------- | -------- | ----------------------------------------------------------------- |
| percent         | `number`                             | `66`      | N        | Percentage value.                                                 |
| percentPosition | `'inner'\|'right'\|'block'\|null`    | `'right'` | N        | Position of percentage text.                                      |
| height          | `'1'\|'2'\|'3'\|'4'`                 | `'2'`     | N        | Height of progress bar.                                           |
| radius          | `'full'\|'middle'\|'none'`           | `'full'`  | N        | Border radius style.                                              |
| inactive        | `boolean`                            | `false`   | N        | Whether to show in inactive state.                                |
| overflowPercent | `number`                             | `10`      | N        | Text overflow threshold when percentPosition is set to `'inner'`. |
| duration        | `'150'\|'300'\|'500'\|'700'\|'1000'` | `'300'`   | N        | Animation transition duration (ms).                               |
| injClass        | `string`                             | `''`      | N        | Injected class name for active progress bar.                      |
| trackInjClass   | `string`                             | `''`      | N        | Injected class name for track bar.                                |

## Progress Snippets

| Name     | Type                                                                | Params | Description                                 |
| -------- | ------------------------------------------------------------------- | ------ | ------------------------------------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -      | Renders custom text content when passed in. |



================================================
FILE: docs/mds/components/progress/FAQ.md
================================================



================================================
FILE: docs/mds/components/progress/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/progress/guide.md
================================================
## Snippet

当传入 children 时，百分比内容不再使用默认百分比文字，而是使用传入的 children 渲染。

## overflowPercent

当 percentPosition 为 `'inner'` 且百分比数值较低时，百分比文字会溢出，overflowPercent 为溢出的阀值，当百分比小于该值时，百分比文字会放置于进度条右侧。

## CSS 注入

通过 injClass 和 trackInjClass 参数可以向组件内部的激活进度条和轨道条元素注入 CSS 名称（不仅限于 Tailwind CSS），这将使组件样式有更多自定义可能性，示例中通过 injClass 和 trackInjClass 实现了自定义进度条颜色。

若注入的 class 没生效，请在注入的 class 名称前添加“!” ，可参考 [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier)。



================================================
FILE: docs/mds/components/progress/guide_en.md
================================================
## Snippet

When children is passed in, the percentage content will no longer use the default percentage text, but will render using the passed in children.

## overflowPercent

When percentPosition is set to `'inner'` and the percentage value is low, the percentage text may overflow. overflowPercent is the overflow threshold - when the percentage is less than this value, the percentage text will be placed on the right side of the progress bar.

## CSS Injection

The injClass and trackInjClass parameters can be used to inject CSS class names (not limited to Tailwind CSS) into the active progress bar and track bar elements inside the component. This provides more customization possibilities for component styling. The example demonstrates customizing progress bar colors through injClass and trackInjClass.

If the injected class is not taking effect, try adding "!" before the class name. See [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier) for reference.



================================================
FILE: docs/mds/components/progress/version.md
================================================



================================================
FILE: docs/mds/components/progress/version_en.md
================================================



================================================
FILE: docs/mds/components/progressLoop/api.md
================================================
## ProgressLoop Props

| 名称          | 类型                                 | 默认值  | 必传 | 说明                               |
| ------------- | ------------------------------------ | ------- | ---- | ---------------------------------- |
| percent       | `number`                             | `66`    | N    | 百分比。                           |
| strokeWidth   | `number`                             | `2`     | N    | 圆环宽度。                         |
| butt          | `boolean`                            | `false` | N    | 端点是否直角。                     |
| reverse       | `boolean`                            | `false` | N    | 是否反向（逆时针）。               |
| duration      | `'150'\|'300'\|'500'\|'700'\|'1000'` | `'300'` | N    | 动画过渡时间。                     |
| gradient      | `[string,string]\|null`              | `[]`    | N    | 渐变色，开始色与结束色组成的数组。 |
| injClass      | `String`                             | `''`    | N    | 激活进度环注入 Class 名称。        |
| trackInjClass | `String`                             | `''`    | N    | 轨道环注入 Class 名称。            |

## ProgressLoop Snippets

| 名称     | 类型                                                                | 参数 | 说明                 |
| -------- | ------------------------------------------------------------------- | ---- | -------------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 传入时渲染文字内容。 |



================================================
FILE: docs/mds/components/progressLoop/api_en.md
================================================
## ProgressLoop Props

| Name          | Type                                 | Default | Required | Description                                      |
| ------------- | ------------------------------------ | ------- | -------- | ------------------------------------------------ |
| percent       | `number`                             | `66`    | N        | Percentage value.                                |
| strokeWidth   | `number`                             | `2`     | N        | Width of the circular ring.                      |
| butt          | `boolean`                            | `false` | N        | Whether the endpoints are square.                |
| reverse       | `boolean`                            | `false` | N        | Whether to reverse direction (counterclockwise). |
| duration      | `'150'\|'300'\|'500'\|'700'\|'1000'` | `'300'` | N        | Animation transition duration.                   |
| gradient      | `[string,string]\|null`              | `[]`    | N        | Gradient colors, array of start and end colors.  |
| injClass      | `String`                             | `''`    | N        | Injected class name for active progress ring.    |
| trackInjClass | `String`                             | `''`    | N        | Injected class name for track ring.              |

## ProgressLoop Snippets

| Name     | Type                                                                | Params | Description                       |
| -------- | ------------------------------------------------------------------- | ------ | --------------------------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -      | Renders text content when passed. |



================================================
FILE: docs/mds/components/progressLoop/FAQ.md
================================================



================================================
FILE: docs/mds/components/progressLoop/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/progressLoop/guide.md
================================================
## 进度环大小与宽度

进度环 ProgressLoop 的大小由外层容器的宽度决定，组件内部使用了 24＊24 画布大小的 svg 渲染，铺满父容器。而宽度 strokeWidth 理论上支持 0-12 的任意数值，但宽度太大时圆环将会很不美观。

## Snippet

当传入 children 时，百分比内容不再使用默认百分比文字，而是使用传入的 children 渲染。

## CSS 注入

通过 injClass 和 trackInjClass 参数可以向组件内部的激活进度环和轨道环元素注入 CSS 名称（不仅限于 Tailwind CSS），这将使组件样式有更多自定义可能性，示例中通过 injClass 和 trackInjClass 实现了自定义进度环颜色。

若注入的 class 没生效，请在注入的 class 名称前添加“!” ，可参考 [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier)。



================================================
FILE: docs/mds/components/progressLoop/guide_en.md
================================================
## Progress loop size and width

The size of the progress loop, ProgressLoop, is determined by the width of the outer container. The component uses an SVG rendering with a canvas size of 24\*24, which fills the parent container. The width, strokeWidth, theoretically supports any value between 0 to 12, but when the width is too large, the circular ring may not be aesthetically pleasing.

## Snippet

When children is passed in, the percentage content no longer uses the default percentage text, but uses the passed children to render.

## CSS injection

The injClass and trackInjClass parameters can be used to inject CSS names (not limited to Tailwind CSS) into the activating progress ring and track ring elements inside the component. This will provide more possibilities for customizing the component style. In the example, custom progress loop colors are achieved using injClass and trackInjClass.

If the injected class is not effective, add "!" before the class name. For the reference, please see the [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier).



================================================
FILE: docs/mds/components/progressLoop/version.md
================================================



================================================
FILE: docs/mds/components/progressLoop/version_en.md
================================================



================================================
FILE: docs/mds/components/radio/api.md
================================================
## Radio Props

| 名称         | 类型                                                                         | 默认值      | 必传 | 说明                     |
| ------------ | ---------------------------------------------------------------------------- | ----------- | ---- | ------------------------ |
| data         | `RadioItem[]`                                                                | `[]`        | Y    | 选项数据。               |
| layout       | `'v'\|'h'\|'inline'`                                                         | `'v'`       | N    | 排列方式。               |
| value        | `string`                                                                     | `''`        | N    | 选中的 value。           |
| textPosition | `'l'\|'r'\|'t'\|'b'`                                                         | `'r'`       | N    | 选项内容区域位置。       |
| icon         | `'default'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'default'` | N    | 未选中选项图标区域内容。 |
| iconChecked  | `'default'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'default'` | N    | 选中选项图标区域内容。   |

## Radio Events

| 名称     | 类型                      | 参数                        | 描述                                             |
| -------- | ------------------------- | --------------------------- | ------------------------------------------------ |
| onchange | `(value: string) => void` | value - 选中的 Radio 标识符 | 点击 RadioItem（即 Radio 的 value 变化）时触发。 |

## Radio Snippets

| 名称       | 类型                                                                                       | 参数            | 说明                     |
| ---------- | ------------------------------------------------------------------------------------------ | --------------- | ------------------------ |
| radioChild | [`Snippet<[{ item: RadioItem }]>`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | item - 选项数据 | 当选项区域自定义时使用。 |

## RadioItem Props

| 名称         | 类型                                                                         | 默认值      | 必传 | 说明                                |
| ------------ | ---------------------------------------------------------------------------- | ----------- | ---- | ----------------------------------- |
| name         | `string`                                                                     | `''`        | Y    | 标识符，对应 Radio Props 的 value。 |
| label        | `string`                                                                     | `''`        | N    | 选项内容。                          |
| layout       | `'v'\|'h'\|'inline'`                                                         | `'v'`       | N    | 排列方式。                          |
| textPosition | `'l'\|'r'\|'t'\|'b'`                                                         | `'r'`       | N    | 选项内容区域位置。                  |
| icon         | `'default'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'default'` | N    | 未选中选项图标区域内容。            |
| iconChecked  | `'default'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'default'` | N    | 选中选项图标区域内容。              |
| checked      | `boolean`                                                                    | `false`     | N    | 是否选中。                          |

## RadioItem Events

| 名称    | 类型                     | 参数                | 说明         |
| ------- | ------------------------ | ------------------- | ------------ |
| onclick | `(name: string) => void` | name - 点击项标识符 | 点击时触发。 |

## RadioItem Snippets

| 名称     | 类型                                                                | 参数 | 说明           |
| -------- | ------------------------------------------------------------------- | ---- | -------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 选项区域内容。 |



================================================
FILE: docs/mds/components/radio/api_en.md
================================================
## Radio Props

| Name         | Type                                                                         | Default     | Required | Description                            |
| ------------ | ---------------------------------------------------------------------------- | ----------- | -------- | -------------------------------------- |
| data         | `RadioItem[]`                                                                | `[]`        | Y        | Option data.                           |
| layout       | `'v'\|'h'\|'inline'`                                                         | `'v'`       | N        | Layout mode.                           |
| value        | `string`                                                                     | `''`        | N        | Selected value.                        |
| textPosition | `'l'\|'r'\|'t'\|'b'`                                                         | `'r'`       | N        | Position of option content area.       |
| icon         | `'default'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'default'` | N        | Content of unchecked option icon area. |
| iconChecked  | `'default'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'default'` | N        | Content of checked option icon area.   |

## Radio Events

| Name     | Type                      | Parameters                        | Description                                                |
| -------- | ------------------------- | --------------------------------- | ---------------------------------------------------------- |
| onchange | `(value: string) => void` | value - Selected Radio identifier | Triggered when RadioItem is clicked (Radio value changes). |

## Radio Snippets

| Name       | Type                                                                                       | Parameters         | Description                            |
| ---------- | ------------------------------------------------------------------------------------------ | ------------------ | -------------------------------------- |
| radioChild | [`Snippet<[{ item: RadioItem }]>`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | item - Option data | Used when customizing the option area. |

## RadioItem Props

| Name         | Type                                                                         | Default     | Required | Description                                   |
| ------------ | ---------------------------------------------------------------------------- | ----------- | -------- | --------------------------------------------- |
| name         | `string`                                                                     | `''`        | Y        | Identifier, corresponds to Radio Props value. |
| label        | `string`                                                                     | `''`        | N        | Option content.                               |
| layout       | `'v'\|'h'\|'inline'`                                                         | `'v'`       | N        | Layout mode.                                  |
| textPosition | `'l'\|'r'\|'t'\|'b'`                                                         | `'r'`       | N        | Position of option content area.              |
| icon         | `'default'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'default'` | N        | Content of unchecked option icon area.        |
| iconChecked  | `'default'\|null`\|[`Icon`](https://stdf.design/components?nav=icon&tab=1) | `'default'` | N        | Content of checked option icon area.          |
| checked      | `boolean`                                                                    | `false`     | N        | Whether checked.                              |

## RadioItem Events

| Name    | Type                     | Parameters                     | Description             |
| ------- | ------------------------ | ------------------------------ | ----------------------- |
| onclick | `(name: string) => void` | name - Clicked item identifier | Triggered when clicked. |

## RadioItem Snippets

| Name     | Type                                                                | Parameters | Description          |
| -------- | ------------------------------------------------------------------- | ---------- | -------------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Option area content. |



================================================
FILE: docs/mds/components/radio/FAQ.md
================================================



================================================
FILE: docs/mds/components/radio/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/radio/guide.md
================================================
> Radio 使用了图标 ri-radio-button-line 和 ri-checkbox-blank-circle-line，请确保项目的 symbol.svg 文件中包含这些图标。详细信息请参考 [STDF-指南 - 图标](https://stdf.design/guide/icon)。

## 说明

由于移动端横向显示内容有限，Radio 默认为纵向布局，横向布局建议只用作简单使用。当选项较多、内容较长或显示内容较多时建议使用纵向布局，

Radio 通过 value 传入一个值作为内部 Radio 的初始标识符；而当 RadioItem 被点击时，Radio 通过 onchange 事件，可以获取到当前 value，即当前选定 RadioItem 的 name。

## icon && iconChecked

Radio Props 的 icon 默认值 `'default'` 会按照 Remix Icon 的 ri-checkbox-blank-circle-line 以 Icon 组件形式渲染；传入 `null` 表示未选中选项图标区域不显示内容；也可以传入 Icon Props，未选中选项图标区域将会以传入的参数以 Icon 组件形式渲染。

iconChecked 与 icon 逻辑一样，对应的是选中选项的图标区域内容。

## Radio Snippets

当传入 radioChild 时，Radio 的每条 RadioItem 的内容区域将会使用 radioChild 的内容区域，可结合 Radio 的 onchange 事件获取到的 value，自由设计选中与未选中的效果。

注：虽然有 Tailwind 写样式比较方便，但过多的自定义将会失去使用组件库的意义。

## 点击区域优化

为了优化体验，RadioItem 整个区域都可以点击，将会激活与之对应的 value，不仅仅只可以点击文字或图标区域。

## ActionSheet、Picker、Radio

ActionSheet、Picker、Radio 三者都是给出数据，让用户进行数据选择或执行一些操作，但何时使用哪个组件呢？

- Radio 一般用于单选数据，数据量固定且较少，需要在 UI 界面上直接展示选项，方便用户在界面交互时对多条数据有个概览，比如性别选择。
- ActionSheet 一般用于选择之后立即执行一些操作，选项固定且较少，但不需要在 UI 界面上直接展示选项，比如做一些删除、修改等操作。
- Picker 一般用于选择单条或多条数据，数据量较大或无法确定长度的动态数据，或用于一些联动数据的选择，比如省市区选择。



================================================
FILE: docs/mds/components/radio/guide_en.md
================================================
> Radio uses icons ri-radio-button-line and ri-checkbox-blank-circle-line. Please ensure these icons are included in your project's symbol.svg file. For detailed information, please refer to [STDF-Guide-Icon](https://stdf.design/guide/icon).

## Description

Due to limited horizontal display space on mobile devices, Radio defaults to vertical layout. Horizontal layout is recommended only for simple use cases. When there are multiple options, longer content, or more display content, vertical layout is recommended.

Radio accepts a value prop as the initial identifier for internal Radio items. When a RadioItem is clicked, Radio can get the current value through the onchange event, which is the name of the currently selected RadioItem.

## icon && iconChecked

The default value `'default'` for Radio Props' icon will render as an Icon component using Remix Icon's ri-checkbox-blank-circle-line. Passing `null` means no content will be displayed in the unchecked option's icon area. You can also pass Icon Props, and the unchecked option's icon area will render as an Icon component with the passed parameters.

iconChecked follows the same logic as icon, corresponding to the icon area content of the selected option.

## Radio Snippets

When radioChild is passed, the content area of each RadioItem in Radio will use the content area of radioChild. You can freely design the selected and unselected effects by combining with the value obtained from Radio's onchange event.

Note: Although Tailwind makes styling convenient, too much customization will defeat the purpose of using a component library.

## Click Area Optimization

To optimize the user experience, the entire area of RadioItem is clickable and will activate its corresponding value, not just the text or icon areas.

## ActionSheet, Picker, Radio

ActionSheet, Picker, and Radio all provide data for users to select or perform operations, but when should each component be used?

- Radio is generally used for single-selection data with a fixed and small number of options that need to be directly displayed on the UI interface, allowing users to have an overview of multiple data points during interface interaction, such as gender selection.
- ActionSheet is generally used when actions need to be executed immediately after selection, with fixed and fewer options that don't need to be directly displayed on the UI interface, such as delete or modify operations.
- Picker is generally used for selecting single or multiple data points with a large amount of data or dynamic data of uncertain length, or for selecting linked data, such as province-city-district selection.



================================================
FILE: docs/mds/components/radio/version.md
================================================



================================================
FILE: docs/mds/components/radio/version_en.md
================================================



================================================
FILE: docs/mds/components/rate/api.md
================================================
## Rate Props

| 名称      | 类型                                                                         | 默认值      | 必传 | 说明                  |
| --------- | ---------------------------------------------------------------------------- | ----------- | ---- | --------------------- |
| value     | `number`                                                                     | `4`         | N    | 选定值。              |
| total     | `number`                                                                     | `5`         | N    | 总分。               |
| width     | `number`                                                                     | `24`        | N    | 单个内容宽度（px） 。 |
| height    | `number`                                                                     | `24`        | N    | 单个内容高度（px）。  |
| opacity   | `'0.05'\|'0.1'\|'0.2'\|'0.3'\|'0.4'\|'0.5'\|'0.6'\|'0.7'\|'0.8'\|'0.9'\|'1'` | `0.2`       | N    | 未选中内容透明度。   |
| space     | `'0'\|'1'\|'2'\|'3'\|'4'\|'8'`                                               | `'3'`       | N    | 内容间距。            |
| half      | `boolean`                                                                    | `false`     | N    | 是否允许半选。        |
| zero      | `boolean`                                                                    | `false`     | N    | 是否允许 0 分。      |
| vertical  | `boolean`                                                                    | `false`     | N    | 是否垂直半选。       |
| disabled  | `boolean`                                                                    | `false`     | N    | 是否禁用。            |
| readonly  | `boolean`                                                                    | `false`     | N    | 是否只读。            |
| custom    | `boolean`                                                                    | `false`     | N    | 是否自定义内容。      |
| animation | `'current'\|'active'\|null`                                                  | `'current'` | N    | 点击动画类型。        |

## Rate Events

| 名称    | 类型                      | 参数               | 描述       |
| ------- | ------------------------- | ------------------ | ---------- |
| onclick | `(value: number) => void` | value - 当前 value | 点击触发。 |

## Rate Snippets

| 名称     | 类型                                                                | 参数 | 说明                     |
| -------- | ------------------------------------------------------------------- | ---- | ------------------------ |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 将作为 Rate 的单个内容。 |



================================================
FILE: docs/mds/components/rate/api_en.md
================================================
## Rate Props

| Name      | Type                                                                         | Default     | Required | Description                                |
| --------- | ---------------------------------------------------------------------------- | ----------- | -------- | ------------------------------------------ |
| value     | `number`                                                                     | `4`         | N        | Selected value.                            |
| total     | `number`                                                                     | `5`         | N        | Total score.                               |
| width     | `number`                                                                     | `24`        | N        | Width of single content (px).              |
| height    | `number`                                                                     | `24`        | N        | Height of single content (px).             |
| opacity   | `'0.05'\|'0.1'\|'0.2'\|'0.3'\|'0.4'\|'0.5'\|'0.6'\|'0.7'\|'0.8'\|'0.9'\|'1'` | `0.2`       | N        | Opacity of unselected content.             |
| space     | `'0'\|'1'\|'2'\|'3'\|'4'\|'8'`                                               | `'3'`       | N        | Content spacing.                           |
| half      | `boolean`                                                                    | `false`     | N        | Whether to allow half selection.           |
| zero      | `boolean`                                                                    | `false`     | N        | Whether to allow 0 score.                  |
| vertical  | `boolean`                                                                    | `false`     | N        | Whether to enable vertical half selection. |
| disabled  | `boolean`                                                                    | `false`     | N        | Whether to disable.                        |
| readonly  | `boolean`                                                                    | `false`     | N        | Whether it's read-only.                    |
| custom    | `boolean`                                                                    | `false`     | N        | Whether to use custom content.             |
| animation | `'current'\|'active'\|null`                                                  | `'current'` | N        | Click animation type.                      |

## Rate Events

| Name    | Type                      | Parameters            | Description         |
| ------- | ------------------------- | --------------------- | ------------------- |
| onclick | `(value: number) => void` | value - Current value | Triggered on click. |

## Rate Snippets

| Name     | Type                                                                | Parameters | Description                              |
| -------- | ------------------------------------------------------------------- | ---------- | ---------------------------------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Will be used as single content for Rate. |



================================================
FILE: docs/mds/components/rate/FAQ.md
================================================



================================================
FILE: docs/mds/components/rate/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/rate/guide.md
================================================
> Rate 使用了图标 ri-star-fill，请确保项目的 symbol.svg 文件中包含这些图标。详细信息请参考 [STDF-指南 - 图标](https://stdf.design/guide/icon)。

## value 与 total 注意事项

1. 传入的 value 不允许大于 total；
2. total 必须能被 1 整除；
3. 非半选时，value 必须能被 1 整除；
4. 半选时，value 必须能被 0.5 整除。

## 点击优化

考虑移动端交互方式，允许半选时点击会在半选和全选之间切换，允许零分时点击第一项会在 0、0.5、1 之间切换。

注意：考虑点击区域，**width 与 height 的值请不要小于 20**。

## 点击动画

通过 animation 来控制点击动画，`'current'` 表示仅点击项有动画，`'active'` 表示点击项及之前的项都有动画，`null` 表示无动画。

## 特别注意

当需要自定义内容时，可以通过传入 Snippet 实现，此时请务必**传入自定义内容的宽高**。



================================================
FILE: docs/mds/components/rate/guide_en.md
================================================
> Rate uses the icon ri-star-fill, please ensure that the symbol.svg file in your project includes this icon. For details, please refer to [STDF-Guide-Icon](https://stdf.design/guide/icon).

## Notes on value and total

1. The passed-in value cannot be greater than the total;
2. The value of total must be divisible by 1;
3. When not allowing half selection, the value must be divisible by 1;
4. When allowing half selection, the value must be divisible by 0.5.

## Click optimization

Considering the interaction mode on mobile devices, when allowing half selection, clicking will switch between half selection and full selection, and when allowing zero scores, clicking the first item will switch between 0, 0.5, and 1.

Note: When considering the click area, please make sure that **the values of width and height are not less than 20**.

## Click Animation

Control click animation through animation, `'current'` means only the clicked item has animation, `'active'` means the clicked item and all previous items have animation, and `null` means no animation.

## Special attention

When custom content is needed, it can be achieved by passing in Snippet. At this time, **be sure to pass in the width and height of the custom content**.



================================================
FILE: docs/mds/components/rate/version.md
================================================



================================================
FILE: docs/mds/components/rate/version_en.md
================================================



================================================
FILE: docs/mds/components/skeleton/api.md
================================================
## Skeleton Props

| 名称      | 类型                                                                   | 默认值  | 必传 | 说明                                                                  |
| --------- | ---------------------------------------------------------------------- | ------- | ---- | --------------------------------------------------------------------- |
| type      | `'div'\|'p'\|'img'\|'video'\|'code'\|'qrcode'\|'barcode'`              | `'div'` | N    | Skeleton 类型。                                                       |
| width     | `'2'\|'4'\|'6'\|'8'\|'12'\|'16'\|'24'\|'32'\|'48'\|'64'\|'96'\|'full'` | `'6'`   | N    | 宽度。                                                                |
| height    | `'1'\|'2'\|'4'\|'6'\|'8'\|'12'\|'16'\|'24'\|'32'\|'48'\|'64'\|'96'`    | `'6'`   | N    | 高度。                                                                |
| radius    | `'none'\|'sm'\|'md'\|'xl'\|'2xl'\|'3xl'\|'full'`                       | `'sm'`  | N    | 圆角风格。                                                            |
| padding   | `'0.5'\|'1'\|'2'\|'4'\|'8'`                                            | `'1'`   | N    | 内边距。                                                              |
| lines     | `number`                                                               | `3`     | N    | 行数，仅在 type 为 p 时生效。                                         |
| iconRatio | `number`                                                               | `0.6`   | N    | 内部图标比例，仅在 type 为 img、video、code、qrcode、barcode 时生效。 |



================================================
FILE: docs/mds/components/skeleton/api_en.md
================================================
## Skeleton Props

| Name      | Type                                                                   | Default | Required | Description                                                                               |
| --------- | ---------------------------------------------------------------------- | ------- | -------- | ----------------------------------------------------------------------------------------- |
| type      | `'div'\|'p'\|'img'\|'video'\|'code'\|'qrcode'\|'barcode'`              | `'div'` | N        | Type of skeleton.                                                                         |
| width     | `'2'\|'4'\|'6'\|'8'\|'12'\|'16'\|'24'\|'32'\|'48'\|'64'\|'96'\|'full'` | `'6'`   | N        | Width.                                                                                    |
| height    | `'1'\|'2'\|'4'\|'6'\|'8'\|'12'\|'16'\|'24'\|'32'\|'48'\|'64'\|'96'`    | `'6'`   | N        | Height.                                                                                   |
| radius    | `'none'\|'sm'\|'md'\|'xl'\|'2xl'\|'3xl'\|'full'`                       | `'sm'`  | N        | Border radius style.                                                                      |
| padding   | `'0.5'\|'1'\|'2'\|'4'\|'8'`                                            | `'1'`   | N        | Padding.                                                                                  |
| lines     | `number`                                                               | `3`     | N        | Number of lines, only takes effect when type is p.                                        |
| iconRatio | `number`                                                               | `0.6`   | N        | Internal icon ratio, only takes effect when type is img, video, code, qrcode, or barcode. |



================================================
FILE: docs/mds/components/skeleton/FAQ.md
================================================



================================================
FILE: docs/mds/components/skeleton/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/skeleton/guide.md
================================================
> Skeleton 使用了图标 ri-image-fill、ri-movie-2-fill、ri-code-box-fill、ri-qr-code-fill、ri-barcode-fill，请确保项目的 symbol.svg 文件中包含这些图标。详细信息请参考 [STDF-指南 - 图标](https://stdf.design/guide/icon)。

## 说明

1. Skeleton 组件并不是必需组件，但它能优化页面加载过程中的视觉效果，进而有效地提升用户体验。

2. 对比 Loading 组件，Skeleton 组件更加不容易引起用户的注意，因为它的样式接近实际页面，而且它的过渡效果更加轻柔自然，能给用户一个页面的预期效果。

3. 为了满足如此多复杂的页面布局，使 Skeleton 更加接近实际页面轮廓，组件内部只是实现了基本的过渡效果与自身样式配置，页面整块 Skeleton 区域需开发者按照实际业务场景去布局，使用 Tailwind CSS 的 Flexbox 或 Grid 是很快的，况且这一过程相当于搭建实际页面之前的一次彩排，可以复用。

## type

Skeleton 组件目前提供了七种类型的骨架屏，分别是：`'div'|'p'|'img'|'video'|'code'|'qrcode'|'barcode'`，其中 code 是代码块，qrcode 是二维码，barcode 是条形码。

## 特殊

当 type 为 `'p'` 时可以通过 lines 属性来控制段落行数，此时最后一行的长度会在一个合适的范围内随机变化。



================================================
FILE: docs/mds/components/skeleton/guide_en.md
================================================
> Skeleton uses the icon ri-image-fill, ri-movie-2-fill, ri-code-box-fill,ri-qr-code-fill, ri-barcode-fill, please ensure that the symbol.svg file in your project includes these icons. For details, please refer to [STDF-Guide-Icon](https://stdf.design/guide/icon).

## Explanation

1. The Skeleton component is not a mandatory component, but it can optimize the visual effect during the page loading process, thereby effectively improving the user experience.

2. Compared with the Loading component, the Skeleton component is less likely to attract users' attention, because its style is close to the actual page, and its transition effect is more gentle and natural, which can give users an expected effect of the page.

3. In order to meet such complex page layouts and make the Skeleton more close to the actual page outline, the component internally only implements basic transition effects and self-style configuration. The entire Skeleton area of ​​the page needs to be layout according to the actual business scenario by developers. Using Tailwind CSS's Flexbox or Grid is fast, and this process is like a rehearsal before building the actual page, which can be reused.

## Type

The Skeleton component currently provides seven types of skeletons, which are: `'div'|'p'|'img'|'video'|'code'|'qrcode'|'barcode'`, where code is a code block, qrcode is a QR code, and barcode is a barcode.

## Special

When the type is `'p'`, you can control the number of lines in the paragraph through the lines attribute, and the length of the last line will randomly change within a reasonable range.



================================================
FILE: docs/mds/components/skeleton/version.md
================================================
## 0.2.11

- [!tag|B|2|]修复当使用 'img'/'video'/'code'/'qrcode'/'barcode' 等内容时，图标上下居中的问题。



================================================
FILE: docs/mds/components/skeleton/version_en.md
================================================
## 0.2.11

- [!tag|B|2|] Fix the problem of vertical centering of icons when using 'img'/'video'/'code'/'qrcode'/'barcode' and other content.



================================================
FILE: docs/mds/components/slider/api.md
================================================
## Slider Props

| 名称       | 类型                        | 默认值    | 必传 | 说明             |
| ---------- | --------------------------- | --------- | ---- | ---------------- |
| value      | `number`                    | `40`      | N    | 当前值。         |
| step       | `number`                    | `1`       | N    | 步长。           |
| minRange   | `number`                    | `0`       | N    | 可选最小值。     |
| maxRange   | `number`                    | `100`     | N    | 可选最大值。     |
| isRange    | `boolean`                   | `false`   | N    | 是否为区间选择。 |
| startValue | `number`                    | `20`      | N    | 区间选择开始值。 |
| endValue   | `number`                    | `60`      | N    | 区间选择结束值。 |
| showTip    | `'always'\|'never'\|'touch'` | `'touch'` | N    | 提示显示方式。   |
| radius     | `'none'\|'sm'\|'xl'\|'full'` | `'full'`  | N    | 圆角风格。       |
| lineBlock  | `boolean`                   | `false`   | N    | 滑块是否为线框。 |
| disabled   | `boolean`                   | `false`   | N    | 是否禁用。       |
| readonly   | `boolean`                   | `false`   | N    | 是否只读。       |

## Slider Events

| 名称     | 类型                                  | 参数                                      | 描述             |
| -------- | ------------------------------------- | ----------------------------------------- | ---------------- |
| onchange | `(values: [number, number?]) => void` | values - 当前取值数组（区间选择时两项）。 | 取值变化时触发。 |

## Slider Snippets

| 名称     | 类型                                                                | 参数 | 说明                     |
| -------- | ------------------------------------------------------------------- | ---- | ------------------------ |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 传入将渲染进度区域内容。 |



================================================
FILE: docs/mds/components/slider/api_en.md
================================================
## Slider Props

| Name       | Type                        | Default   | Required | Description                         |
| ---------- | --------------------------- | --------- | -------- | ----------------------------------- |
| value      | `number`                    | `40`      | N        | Current value.                      |
| step       | `number`                    | `1`       | N        | Step size.                          |
| minRange   | `number`                    | `0`       | N        | Minimum selectable value.           |
| maxRange   | `number`                    | `100`     | N        | Maximum selectable value.           |
| isRange    | `boolean`                   | `false`   | N        | Whether it's a range selection.     |
| startValue | `number`                    | `20`      | N        | Start value for range selection.    |
| endValue   | `number`                    | `60`      | N        | End value for range selection.      |
| showTip    | `'always'\|'never'\|'touch'` | `'touch'` | N        | Tip display mode.                   |
| radius     | `'none'\|'sm'\|'xl'\|'full'` | `'full'`  | N        | Border radius style.                |
| lineBlock  | `boolean`                   | `false`   | N        | Whether the slider is a line block. |
| disabled   | `boolean`                   | `false`   | N        | Whether it's disabled.              |
| readonly   | `boolean`                   | `false`   | N        | Whether it's read-only.             |

## Slider Events

| Name     | Type                                  | Parameters                                          | Description                   |
| -------- | ------------------------------------- | --------------------------------------------------- | ----------------------------- |
| onchange | `(values: [number, number?]) => void` | values - Current value array (two items for range). | Triggered when value changes. |

## Slider Snippets

| Name     | Type                                                                | Parameters | Description                                  |
| -------- | ------------------------------------------------------------------- | ---------- | -------------------------------------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Content to be rendered in the progress area. |



================================================
FILE: docs/mds/components/slider/FAQ.md
================================================



================================================
FILE: docs/mds/components/slider/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/slider/guide.md
================================================
## value、startValue、endValue、minRange、maxRange

传入 value、startValue、endValue 时，请确保在 minRange 与 maxRange 之间。

## step

传入 step 时，请尽量保证 (maxRange - minRange) / step 为整数，且考虑每一步的精度问题，太小可能导致无法快速滑动到需要的值，从而影响用户体验。

## 布局

Slider 未设置外部间距，请在页面布局时自行设置。

## Snippet

当传入 Snippet 时，Slider 的进度区域会使用 Snippet 渲染，参考示例。



================================================
FILE: docs/mds/components/slider/guide_en.md
================================================
## value, startValue, endValue, minRange, maxRange

When passing in value, startValue, and endValue, please make sure it is between minRange and maxRange.

## step

When passing in step, please try to ensure that (maxRange - minRange) / step is an integer, and consider the accuracy of each step. The step size is too small may cause the slider unable to slide to the required value quickly, thus affecting the user experience.

## Layout

The Slider component does not set external margins, please set it yourself when laying out the page.

## Snippet

When passing in Snippet, the area representing the progress of the Slider will render using Snippet, refer to the example.



================================================
FILE: docs/mds/components/slider/version.md
================================================
## 0.4.7

- [!tag|O|0|]优化滑动动画效果。关联 [PR](https://github.com/any-tdf/stdf/pull/26)。[!contribute|mrlovables|]



================================================
FILE: docs/mds/components/slider/version_en.md
================================================
## 0.4.7

- [!tag|O|0|] Optimize the sliding animation effect. Associated [PR](https://github.com/any-tdf/stdf/pull/26). [!contribute|mrlovables|]



================================================
FILE: docs/mds/components/stepper/api.md
================================================
## Stepper Props

| 名称            | 类型                                                            | 默认值  | 必传 | 说明                               |
| --------------- | --------------------------------------------------------------- | ------- | ---- | ---------------------------------- |
| value           | `number`                                                        | `10`    | N    | 当前值。                           |
| min             | `number`                                                        | `0`     | N    | 最小值。                           |
| max             | `number`                                                        | `100`   | N    | 最大值。                           |
| step            | `number`                                                        | `1`     | N    | 步长。                             |
| vertical        | `boolean`                                                       | `false` | N    | 是否纵向。                         |
| numberHighlight | `boolean`                                                       | `false` | N    | 是否强调数字区域。                 |
| theme           | `boolean`                                                       | `true`  | N    | 强调区域是否是主题色。             |
| radius          | `'none'\|'sm'\|'xl'\|'full'`                                    | `'sm'`  | N    | 圆角风格。                         |
| decimal         | `number`                                                        | `0`     | N    | 对内部显示数字保留小数位数。       |
| async           | `boolean`                                                       | `false` | N    | 是否异步状态。                     |
| asyncLoading    | `boolean`                                                       | `false` | N    | 异步状态时，是否显示内部 Loading。 |
| loading         | [`Loading`](https://stdf.design/components?nav=loading&tab=1) | `{}`    | N    | 异步状态时，Loading 参数。         |
| padding         | `boolean`                                                       | `true`  | N    | 外部有无 padding。                 |
| injClassOut     | `string`                                                        | `''`    | N    | 外部注入的类。                     |
| injClassBtn     | `string`                                                        | `''`    | N    | 按钮区域注入的类。                 |
| injClassNum     | `string`                                                        | `''`    | N    | 数字区域注入的类。                 |

## Stepper Events

| 名称       | 类型                | 参数           | 描述             |
| ---------- | ------------------- | -------------- | ---------------- |
| onchange   | `{ value: number }` | value - 当前值 | 当前值。         |
| ondecrease | `() => void`        | -              | 点击减少时触发。 |
| onincrease | `() => void`        | -              | 点击增加时触发。 |



================================================
FILE: docs/mds/components/stepper/api_en.md
================================================
## Stepper Props

| Name            | Type                                                            | Default | Required | Description                                        |
| --------------- | --------------------------------------------------------------- | ------- | -------- | -------------------------------------------------- |
| value           | `number`                                                        | `10`    | N        | Current value.                                     |
| min             | `number`                                                        | `0`     | N        | Minimum value.                                     |
| max             | `number`                                                        | `100`   | N        | Maximum value.                                     |
| step            | `number`                                                        | `1`     | N        | Step increment.                                    |
| vertical        | `boolean`                                                       | `false` | N        | Whether to display vertically.                     |
| numberHighlight | `boolean`                                                       | `false` | N        | Whether to highlight the number area.              |
| theme           | `boolean`                                                       | `true`  | N        | Whether the highlighted area uses the theme color. |
| radius          | `'none'\|'sm'\|'xl'\|'full'`                                    | `'sm'`  | N        | Border radius style.                               |
| decimal         | `number`                                                        | `0`     | N        | Number of decimal places for displayed value.      |
| async           | `boolean`                                                       | `false` | N        | Whether in async state.                            |
| asyncLoading    | `boolean`                                                       | `false` | N        | Whether to show internal Loading in async state.   |
| loading         | [`Loading`](https://stdf.design/components?nav=loading&tab=1) | `{}`    | N        | Loading parameters in async state.                 |
| padding         | `boolean`                                                       | `true`  | N        | Whether to have external padding.                  |
| injClassOut     | `string`                                                        | `''`    | N        | Injected class for the outer container.            |
| injClassBtn     | `string`                                                        | `''`    | N        | Injected class for the button area.                |
| injClassNum     | `string`                                                        | `''`    | N        | Injected class for the number area.                |

## Stepper Events

| Name       | Type                | Parameters            | Description                                |
| ---------- | ------------------- | --------------------- | ------------------------------------------ |
| onchange   | `{ value: number }` | value - current value | Triggered when the value changes.          |
| ondecrease | `() => void`        | -                     | Triggered when decrease button is clicked. |
| onincrease | `() => void`        | -                     | Triggered when increase button is clicked. |



================================================
FILE: docs/mds/components/stepper/FAQ.md
================================================



================================================
FILE: docs/mds/components/stepper/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/stepper/guide.md
================================================
> Stepper 使用了图标 ri-subtract-line、ri-add-line，请确保项目的 symbol.svg 文件中包含这些图标。详细信息请参考 [STDF-指南 - 图标](https://stdf.design/guide/icon)。

## 使用场景

Stepper 组件一般用于需要对数据进行逐步增减操作的场景，比如商品数量选择、积分加减、进度条等，如果数据量调整较大，建议使用 NumKeyboard 或 Input 组件。

## 异步状态

Stepper 组件支持异步状态，一般用于与服务端交互过程中更加合理地显示 Stepper 的值。通过设置 async 属性开启，此时可通过 asyncLoading 属性设置内部是否显示 Loading 状态，当然也可以自由设置 Loading 的显示位置和方式，请参考示例。

异步状态时为防止用户误触，增减按钮将会自动禁用，直到异步状态结束。

## CSS 注入

通过 injClass 参数可以分别向组件的外部、增减按钮、数字区域注入 CSS 名称（不仅限于 Tailwind CSS），这将使组件样式有更多自定义可能性，示例中通过注入实现了自定义不同位置的样式。

若注入的 class 没生效，请在注入的 class 名称前添加“!” ，可参考 [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier)。



================================================
FILE: docs/mds/components/stepper/guide_en.md
================================================
> Stepper uses the icon ri-subtract-line, ri-add-line, please ensure that the symbol.svg file in your project includes these icons. For details, please refer to [STDF-Guide-Icon](https://stdf.design/guide/icon).

## Usage scenarios

The Stepper component is generally used in scenarios where data needs to be incrementally increased or decreased, such as selecting the quantity of goods, adding or subtracting points, progress bars, etc. If there are significant adjustments to the data volume, it is recommended to use the NumKeyboard or Input components.

## Async State

The Stepper component supports asynchronous state, generally used to display the Stepper's value more reasonably during interactions with the server. It can be enabled by setting the async property. At this time, you can use the asyncLoading property to set whether to display the Loading state internally. Of course, you can also freely set the display position and method of Loading. Please refer to the example.

To prevent accidental user touches during the asynchronous state, the increase and decrease buttons will be automatically disabled until the asynchronous state ends.

## CSS Injection

The injClass parameter allows you to inject CSS class names (not limited to Tailwind CSS) into different parts of the component: the outer container, the increase/decrease buttons, and the number area. This provides more possibilities for customizing the component's style. In the example, custom styles for different positions are implemented through injection.

If the injected class doesn't take effect, try adding "!" before the class name. You can refer to [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier) for more information.



================================================
FILE: docs/mds/components/stepper/version.md
================================================



================================================
FILE: docs/mds/components/stepper/version_en.md
================================================



================================================
FILE: docs/mds/components/steps/api.md
================================================
## Steps Props

| 名称      | 类型                         | 默认值  | 必传 | 说明                                        |
| --------- | ---------------------------- | ------- | ---- | ------------------------------------------- |
| steps     | `StepsItem[]`                | `[]`    | Y    | step Props 或 finishStep Props 组成的数组。 |
| current   | `number`                     | `1`     | N    | 当前进行的步骤序号。                        |
| radius    | `'none'\|'sm'\|'xl'\|'full'` | `'sm'`  | N    | 圆角风格。                                  |
| barBorder | `boolean`                    | `true`  | N    | 图标是否带边框。                            |
| vertical  | `boolean`                    | `false` | N    | 是否纵向布局。                              |

## StepsItem Props

| 名称       | 类型              | 默认值 | 必传 | 说明                                                 |
| ---------- | ----------------- | ------ | ---- | ---------------------------------------------------- |
| step       | `StepsStep`       | `{}`   | Y    | 步骤参数。                                           |
| finishStep | `StepsFinishStep` | `{}`   | N    | 已完成步骤参数。                                     |
| height     | `number`          | `0`    | N    | 步骤高度，用于纵向布局，一般不设置，由组件自动计算。 |

## step Props && StepsFinishStep Props

| 名称         | 类型                                                          | 默认值 | 必传 | 说明                         |
| ------------ | ------------------------------------------------------------- | ------ | ---- | ---------------------------- |
| title        | `string`                                                      | `''`   | Y    | 步骤标题。                   |
| bar          | `StepsStepBarIcon \| StepsStepBarImage \| StepsStepBarString` | `{}`   | N    | 步骤区域内容。               |
| desc         | `string`                                                      | `''`   | N    | 步骤描述内容。               |
| injComponent | `Component`                                                   | -      | N    | 向步骤区域注入 Svelte 组件。 |

## StepsStepBarIcon Props

| 名称    | 类型                                                      | 默认值 | 必传 | 说明                       |
| ------- | --------------------------------------------------------- | ------ | ---- | -------------------------- |
| type    | `'icon'`                                                  | `{}`   | Y    | 步骤区域内容为图标时使用。 |
| content | [`Icon`](https://stdf.design/components?nav=icon&tab=1) | `-`    | Y    | 图标参数。                 |

## StepsStepBarImage Props

| 名称    | 类型      | 默认值 | 必传 | 说明                       |
| ------- | --------- | ------ | ---- | -------------------------- |
| type    | `'image'` | `{}`   | Y    | 步骤区域内容为图片时使用。 |
| content | `string`  | `-`    | Y    | 图片路径。                 |

## StepsStepBarString Props

| 名称    | 类型       | 默认值 | 必传 | 说明                         |
| ------- | ---------- | ------ | ---- | ---------------------------- |
| type    | `'string'` | `{}`   | Y    | 步骤区域内容为字符串时使用。 |
| content | `string`   | `-`    | Y    | 字符串内容。                 |



================================================
FILE: docs/mds/components/steps/api_en.md
================================================
## Steps Props

| Name      | Type                         | Default | Required | Description                                       |
| --------- | ---------------------------- | ------- | -------- | ------------------------------------------------- |
| steps     | `StepsItem[]`                | `[]`    | Y        | Array composed of step Props or finishStep Props. |
| current   | `number`                     | `1`     | N        | Current step number.                              |
| radius    | `'none'\|'sm'\|'xl'\|'full'` | `'sm'`  | N        | Border radius style.                              |
| barBorder | `boolean`                    | `true`  | N        | Whether the icon has a border.                    |
| vertical  | `boolean`                    | `false` | N        | Whether to use vertical layout.                   |

## StepsItem Props

| Name       | Type              | Default | Required | Description                                                                |
| ---------- | ----------------- | ------- | -------- | -------------------------------------------------------------------------- |
| step       | `StepsStep`       | `{}`    | Y        | Step parameters.                                                           |
| finishStep | `StepsFinishStep` | `{}`    | N        | Completed step parameters.                                                 |
| height     | `number`          | `0`     | N        | Step height for vertical layout, usually auto-calculated by the component. |

## step Props && StepsFinishStep Props

| Name         | Type                                                          | Default | Required | Description                             |
| ------------ | ------------------------------------------------------------- | ------- | -------- | --------------------------------------- |
| title        | `string`                                                      | `''`    | Y        | Step title.                             |
| bar          | `StepsStepBarIcon \| StepsStepBarImage \| StepsStepBarString` | `{}`    | N        | Step area content.                      |
| desc         | `string`                                                      | `''`    | N        | Step description content.               |
| injComponent | `Component`                                                   | -       | N        | Inject Svelte component into step area. |

## StepsStepBarIcon Props

| Name    | Type                                                      | Default | Required | Description                             |
| ------- | --------------------------------------------------------- | ------- | -------- | --------------------------------------- |
| type    | `'icon'`                                                  | `{}`    | Y        | Used when step area content is an icon. |
| content | [`Icon`](https://stdf.design/components?nav=icon&tab=1) | `-`     | Y        | Icon parameters.                        |

## StepsStepBarImage Props

| Name    | Type      | Default | Required | Description                              |
| ------- | --------- | ------- | -------- | ---------------------------------------- |
| type    | `'image'` | `{}`    | Y        | Used when step area content is an image. |
| content | `string`  | `-`     | Y        | Image path.                              |

## StepsStepBarString Props

| Name    | Type       | Default | Required | Description                              |
| ------- | ---------- | ------- | -------- | ---------------------------------------- |
| type    | `'string'` | `{}`    | Y        | Used when step area content is a string. |
| content | `string`   | `-`     | Y        | String content.                          |



================================================
FILE: docs/mds/components/steps/FAQ.md
================================================



================================================
FILE: docs/mds/components/steps/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/steps/guide.md
================================================
## 说明

Steps 默认为横向布局，由于移动端横向显示内容有限，横向布局建议只用作简单使用。当步骤较多、标题较长或显示内容较多时建议使用纵向布局。

> 横向布局只显示标题与步骤栏区域，即使传入了 desc 等其他参数也不会显示。

## current

从 1 开始的实际步骤序号，组件内部对应 steps 的索引值 +1。

## finishStep

每一步的 Props 支持传入 finishStep，格式与 step 相同，用于一些场景下更准确细致地表达已经完成的步骤，请参考示例。

## 步骤栏区域

步骤栏区域 bar 可以传入三种情况，type 为 `'string'` 将直接显示字符，建议单个字符；type 为 `'image'` 将显示图片，可以传入图片的相对路径或绝对路径，组件内部将其转换为 img 标签的 src 属性；type 为 `'icon'` 将显示图标，根据传入的 [Icon Props](https://stdf.design/components?nav=icon&tab=1) 进行渲染。

## injComponent

step 和 finishStep 支持通过 injComponent 注入 Svelte 组件，Steps 内部将其渲染至步骤区域底部，请参考示例。

将 Svelte 组件作为传入参数并进行渲染的实现，使用到了 Svelte 的 `{@const ...}` 语法，请参考 [{@const ...}](https://svelte.dev/docs/svelte/@const)。

## 补充

Tip：表示时间线的业务场景也是可以使用 Steps 组件。



================================================
FILE: docs/mds/components/steps/guide_en.md
================================================
## Description

Steps defaults to horizontal layout. Due to limited horizontal display content on mobile devices, horizontal layout is recommended only for simple use. When there are multiple steps, long titles, or more content to display, vertical layout is recommended.

> Horizontal layout only displays the title and step bar area, even if other parameters like desc are passed in, they will not be displayed.

## current

The actual step number starting from 1, which corresponds to the steps array index + 1 internally in the component.

## finishStep

Each step's Props supports passing in finishStep, which has the same format as step, used to more accurately and precisely express completed steps in some scenarios. Please refer to the examples.

## Step Bar Area

The step bar area can accept three types of content: when type is `'string'`, it will directly display characters (single character recommended); when type is `'image'`, it will display an image, accepting relative or absolute image paths which will be converted to img tag src attribute internally; when type is `'icon'`, it will display an icon rendered according to the passed [Icon Props](https://stdf.design/components?nav=icon&tab=1).

## injComponent

step and finishStep support injecting Svelte components via injComponent, which Steps will render at the bottom of the step area. Please refer to the examples.

The implementation of passing and rendering Svelte components as parameters uses Svelte's `{@const ...}` syntax, please refer to [{@const ...}](https://svelte.dev/docs/svelte/@const).

## Additional Note

Tip: The Steps component can also be used for timeline business scenarios.



================================================
FILE: docs/mds/components/steps/version.md
================================================



================================================
FILE: docs/mds/components/steps/version_en.md
================================================



================================================
FILE: docs/mds/components/swiper/api.md
================================================
## Swiper Props

| 名称                | 类型                                             | 默认值        | 必传 | 说明                         |
| ------------------- | ------------------------------------------------ | ------------- | ---- | ---------------------------- |
| data                | `(SwiperImg\|SwiperComponent)[]`                 | `[]`          | Y    | 数据。                       |
| interval            | `number`                                         | `4`           | N    | 间隔时间（秒）。             |
| duration            | `number`                                         | `1000`        | N    | 过渡时间（毫秒）。           |
| autoplay            | `boolean`                                        | `true`        | N    | 是否自动播放。               |
| lazyplay            | `boolean`                                        | `true`        | N    | 是否懒轮播。                 |
| initActive          | `number`                                         | `0`           | N    | 初始激活索引。               |
| indicatePosition    | `'inner'\|'out'\|null`                           | `'inner'`     | N    | 指示器位置。                 |
| indicateAlign       | `'center'\|'right'\|'left'`                      | `'center'`    | N    | 指示器对齐方式。             |
| indicateStyle       | `'point'\|'line'\|'pointLine'\|'longLine'`       | `'pointLine'` | N    | 指示器样式。                 |
| indicateRadius      | `boolean`                                        | `true`        | N    | 指示器是否圆角。             |
| indicateInjClass    | `string`                                         | `''`          | N    | 指示器注入 Class。           |
| indicateColor       | `string`                                         | `''`          | N    | 指示器颜色。                 |
| indicateActiveColor | `string`                                         | `''`          | N    | 指示器激活颜色。             |
| aspectRatio         | `[number,number]`                                | `[16, 9]`     | N    | 容器宽高比。                 |
| containerWidth      | `number`                                         | `0`           | N    | 容器宽度。                   |
| px                  | `'0'\|'1'\|'2'\|'4'\|'6'\|'8'\|'12'\|'16'\|'24'` | `'0'`         | N    | 容器横向内边距。             |
| py                  | `'0'\|'1'\|'2'\|'4'\|'6'\|'8'\|'12'`             | `'0'`         | N    | 容器纵向内边距。             |
| translateX          | `number`                                         | `0`           | N    | 未激活容器 X 方向偏移值。    |
| translateZ          | `number`                                         | `0`           | N    | 未激活容器 Z 方向偏移值。    |
| rotateX             | `number`                                         | `0`           | N    | 未激活容器 X 轴旋转值。      |
| rotateY             | `number`                                         | `0`           | N    | 未激活容器 Y 轴旋转值。      |
| rotateZ             | `number`                                         | `0`           | N    | 未激活容器 Z 轴旋转值。      |
| activeInjClass      | `string`                                         | `''`          | N    | 激活容器注入 Class。         |
| notActiveInjClass   | `string`                                         | `''`          | N    | 未激活容器注入 Class。       |
| radius              | `'none'\|'sm'\|'xl'\|'2xl'\|'full'`              | `'none'`      | N    | 容器内部区域圆角。           |
| triggerLong         | `number`                                         | `30`          | N    | 始终触发的滑动距离百分比。   |
| notTriggerLong      | `number`                                         | `10`          | N    | 始终不触发的滑动距离百分比。 |
| triggerSpeed        | `number`                                         | `0.5`         | N    | 触发的滑动速度系数。         |
| innerInjClass       | `string`                                         | `''`          | N    | 容器内部元素注入 Class。     |

## Swiper Events

| 名称     | 类型                        | 参数                 | 描述                     |
| -------- | --------------------------- | -------------------- | ------------------------ |
| onclick  | `(current: number) => void` | current - 点击索引值 | 点击容器内图片时触发。   |
| onchange | `(current: number) => void` | current - 当前索引值 | 当前激活容器变化时触发。 |

## SwiperImg

```javascript
type SwiperImg = { type: 'img', url: string };
```

## SwiperComponent

```javascript
type SwiperComponent = { type: 'component', component: Component };
```



================================================
FILE: docs/mds/components/swiper/api_en.md
================================================
## Swiper Props

| Name                | Type                                             | Default       | Required | Description                                     |
| ------------------- | ------------------------------------------------ | ------------- | -------- | ----------------------------------------------- |
| data                | `(SwiperImg\|SwiperComponent)[]`                 | `[]`          | Y        | Data.                                           |
| interval            | `number`                                         | `4`           | N        | Interval time (seconds).                        |
| duration            | `number`                                         | `1000`        | N        | Transition duration (milliseconds).             |
| autoplay            | `boolean`                                        | `true`        | N        | Whether to autoplay.                            |
| lazyplay            | `boolean`                                        | `true`        | N        | Whether to lazy load.                           |
| initActive          | `number`                                         | `0`           | N        | Initial active index.                           |
| indicatePosition    | `'inner'\|'out'\|null`                           | `'inner'`     | N        | Indicator position.                             |
| indicateAlign       | `'center'\|'right'\|'left'`                      | `'center'`    | N        | Indicator alignment.                            |
| indicateStyle       | `'point'\|'line'\|'pointLine'\|'longLine'`       | `'pointLine'` | N        | Indicator style.                                |
| indicateRadius      | `boolean`                                        | `true`        | N        | Whether indicator has rounded corners.          |
| indicateInjClass    | `string`                                         | `''`          | N        | Indicator injected class.                       |
| indicateColor       | `string`                                         | `''`          | N        | Indicator color.                                |
| indicateActiveColor | `string`                                         | `''`          | N        | Active indicator color.                         |
| aspectRatio         | `[number,number]`                                | `[16, 9]`     | N        | Container aspect ratio.                         |
| containerWidth      | `number`                                         | `0`           | N        | Container width.                                |
| px                  | `'0'\|'1'\|'2'\|'4'\|'6'\|'8'\|'12'\|'16'\|'24'` | `'0'`         | N        | Container horizontal padding.                   |
| py                  | `'0'\|'1'\|'2'\|'4'\|'6'\|'8'\|'12'`             | `'0'`         | N        | Container vertical padding.                     |
| translateX          | `number`                                         | `0`           | N        | Inactive container X-axis translation.          |
| translateZ          | `number`                                         | `0`           | N        | Inactive container Z-axis translation.          |
| rotateX             | `number`                                         | `0`           | N        | Inactive container X-axis rotation.             |
| rotateY             | `number`                                         | `0`           | N        | Inactive container Y-axis rotation.             |
| rotateZ             | `number`                                         | `0`           | N        | Inactive container Z-axis rotation.             |
| activeInjClass      | `string`                                         | `''`          | N        | Active container injected class.                |
| notActiveInjClass   | `string`                                         | `''`          | N        | Inactive container injected class.              |
| radius              | `'none'\|'sm'\|'xl'\|'2xl'\|'full'`              | `'none'`      | N        | Container inner area border radius.             |
| triggerLong         | `number`                                         | `30`          | N        | Slide distance percentage that always triggers. |
| notTriggerLong      | `number`                                         | `10`          | N        | Slide distance percentage that never triggers.  |
| triggerSpeed        | `number`                                         | `0.5`         | N        | Slide speed coefficient that triggers.          |
| innerInjClass       | `string`                                         | `''`          | N        | Container inner element injected class.         |

## Swiper Events

| Name     | Type                        | Parameters              | Description                              |
| -------- | --------------------------- | ----------------------- | ---------------------------------------- |
| onclick  | `(current: number) => void` | current - clicked index | Triggered when clicking container image. |
| onchange | `(current: number) => void` | current - current index | Triggered when active container changes. |

## SwiperImg

```javascript
type SwiperImg = { type: 'img', url: string };
```

## SwiperComponent

```javascript
type SwiperComponent = { type: 'component', component: Component };
```



================================================
FILE: docs/mds/components/swiper/FAQ.md
================================================
## 问：为何 Swiper 左右滑动过快时会感到卡顿？

答：最开始是考虑直接通过使容器左右滚动和滚动对齐来实现切换效果（自带滚动惯性），遗憾的是目前 web 还不支持对平滑滚动的过渡时间做控制，这就失去了过渡效果的可配置。所以目前采用的方案是监听手指滑动的距离来实现滑动切换，同时通过 triggerLong、notTriggerLong 和 triggerSpeed 可对触发条件做自定义配置。当手指滑动结束离开屏幕时即表示一次滑动结束，Swiper 会结合滑动距离与滑动速度判断本次滑动是否触发切换。



================================================
FILE: docs/mds/components/swiper/FAQ_en.md
================================================
## Q: Why does Swiper lag when sliding too quickly left and right?

A: Initially, we considered using container scrolling and alignment to achieve the switching effect (with built-in scroll inertia). Unfortunately, web browsers currently do not support controlling the transition time for smooth scrolling, which makes the configuration of transition effects impossible. Therefore, the current solution is to listen to the distance of finger sliding to achieve slide switching, and custom configure the triggering conditions using triggerLong, notTriggerLong, and triggerSpeed. When the finger finishes sliding and leaves the screen, it indicates the end of a slide. Swiper will determine whether to trigger the slide switch based on the sliding distance and sliding speed.



================================================
FILE: docs/mds/components/swiper/guide.md
================================================
## data

传入的数据 data 内部的 type 支持 `'img'` 和 `'component'`，其中 `img` 类型需要传入图片 url，`component` 类型时传入单文件组件，Swiper
内部将会根据 type 渲染对应内容。

## interval && duration

为了书写方便，注意间隔时间 interval 以秒为单位，过渡时间 duration 以毫秒为单位，同时需要注意传入的过渡时间必须小于间隔时间。

## indicateStyle

此参数配置指示器的样式，当 `indicateStyle` 为 `longLine` 时，激活的指示器会在 Swiper 停留时间内表示间隔进度，请参考示例。

## indicateInjClass

此参数可以对指示器 indicate 区域注入 CSS 名称（不仅限于 Tailwind CSS），比如示例中去除默认自带透明度的渐变色背景。

若注入的 class 没生效，请在注入的 class 名称前添加“!”
，可参考 [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier)。

## aspectRatio && containerWidth && px&& py

containerWidth 若不传或为 0，Swiper 内部默认使用页面宽度作为此组件区域宽度。而此区域高度将通过 containerWidth 与
aspectRatio 计算出来。

注意，aspectRatio 仅仅决定容器的宽高比，所以只有当 px 和 py 一致时，每个容器内部显示区域宽高比才会与 aspectRatio 一致。

## 未激活容器偏移与旋转

通过对 X、Z 两个方向上的偏移值和 X、Y、Z 三个旋转轴旋转角度的设置，可以让未激活的容器在对应轴进行偏移与旋转，从而实现一些特殊的切换过渡效果，请参考示例。

注意，偏移值以像素（px）为单位，而旋转角度以度（deg）为单位。

## activeInjClass && notActiveInjClass

通过对激活和未激活的容器注入 Class，可以让不同状态的容器有不同的样式，

## radius && innerInjClass

这是对容器内部区域的圆角设置与注入 Class，请参考示例。

## onclick 事件

点击事件仅仅在传入图片时生效，传入组件时事件由传入的组件内部决定。

## 滑动事件

当手指或其他触摸设备在 Swiper 容器内滑动结束时，Swiper 会结合滑动距离与滑动速度判断本次滑动是否触发切换，若触发则会根据滑动方向切换到上一个或下一个容器。

- 当滑动距离小于某个阈值时，始终不触发切换。
- 当滑动距离大于某个阈值时，始终触发切换。
- 当滑动距离介于两个阈值之间时，会根据滑动速度判断是否触发切换，速度大于某个速度系数时会触发切换。

上述三种情况的阈值和速度系数可以通过 triggerLong、notTriggerLong 和 triggerSpeed 参数进行自定义。其中 triggerLong 和 notTriggerLong 为百分比，表示滑动距离占容器宽度的百分比；triggerSpeed 为 0-1 之间的小数，表示滑动速度系数。

## lazyplay

Swiper 自动轮播时有一系列过渡动画，当页面同时有大量过渡效果时，考虑到设备性能与动画帧率等问题，Swiper 默认会开启懒轮播，即
Swiper 组件**不在页面可视范围内时会暂停自动轮播**，当然你也可以单独设置。

下面两张图展示了极端情况下，同一个页面存在 30+ Swiper 同时轮播时，桌面端浏览器处理大量过渡动画时的性能监视图对比。

- 未开启懒轮播，同时会有 30+ 组过渡动画在进行时的性能监视图。
  <img src="lazyplay_no.png" style="width: 100%;" alt="lazyplay_no" title="未开启懒轮播性能监视图">

- 已开启懒轮播，同时只有 3-4 组过渡动画在进行时的性能监视图。
  <img src="lazyplay_yes.png" style="width: 100%;" alt="lazyplay_yes" title="已开启懒轮播性能监视图">



================================================
FILE: docs/mds/components/swiper/guide_en.md
================================================
## data

The type field in the input data supports 'img' and 'component'. For 'img' type, you need to provide an image URL. For 'component' type, you need to provide a single-file component. The Swiper will render corresponding content based on the type.

## interval && duration

For convenience, note that the interval time is in seconds while the transition duration is in milliseconds. Also note that the transition duration must be less than the interval time.

## indicateStyle

This parameter configures the indicator style. When `indicateStyle` is set to `longLine`, the active indicator will show the interval progress during the Swiper's dwell time. Please refer to the examples.

## indicateInjClass

This parameter allows you to inject CSS class names (not limited to Tailwind CSS) into the indicator area. For example, you can remove the default gradient background with transparency as shown in the examples.

If the injected class doesn't take effect, add "!" before the class name. Please refer to [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier).

## aspectRatio && containerWidth && px && py

If containerWidth is not provided or set to 0, the Swiper will use the page width as the component area width by default. The height of this area will be calculated using containerWidth and aspectRatio.

Note that aspectRatio only determines the container's aspect ratio. The aspect ratio of the inner display area will match aspectRatio only when px and py are equal.

## Inactive Container Offset and Rotation

By setting offset values in X and Z directions and rotation angles around X, Y, and Z axes, inactive containers can be offset and rotated along corresponding axes to achieve special transition effects. Please refer to the examples.

Note that offset values are in pixels (px) while rotation angles are in degrees (deg).

## activeInjClass && notActiveInjClass

By injecting classes into active and inactive containers, you can apply different styles to containers in different states.

## radius && innerInjClass

These parameters control the border radius and class injection for the inner container area. Please refer to the examples.

## onclick Event

Click events only work when images are provided. For components, events are determined by the provided component itself.

## Swipe Events

When a finger or other touch device finishes sliding within the Swiper container, the Swiper will determine whether to trigger a switch based on the sliding distance and velocity. If triggered, it will switch to the previous or next container according to the sliding direction.

- When the sliding distance is less than a certain threshold, switching will never be triggered.
- When the sliding distance is greater than a certain threshold, switching will always be triggered.
- When the sliding distance is between these two thresholds, switching will be determined by the sliding velocity - if the velocity exceeds a certain coefficient, switching will be triggered.

The thresholds and velocity coefficient for these three scenarios can be customized through triggerLong, notTriggerLong, and triggerSpeed parameters. Both triggerLong and notTriggerLong are percentages representing the sliding distance as a percentage of container width; triggerSpeed is a decimal between 0-1 representing the velocity coefficient.

## lazyplay

When Swiper auto-plays, there are a series of transition animations. Considering device performance and animation frame rate issues when there are many simultaneous transitions on a page, Swiper enables lazy playback by default - meaning the Swiper component **will pause auto-play when not in the viewport**. Of course, you can configure this individually.

The following two images show performance monitoring comparisons in an extreme case where 30+ Swipers are playing simultaneously on the same page in a desktop browser.

- Performance monitor when lazy playback is disabled, showing 30+ sets of transitions occurring simultaneously.
  <img src="lazyplay_no.png" style="width: 100%;" alt="lazyplay_no" title="Performance monitor with lazy playback disabled">

- Performance monitor when lazy playback is enabled, showing only 3-4 sets of transitions occurring simultaneously.
  <img src="lazyplay_yes.png" style="width: 100%;" alt="lazyplay_yes" title="Performance monitor with lazy playback enabled">



================================================
FILE: docs/mds/components/swiper/version.md
================================================
## 0.2.0

- [!tag|A|0|] 支持通过 triggerLong、notTriggerLong 和 triggerSpeed 三个 API 自定义滑动触发条件。



================================================
FILE: docs/mds/components/swiper/version_en.md
================================================
## 0.2.0

- [!tag|A|0|] Supports customizing slide triggering conditions through the triggerLong, notTriggerLong, and triggerSpeed APIs.



================================================
FILE: docs/mds/components/switch/api.md
================================================
## Switch Props

| 名称     | 类型                                                            | 默认值     | 必传 | 说明                                            |
| -------- | --------------------------------------------------------------- | ---------- | ---- | ----------------------------------------------- |
| active   | `boolean`                                                       | `false`    | N    | 开关状态。                                      |
| radius   | `'none'\|'middle'\|'full'`                                      | `'middle'` | N    | 圆角风格。                                      |
| inside   | `'state'\|'loading'\|[string,string]\|null`                     | `null`     | N    | 开关内部内容。                                  |
| injClass | `string`                                                        | `''`       | N    | 注入 CSS 名称。                                 |
| disabled | `boolean`                                                       | `false`    | N    | 是否禁用。                                      |
| async    | `boolean`                                                       | `false`    | N    | 是否异步。                                      |
| loading  | [`Loading`](https://stdf.design/components?nav=loading&tab=1) | `{}`       | N    | 加载组件参数，仅 inside 为 `'loading'` 时生效。 |

## Switch Events

| 名称     | 类型                        | 参数                    | 描述                 |
| -------- | --------------------------- | ----------------------- | -------------------- |
| onclick  | `() => void`                | -                       | 点击触发。           |
| onchange | `(active: boolean) => void` | active - 当前开关状态。 | 开关状态变化时触发。 |

## Switch Snippets

| 名称       | 类型                                                                | 参数 | 说明                       |
| ---------- | ------------------------------------------------------------------- | ---- | -------------------------- |
| trueChild  | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 状态为开启时开关内部内容。 |
| falseChild | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 状态为关闭时开关内部内容。 |



================================================
FILE: docs/mds/components/switch/api_en.md
================================================
## Switch Props

| Name     | Type                                                            | Default    | Required | Description                                                              |
| -------- | --------------------------------------------------------------- | ---------- | -------- | ------------------------------------------------------------------------ |
| active   | `boolean`                                                       | `false`    | N        | Switch state.                                                            |
| radius   | `'none'\|'middle'\|'full'`                                      | `'middle'` | N        | Border radius style.                                                     |
| inside   | `'state'\|'loading'\|[string,string]\|null`                     | `null`     | N        | Switch inner content.                                                    |
| injClass | `string`                                                        | `''`       | N        | Injected CSS class name.                                                 |
| disabled | `boolean`                                                       | `false`    | N        | Whether the switch is disabled.                                          |
| async    | `boolean`                                                       | `false`    | N        | Whether the switch is asynchronous.                                      |
| loading  | [`Loading`](https://stdf.design/components?nav=loading&tab=1) | `{}`       | N        | Loading component parameters, only effective when inside is `'loading'`. |

## Switch Events

| Name     | Type                        | Parameters                     | Description                              |
| -------- | --------------------------- | ------------------------------ | ---------------------------------------- |
| onclick  | `() => void`                | -                              | Triggered when clicked.                  |
| onchange | `(active: boolean) => void` | active - Current switch state. | Triggered when the switch state changes. |

## Switch Snippets

| Name       | Type                                                                | Parameters | Description                                 |
| ---------- | ------------------------------------------------------------------- | ---------- | ------------------------------------------- |
| trueChild  | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Switch inner content when the state is on.  |
| falseChild | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Switch inner content when the state is off. |



================================================
FILE: docs/mds/components/switch/FAQ.md
================================================



================================================
FILE: docs/mds/components/switch/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/switch/guide.md
================================================
## 使用场景

移动端的 Switch 组件一般来说都是搭配在 Cell 组件内使用，Cell 组件的 right 参数支持传入 Switch Props，请参考 Cell API。

当然，单独使用也是可以的。

## injClass

通过 injClass 参数可以向组件内部最外层元素注入 CSS 名称（不仅限于 Tailwind CSS），这将使组件样式有更多自定义可能性。因为 CSS 注入于最后，此时最外层元素若已有同属性 CSS 将会以 injClass 为准，这也是通过 injClass 实现自定义开关颜色的原因。

## inside & Snippet

inside 参数决定了开关内部显示内容，默认值是空字符，不显示任何内容。若传入字符 `'state’` 则会以竖线和圆形表示开关状态；若传入两项字符组成的数组，第一项和第二项将分别显示关闭与开启状态时的内部文字，建议传入单个文字；若传入字符 `'loading'` 则会以 Loading 图标渲染，且支持传入 Loading Props；若传入 falseChild 和 trueChild 则会以传入内容分别渲染开启与关闭时开关内部内容，请参考示例。

## 特别注意

在 Cell 组件内使用时，Switch 的 active 由 Cell Props 的 switchActive 决定，**请不要在 switch 内部再传入 active**。



================================================
FILE: docs/mds/components/switch/guide_en.md
================================================
## Usage Scenarios

The Switch component for mobile devices is generally used in conjunction with the Cell component. The right parameter of the Cell component supports passing Switch Props. Please refer to the Cell API for more details.

Of course, it can also be used independently.

## injClass

The injClass parameter allows you to inject CSS class names (not limited to Tailwind CSS) into the outermost element of the component, providing more customization possibilities for the component's style. Since CSS injection occurs at the end, if the outermost element already has CSS properties with the same attributes, the injClass will take precedence. This is also the reason why injClass can be used to customize the switch color.

## inside & Snippet

The inside parameter determines the content displayed inside the switch. The default value is an empty string, which displays nothing. If the string 'state' is passed, it will represent the switch state with a vertical line and a circle. If an array of two strings is passed, the first and second items will display the internal text for the off and on states respectively; it's recommended to pass a single character. If the string 'loading' is passed, it will render with a Loading icon and supports passing Loading Props. If falseChild and trueChild are passed, they will render the internal content of the switch when it's off and on respectively. Please refer to the examples.

## Special Note

When used within the Cell component, the active state of the Switch is determined by the switchActive prop of the Cell. **Please do not pass active again inside the switch.**



================================================
FILE: docs/mds/components/switch/version.md
================================================



================================================
FILE: docs/mds/components/switch/version_en.md
================================================



================================================
FILE: docs/mds/components/tabBar/api.md
================================================
## TabBar Props

| 名称              | 类型            | 默认值  | 必传 | 说明                        |
| ----------------- | --------------- | ------- | ---- | --------------------------- |
| labels            | `TabBarLabel[]` | `[]`    | Y    | 选项卡内容组。              |
| active            | `number`        | `0`     | N    | 激活的选项卡索引值。        |
| line              | `boolean`       | `false` | N    | 底部是否显示线条。          |
| lineW             | `number`        | `4`     | N    | 线条占当前 Tab 宽度的比例。 |
| love              | `boolean`       | `false` | N    | 是否开启关爱版。            |
| injClass          | `string`        | `''`    | N    | TabBar 外层注入 CSS。       |
| tabInjClass       | `string`        | `''`    | N    | 单项 Tab 注入 CSS。         |
| activeTabInjClass | `string`        | `''`    | N    | 激活的 Tab 注入 CSS。       |
| activeInjClass    | `string`        | `''`    | N    | 底部线条注入 CSS。          |

## TabBarLabel Props

| 名称       | 类型                                                      | 默认值 | 必传 | 说明               |
| ---------- | --------------------------------------------------------- | ------ | ---- | ------------------ |
| text       | `string`                                                  | `''`   | N    | 选项卡文字。       |
| icon       | [`Icon`](https://stdf.design/components?nav=icon&tab=1) | -      | N    | 选项卡图标。       |
| activeIcon | [`Icon`](https://stdf.design/components?nav=icon&tab=1) | -      | N    | 激活的选项卡图标。 |

## TabBar Events

| 名称     | 类型                       | 参数                            | 描述                 |
| -------- | -------------------------- | ------------------------------- | -------------------- |
| onchange | `(active: number) => void` | `active` - 激活的 TabBar 索引值 | 点击 TabBar 时触发。 |



================================================
FILE: docs/mds/components/tabBar/api_en.md
================================================
## TabBar Props

| Name              | Type            | Default | Required | Description                            |
| ----------------- | --------------- | ------- | -------- | -------------------------------------- |
| labels            | `TabBarLabel[]` | `[]`    | Y        | Tab content group.                     |
| active            | `number`        | `0`     | N        | Index value of active tab.             |
| line              | `boolean`       | `false` | N        | Whether to show bottom line.           |
| lineW             | `number`        | `4`     | N        | Line width ratio of current tab width. |
| love              | `boolean`       | `false` | N        | Whether to enable care version.        |
| injClass          | `string`        | `''`    | N        | Inject CSS class for TabBar wrapper.   |
| tabInjClass       | `string`        | `''`    | N        | Inject CSS class for single tab.       |
| activeTabInjClass | `string`        | `''`    | N        | Inject CSS class for active tab.       |
| activeInjClass    | `string`        | `''`    | N        | Inject CSS class for bottom line.      |

## TabBarLabel Props

| Name       | Type                                                      | Default | Required | Description      |
| ---------- | --------------------------------------------------------- | ------- | -------- | ---------------- |
| text       | `string`                                                  | `''`    | N        | Tab text.        |
| icon       | [`Icon`](https://stdf.design/components?nav=icon&tab=1) | -       | N        | Tab icon.        |
| activeIcon | [`Icon`](https://stdf.design/components?nav=icon&tab=1) | -       | N        | Active tab icon. |

## TabBar Events

| Name     | Type                       | Parameters                     | Description                       |
| -------- | -------------------------- | ------------------------------ | --------------------------------- |
| onchange | `(active: number) => void` | `active` - Active TabBar index | Triggered when TabBar is clicked. |



================================================
FILE: docs/mds/components/tabBar/FAQ.md
================================================



================================================
FILE: docs/mds/components/tabBar/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/tabBar/guide.md
================================================
## 说明

TabBar 通过绑定的 onchange 事件，传递出当前激活选项卡的索引值。

## labels

此参数决定了 TabBar 内部的选项卡内容，支持图标与文字自由搭配。数据类型为对象数组，内部对象由 text 和 icon、activeIcon 搭配组成。icon 和 activeIcon 使用 Icon 组件渲染，其中 activeIcon 表示 TabBar 激活时的 Icon。具体参数请参考 [Icon Props](https://stdf.design/components?nav=icon&tab=1)。

## 底部线条

line 为 true 时激活的 TabBar 底部会显示线条，lineW 和 activeInjClass 只会在 line 为 true 时生效。线条宽度可由 lineW 控制，lineW 的值为线条宽度占当前 Tab 宽度的比例，默认值为 4，**lineW 的值越大线条越窄**。

## CSS 注入

TabBar 结构相对复杂，为了支持更灵活的自定义样式，内部支持四个地方注入 CSS，injClass 作用于 TabBar 最外层元素；tabInjClass 作用于内部的单项 tab；activeTabInjClass 作用于当前激活的 tab；activeInjClass 作用于 TabBar 底部的线条。

若注入的 class 没生效，请在注入的 class 名称前添加“!” ，可参考 [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier)。

## 简单

相对于其他组件，TabBar 组件在应用中被使用的频率较低，一般一个应用就一个，而且一般都有针对自己品牌的专属 UI/UX 设计，复用性很低，因此 TabBar 组件在 API 设计上相对简单一些。



================================================
FILE: docs/mds/components/tabBar/guide_en.md
================================================
## Description

TabBar passes the index value of the currently active tab through the bound onchange event.

## labels

This parameter determines the content of tabs inside the TabBar, supporting free combination of icons and text. The data type is an array of objects, where each object consists of text, icon and activeIcon. The icon and activeIcon are rendered using the Icon component, where activeIcon represents the Icon when TabBar is active. For specific parameters, please refer to [Icon Props](https://stdf.design/components?nav=icon&tab=1).

## Bottom Line

When line is true, a line will be displayed at the bottom of the active TabBar. lineW and activeInjClass only take effect when line is true. The line width can be controlled by lineW, whose value represents the ratio of line width to current Tab width. The default value is 4, **the larger the lineW value, the narrower the line**.

## CSS Injection

TabBar has a relatively complex structure. To support more flexible custom styles, it supports CSS injection in four places: injClass applies to the outermost element of TabBar; tabInjClass applies to individual tabs inside; activeTabInjClass applies to the currently active tab; activeInjClass applies to the bottom line of TabBar.

If the injected class doesn't take effect, please add "!" before the injected class name. You can refer to [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier).

## Simplicity

Compared to other components, the TabBar component is used less frequently in applications, usually just one per application, and generally has brand-specific UI/UX design with low reusability. Therefore, the TabBar component's API design is relatively simple.



================================================
FILE: docs/mds/components/tabBar/version.md
================================================



================================================
FILE: docs/mds/components/tabBar/version_en.md
================================================



================================================
FILE: docs/mds/components/tabs/api.md
================================================
## Tabs Props

| 名称       | 类型                               | 默认值   | 必传 | 说明                 |
| ---------- | ---------------------------------- | -------- | ---- | -------------------- |
| tab        | `Tab`                              | `{}`     | Y    | 内部 Tab 组件。      |
| active     | `number`                           | `0`      | N    | 激活的选项卡索引值。 |
| duration   | `'fast'\|'base'\|'slow'\|'slower'` | `'base'` | N    | 过渡动画快慢。       |
| position   | `'t'\|'b'\|'l'\|'r'`               | `'t'`    | N    | 选项卡位置。         |
| transition | `boolean`                          | `true`   | N    | 是否使用过渡动画。   |

## Tabs Events

| 名称     | 类型                       | 参数                        | 描述                         |
| -------- | -------------------------- | --------------------------- | ---------------------------- |
| onchange | `(active: number) => void` | active - 激活的选项卡索引值 | 激活的选项卡发生变化时触发。 |

## Tabs Snippets

| 名称     | 类型                                                                                      | 参数                        | 说明            |
| -------- | ----------------------------------------------------------------------------------------- | --------------------------- | --------------- |
| children | [`Snippet<[{ active: number }]>`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | active - 激活的选项卡索引值 | Tabs 主体内容。 |

## Tab Props

| 名称              | 类型                                                  | 默认值   | 必传 | 说明                               |
| ----------------- | ----------------------------------------------------- | -------- | ---- | ---------------------------------- |
| labels            | `TabLabel[]`                                          | `[]`     | Y    | 选项卡内容组。                     |
| active            | `number`                                              | `0`      | N    | 激活的选项卡索引值。               |
| lineType          | `boolean`                                             | `false`  | N    | 是否使用线性风格。                 |
| radius            | `'none'\|'sm'\|'xl'\|'full'`                          | `'sm'`   | N    | 圆角风格。                         |
| mx                | `'0'\|'1'\|'2'\|'3'\|'4'\|'6'\|'8'\|'12'\|'16'\|'20'` | `'2'`    | N    | 左右间距。                         |
| duration          | `'fast'\|'base'\|'slow'\|'slower'`                    | `'base'` | N    | 过渡动画快慢。                     |
| layout            | `'h'\|'v'`                                            | `'h'`    | N    | 水平或垂直布局。                   |
| love              | `boolean`                                             | `false`  | N    | 是否开启关爱版。                   |
| injClass          | `string`                                              | `''`     | N    | Tab 外层注入 CSS。                 |
| tabInjClass       | `string`                                              | `''`     | N    | 单项 Tab 注入 CSS。                |
| activeTabInjClass | `string`                                              | `''`     | N    | 激活的 Tab 注入 CSS。              |
| activeInjClass    | `string`                                              | `''`     | N    | 指示器注入 CSS。                   |
| overflow          | `boolean`                                             | `false`  | N    | 是否开启溢出模式。                 |
| showNum           | `number`                                              | `3`      | N    | 开启溢出模式时，完整显示 Tab 数。  |
| autoScroll        | `boolean`                                             | `false`  | N    | 开启溢出模式时，是否开启自动滚动。 |

## Tab Events

| 名称       | 类型                       | 参数                          | 描述               |
| ---------- | -------------------------- | ----------------------------- | ------------------ |
| onclickTab | `(active: number) => void` | active - 激活的选项卡索引值。 | 点击选项卡时触发。 |

## TabLabel Props

| 名称 | 类型                                                      | 默认值 | 必传 | 说明       |
| ---- | --------------------------------------------------------- | ------ | ---- | ---------- |
| text | `string`                                                  | `''`   | N    | 标签文本。 |
| icon | [`Icon`](https://stdf.design/components?nav=icon&tab=1) | `{}`   | N    | 标签图标。 |

## TabContent Props

| 名称 | 类型      | 默认值 | 必传 | 说明       |
| ---- | --------- | ------ | ---- | ---------- |
| show | `boolean` | `true` | N    | 是否显示。 |

## TabContent Snippets

| 名称     | 类型                                                                | 参数 | 说明              |
| -------- | ------------------------------------------------------------------- | ---- | ----------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | TabContent 内容。 |



================================================
FILE: docs/mds/components/tabs/api_en.md
================================================
## Tabs Props

| Name       | Type                               | Default  | Required | Description                        |
| ---------- | ---------------------------------- | -------- | -------- | ---------------------------------- |
| tab        | `Tab`                              | `{}`     | Y        | Internal Tab component.            |
| active     | `number`                           | `0`      | N        | Active tab index.                  |
| duration   | `'fast'\|'base'\|'slow'\|'slower'` | `'base'` | N        | Transition animation duration.     |
| position   | `'t'\|'b'\|'l'\|'r'`               | `'t'`    | N        | Tab position.                      |
| transition | `boolean`                          | `true`   | N        | Whether to use transition effects. |

## Tabs Events

| Name     | Type                       | Parameters                | Description                        |
| -------- | -------------------------- | ------------------------- | ---------------------------------- |
| onchange | `(active: number) => void` | active - Active tab index | Triggered when active tab changes. |

## Tabs Snippets

| Name     | Type                                                                                      | Parameters                | Description        |
| -------- | ----------------------------------------------------------------------------------------- | ------------------------- | ------------------ |
| children | [`Snippet<[{ active: number }]>`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | active - Active tab index | Tabs main content. |

## Tab Props

| Name              | Type                                                  | Default  | Required | Description                                      |
| ----------------- | ----------------------------------------------------- | -------- | -------- | ------------------------------------------------ |
| labels            | `TabLabel[]`                                          | `[]`     | Y        | Tab content group.                               |
| active            | `number`                                              | `0`      | N        | Active tab index.                                |
| lineType          | `boolean`                                             | `false`  | N        | Whether to use line style.                       |
| radius            | `'none'\|'sm'\|'xl'\|'full'`                          | `'sm'`   | N        | Border radius style.                             |
| mx                | `'0'\|'1'\|'2'\|'3'\|'4'\|'6'\|'8'\|'12'\|'16'\|'20'` | `'2'`    | N        | Horizontal margin.                               |
| duration          | `'fast'\|'base'\|'slow'\|'slower'`                    | `'base'` | N        | Transition animation duration.                   |
| layout            | `'h'\|'v'`                                            | `'h'`    | N        | Horizontal or vertical layout.                   |
| love              | `boolean`                                             | `false`  | N        | Whether to enable care version.                  |
| injClass          | `string`                                              | `''`     | N        | Inject CSS to Tab wrapper.                       |
| tabInjClass       | `string`                                              | `''`     | N        | Inject CSS to single Tab.                        |
| activeTabInjClass | `string`                                              | `''`     | N        | Inject CSS to active Tab.                        |
| activeInjClass    | `string`                                              | `''`     | N        | Inject CSS to indicator.                         |
| overflow          | `boolean`                                             | `false`  | N        | Whether to enable overflow mode.                 |
| showNum           | `number`                                              | `3`      | N        | Number of fully displayed tabs in overflow mode. |
| autoScroll        | `boolean`                                             | `false`  | N        | Auto scroll in overflow mode.                    |

## Tab Events

| Name       | Type                       | Parameters                 | Description                    |
| ---------- | -------------------------- | -------------------------- | ------------------------------ |
| onclickTab | `(active: number) => void` | active - Active tab index. | Triggered when tab is clicked. |

## TabLabel Props

| Name | Type                                                      | Default | Required | Description |
| ---- | --------------------------------------------------------- | ------- | -------- | ----------- |
| text | `string`                                                  | `''`    | N        | Label text. |
| icon | [`Icon`](https://stdf.design/components?nav=icon&tab=1) | `{}`    | N        | Label icon. |

## TabContent Props

| Name | Type      | Default | Required | Description              |
| ---- | --------- | ------- | -------- | ------------------------ |
| show | `boolean` | `true`  | N        | Whether to show content. |

## TabContent Snippets

| Name     | Type                                                                | Parameters | Description         |
| -------- | ------------------------------------------------------------------- | ---------- | ------------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | TabContent content. |



================================================
FILE: docs/mds/components/tabs/FAQ.md
================================================



================================================
FILE: docs/mds/components/tabs/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/tabs/guide.md
================================================
## Tabs

Tabs 组件内部使用了 Tab 组件，而 Tabs Props 中的 tab 全部透传给 Tab，用于配置 Tab 不同的样式。

### Snippet

Tabs Props 的 transition 默认为 true，此时 Tabs 主体内容切换带有过渡效果。而当 transition 为 false，或者 position 为 'l' 或 'r' 时，Tabs 主体内容将不会有过渡效果，可以通过 Svelte 提供的 [{#snippet ...}](https://svelte.dev/docs/svelte/snippet) 传入，注意此时 children 需要将当前激活的 Tab 索引值 `{ active }` 传入，暴露给 Snippet 内部，再结合 TabContent 的 show 控制主体内容的显示与隐藏。通过暴露出的 active，你还可以自由使用其他方式控制主体区域内容的过渡效果。示例中展示了一种方式，请结合具体业务尝试其他切换效果。

### 选项卡位置

Tabs 通过 position（t：上、b：下、l：左、r：右）决定选项卡位置，而此参数又决定了其中 Tab 的布局方式 layout（h：水平、v：垂直）。

---

## Tab

Tab 组件可以单独使用，通过绑定的 onclickTab 事件，传递出当前激活选项卡的索引值。

### labels

此参数决定了 Tab 内部的选项卡内容，支持图标与文字自由搭配。数据类型为对象数组，内部对象由 text 和 icon 组成，而 icon 使用 Icon 组件渲染，具体参数请参考 [Icon Props](https://stdf.design/components?nav=icon&tab=1)。

### 线性风格

当 Tab props 的 lineType 为 true 时，Tab 会使用线性风格，但若布局方式为 v（垂直）则线性风格不会生效。

### 溢出模式

由于移动设备横向空间有限，当横向布局且 Tab 数量较多或者动态无法确定时，可以开启溢出模式，此时 Tabs 会自动隐藏溢出的 Tab，通过滑动来查看隐藏的 Tab。开启溢出模式后，可以通过 `showNum` 控制显示的 Tab 数量，通过 `autoScroll` 控制是否开启自动滚动。

溢出模式时，可见区域内实际显示的 Tab 是 `showNum+0.5`，如此设计会在初始时将最后一个 Tab 隐藏一半，以便在不刻意提示的情况下，用户可以自然地意识到隐藏了 Tab，从而产生滑动的操作。

> Tip：如果 Tab 内容宽度过大时请适当减小 `showNum`，以免 Tab 内容溢出被隐藏。

### CSS 注入

Tab 结构相对复杂，为了支持更灵活的自定义样式，内部支持四个地方注入 CSS，injClass 作用于 Tab 最外层元素；tabInjClass 作用于内部的单项 tab；activeTabInjClass 作用于当前激活的 tab；activeInjClass 作用于 Tab 的指示器。

若注入的 class 没生效，请在注入的 class 名称前添加“!” ，可参考 [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier)。



================================================
FILE: docs/mds/components/tabs/guide_en.md
================================================
## Tabs

The Tabs component internally uses the Tab component, and the tab in Tabs Props is fully passed through to Tab to configure different styles of Tab.

### Snippet

The transition in Tabs Props defaults to true, at which point the Tabs main content switches with transition effects. When transition is false, or position is 'l' or 'r', the Tabs main content will not have transition effects. It can be passed in through Svelte's [{#snippet ...}](https://svelte.dev/docs/svelte/snippet). Note that children needs to pass in the currently active Tab index value `{ active }` to expose it to the Snippet interior, and then combine with TabContent's show to control the display and hiding of the main content. Through the exposed active, you can also freely use other ways to control the transition effects of the main area content. The example shows one way, please try other switching effects in combination with specific business needs.

### Tab Position

Tabs determines the tab position through position (t: top, b: bottom, l: left, r: right), and this parameter also determines the layout mode of Tab within it (h: horizontal, v: vertical).

---

## Tab

The Tab component can be used independently, passing out the index value of the currently active tab through the bound onclickTab event.

### labels

This parameter determines the tab content inside Tab, supporting free combination of icons and text. The data type is an array of objects, with internal objects consisting of text and icon, while icon is rendered using the Icon component. For specific parameters, please refer to [Icon Props](https://stdf.design/components?nav=icon&tab=1).

### Line Style

When lineType in Tab props is true, Tab will use line style, but if the layout mode is v (vertical), the line style will not take effect.

### Overflow Mode

Due to limited horizontal space on mobile devices, when using horizontal layout and the number of Tabs is large or dynamically uncertain, overflow mode can be enabled. At this time, Tabs will automatically hide overflowing Tabs, which can be viewed by sliding. After enabling overflow mode, you can control the number of displayed Tabs through `showNum`, and control whether to enable auto-scrolling through `autoScroll`.

In overflow mode, the actual number of Tabs displayed in the visible area is `showNum+0.5`. This design will initially hide half of the last Tab, so that users can naturally realize that Tabs are hidden without deliberate prompting, thus producing sliding operations.

> Tip: If the Tab content width is too large, please appropriately reduce `showNum` to prevent Tab content from being hidden due to overflow.

### CSS Injection

The Tab structure is relatively complex. To support more flexible custom styles, four places are supported for CSS injection internally: injClass acts on the outermost element of Tab; tabInjClass acts on the internal single tab; activeTabInjClass acts on the currently active tab; activeInjClass acts on the Tab indicator.

If the injected class doesn't take effect, please add "!" before the injected class name. You can refer to [Tailwind Important modifier](https://tailwindcss.com/docs/configuration#important-modifier).



================================================
FILE: docs/mds/components/tabs/version.md
================================================
## 0.4.4

- [!tag|A|0|]支持溢出模式。

## 0.4.3

- [!tag|O|0|]Tabs Props 的 `placement` 改为 `position`。
- [!tag|O|0|]Tab 的 `mx` 默认值由 '4' 改为 '2'。
- [!tag|B|3|]修复 [Issues](https://github.com/any-tdf/stdf/issues/17)。[!issue|Zz-ZzzZ|]



================================================
FILE: docs/mds/components/tabs/version_en.md
================================================
## 0.4.4

- [!tag|A|0|]Overflow mode is supported.

## 0.4.3

- [!tag|O|0|]Tabs Props `placement` changed to `position`.
- [!tag|O|0|]Tab `mx` default value changed from '4' to '2'.
- [!tag|B|3|]Fix [Issues](https://github.com/any-tdf/stdf/issues/17). [!issue|Zz-ZzzZ|]



================================================
FILE: docs/mds/components/timePicker/api.md
================================================
## TimePicker Props

| 名称        | 类型                                                        | 默认值                               | 必传 | 说明               |
| ----------- | ----------------------------------------------------------- | ------------------------------------ | ---- | ------------------ |
| visible     | `boolean`                                                   | `false`                              | N    | 是否显示。         |
| type        | `TimePickerType`                                            | `'YYYYMMDDhhmmss'`                   | N    | 时间类型。         |
| yearProps   | `TimePickerItem`                                            | `{}`                                 | N    | 年份列参数。       |
| monthProps  | `TimePickerItem`                                            | `{}`                                 | N    | 月份列参数。       |
| dayProps    | `TimePickerItem`                                            | `{}`                                 | N    | 日期列参数。       |
| hourProps   | `TimePickerItem`                                            | `{}`                                 | N    | 小时列参数。       |
| minuteProps | `TimePickerItem`                                            | `{}`                                 | N    | 分钟列参数。       |
| secondProps | `TimePickerItem`                                            | `{}`                                 | N    | 秒钟列参数。       |
| initYear    | `string`                                                    | `''`                                 | N    | 初始选定的年份。   |
| initMonth   | `string`                                                    | `''`                                 | N    | 初始选定的月份。   |
| initDay     | `string`                                                    | `''`                                 | N    | 初始选定的日期。   |
| initHour    | `string`                                                    | `''`                                 | N    | 初始选定的小时。   |
| initMinute  | `string`                                                    | `''`                                 | N    | 初始选定的分钟。   |
| initSecond  | `string`                                                    | `''`                                 | N    | 初始选定的秒钟。   |
| minuteStep  | `number`                                                    | `1`                                  | N    | 分钟步长。         |
| secondStep  | `number`                                                    | `1`                                  | N    | 秒钟步长。         |
| yearRange   | `[number,number]\|[]`                                       | `[]`                                 | N    | 年份范围。         |
| monthRange  | `[number,number]`                                           | `[1, 12]`                            | N    | 月份范围。         |
| hourRange   | `[number,number]`                                           | `[0, 23]`                            | N    | 小时范围。         |
| minuteRange | `[number,number]`                                           | `[0, 59]`                            | N    | 分钟范围。         |
| secondRange | `[number,number]`                                           | `[0, 59]`                            | N    | 秒钟范围。         |
| showTips    | `boolean`                                                   | `true`                               | N    | 是否显示提示信息。 |
| cancelText  | `string`                                                    | 当前语言的 timePicker.defaultCancel  | N    | 取消选项文本。     |
| confirmText | `string`                                                    | 当前语言的 timePicker.defaultConfirm | N    | 确定选项文本。     |
| title       | `string`                                                    | 当前语言的 timePicker.defaultTitle   | N    | 中间标题文本。     |
| yearText    | `string`                                                    | 当前语言的 timePicker.defaultYear    | N    | 年份列提示文本。   |
| monthText   | `string`                                                    | 当前语言的 timePicker.defaultMonth   | N    | 月份列提示文本。   |
| dayText     | `string`                                                    | 当前语言的 timePicker.defaultDay     | N    | 日期列提示文本。   |
| hourText    | `string`                                                    | 当前语言的 timePicker.defaultHour    | N    | 小时列提示文本。   |
| minuteText  | `string`                                                    | 当前语言的 timePicker.defaultMinute  | N    | 分钟列提示文本。   |
| secondText  | `string`                                                    | 当前语言的 timePicker.defaultSecond  | N    | 秒钟列提示文本。   |
| outFormat   | `string`                                                    | `''`                                 | N    | 返回数据格式。     |
| popup       | [`Popup`](https://stdf.design/components?nav=popup&tab=1) | `{}`                                 | N    | 弹出层参数。       |

## TimePicker Events

| 名称      | 类型                                                | 参数                                                   | 描述                 |
| --------- | --------------------------------------------------- | ------------------------------------------------------ | -------------------- |
| onclose   | `() => void`                                        | -                                                      | 关闭时触发。         |
| oncancel  | `() => void`                                        | -                                                      | 点击左侧取消时触发。 |
| onconfirm | `(timeStr: string, timeObj: TimePickerObj) => void` | timeStr - 格式化后的时间字符串<br />timeObj - 时间对象 | 点击右侧确定时触发。 |

## TimePickerItem Props

| 名称    | 类型                        | 默认值     | 必传 | 说明                                         |
| ------- | --------------------------- | ---------- | ---- | -------------------------------------------- |
| flex    | `number`                    | `1`        | N    | 年、月、日、时、分、秒数据列所占的宽度比例。 |
| showRow | `3\|5\|7`                   | `5`        | N    | 年、月、日、时、分、秒数据列可见行数。       |
| align   | `'left'\|'center'\|'right'` | `'center'` | N    | 年、月、日、时、分、秒数据列对齐方式。       |

## TimePickerType

```javascript
type TimePickerType =
	| 'YYYY'
	| 'MM'
	| 'hh'
	| 'mm'
	| 'ss'
	| 'YYYYMM'
	| 'hhmm'
	| 'mmss'
	| 'YYYYMMDD'
	| 'hhmmss'
	| 'YYYYMMDDhh'
	| 'YYYYMMDDhhmm'
	| 'YYYYMMDDhhmmss';
```

## TimePickerObj

```javascript
type TimePickerObj = { YYYY: string; MM: string; DD: string; hh: string; mm: string; ss: string };
```



================================================
FILE: docs/mds/components/timePicker/api_en.md
================================================
## TimePicker Props

| Name        | Type                                                        | Default                                    | Required | Description                 |
| ----------- | ----------------------------------------------------------- | ------------------------------------------ | -------- | --------------------------- |
| visible     | `boolean`                                                   | `false`                                    | N        | Whether to show the picker. |
| type        | `TimePickerType`                                            | `'YYYYMMDDhhmmss'`                         | N        | Time type.                  |
| yearProps   | `TimePickerItem`                                            | `{}`                                       | N        | Year column parameters.     |
| monthProps  | `TimePickerItem`                                            | `{}`                                       | N        | Month column parameters.    |
| dayProps    | `TimePickerItem`                                            | `{}`                                       | N        | Day column parameters.      |
| hourProps   | `TimePickerItem`                                            | `{}`                                       | N        | Hour column parameters.     |
| minuteProps | `TimePickerItem`                                            | `{}`                                       | N        | Minute column parameters.   |
| secondProps | `TimePickerItem`                                            | `{}`                                       | N        | Second column parameters.   |
| initYear    | `string`                                                    | `''`                                       | N        | Initial selected year.      |
| initMonth   | `string`                                                    | `''`                                       | N        | Initial selected month.     |
| initDay     | `string`                                                    | `''`                                       | N        | Initial selected day.       |
| initHour    | `string`                                                    | `''`                                       | N        | Initial selected hour.      |
| initMinute  | `string`                                                    | `''`                                       | N        | Initial selected minute.    |
| initSecond  | `string`                                                    | `''`                                       | N        | Initial selected second.    |
| minuteStep  | `number`                                                    | `1`                                        | N        | Minute step.                |
| secondStep  | `number`                                                    | `1`                                        | N        | Second step.                |
| yearRange   | `[number,number]\|[]`                                       | `[]`                                       | N        | Year range.                 |
| monthRange  | `[number,number]`                                           | `[1, 12]`                                  | N        | Month range.                |
| hourRange   | `[number,number]`                                           | `[0, 23]`                                  | N        | Hour range.                 |
| minuteRange | `[number,number]`                                           | `[0, 59]`                                  | N        | Minute range.               |
| secondRange | `[number,number]`                                           | `[0, 59]`                                  | N        | Second range.               |
| showTips    | `boolean`                                                   | `true`                                     | N        | Whether to show tips.       |
| cancelText  | `string`                                                    | Current language timePicker.defaultCancel  | N        | Cancel button text.         |
| confirmText | `string`                                                    | Current language timePicker.defaultConfirm | N        | Confirm button text.        |
| title       | `string`                                                    | Current language timePicker.defaultTitle   | N        | Title text.                 |
| yearText    | `string`                                                    | Current language timePicker.defaultYear    | N        | Year column tip text.       |
| monthText   | `string`                                                    | Current language timePicker.defaultMonth   | N        | Month column tip text.      |
| dayText     | `string`                                                    | Current language timePicker.defaultDay     | N        | Day column tip text.        |
| hourText    | `string`                                                    | Current language timePicker.defaultHour    | N        | Hour column tip text.       |
| minuteText  | `string`                                                    | Current language timePicker.defaultMinute  | N        | Minute column tip text.     |
| secondText  | `string`                                                    | Current language timePicker.defaultSecond  | N        | Second column tip text.     |
| outFormat   | `string`                                                    | `''`                                       | N        | Output data format.         |
| popup       | [`Popup`](https://stdf.design/components?nav=popup&tab=1) | `{}`                                       | N        | Popup parameters.           |

## TimePicker Events

| Name      | Type                                                | Parameters                                                 | Description                             |
| --------- | --------------------------------------------------- | ---------------------------------------------------------- | --------------------------------------- |
| onclose   | `() => void`                                        | -                                                          | Triggered when closing.                 |
| oncancel  | `() => void`                                        | -                                                          | Triggered when clicking cancel button.  |
| onconfirm | `(timeStr: string, timeObj: TimePickerObj) => void` | timeStr - Formatted time string<br />timeObj - Time object | Triggered when clicking confirm button. |

## TimePickerItem Props

| Name    | Type                        | Default    | Required | Description                                                     |
| ------- | --------------------------- | ---------- | -------- | --------------------------------------------------------------- |
| flex    | `number`                    | `1`        | N        | Width ratio of year, month, day, hour, minute, second columns.  |
| showRow | `3\|5\|7`                   | `5`        | N        | Visible rows of year, month, day, hour, minute, second columns. |
| align   | `'left'\|'center'\|'right'` | `'center'` | N        | Alignment of year, month, day, hour, minute, second columns.    |

## TimePickerType

```javascript
type TimePickerType =
	| 'YYYY'
	| 'MM'
	| 'hh'
	| 'mm'
	| 'ss'
	| 'YYYYMM'
	| 'hhmm'
	| 'mmss'
	| 'YYYYMMDD'
	| 'hhmmss'
	| 'YYYYMMDDhh'
	| 'YYYYMMDDhhmm'
	| 'YYYYMMDDhhmmss';
```

## TimePickerObj

```javascript
type TimePickerObj = { YYYY: string; MM: string; DD: string; hh: string; mm: string; ss: string };
```



================================================
FILE: docs/mds/components/timePicker/FAQ.md
================================================



================================================
FILE: docs/mds/components/timePicker/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/timePicker/guide.md
================================================
## 使用场景

TimePicker 组件用于选择时间，支持单列选择和多列选择。默认参数选择前后十年的时间，默认初始时选中当前时间。

## 时间类型

TimePicker 组件通过传入的 type 参数来决定选择的时间类型，由 YYYY MM DD hh mm ss 组合而来，目前共支持以下 13 种，不在此列出的类型将使用默认的 'YYYYMMDDhhmmss' 类型。

- YYYY：年
- MM：月
- DD：日
- hh：时
- mm：分
- ss：秒
- YYYYMM：年月
- hhmm：时分
- mmss：分秒
- YYYYMMDD：年月日
- hhmmss：时分秒
- YYYYMMDDhh：年月日时
- YYYYMMDDhhmm：年月日时分
- YYYYMMDDhhmmss：年月日时分秒

## 单列样式

无论是年、月、日、时、分、秒的列数据，都可以通过传入对应的 Props 来自定义三种样式，分别是：flex、showRow、align。具体使用请参考示例。

## 限定选择区间

因为每月的天数会根据当前年与月动态更新，所以除了天数列数据，其余列数据都可以通过传入对应的 Range 来限定选择区间，由对应数据组成的数组。但请保证传入的区间数组为两项，**每一项为 Number 类型**，且第一项小于第二项，否则将使用默认的区间。具体使用请参考示例。

## 初始选定值

每列数据初始化时默认会选择当前时间，同时也支持传入对应的初始值来自定义初始选定值。但需要注意的是传入的初始值类型为字符类型，且**保证月、日、时、分、秒的初始值不足两位时补齐至两位**。具体使用请参考示例。

## 分秒步长

考虑实际用途，支持对分和秒数据进行步长设置，步长默认为 1，即每次选择都会增加 1 分或 1 秒。具体使用请参考示例。

## outFormat

默认情况下，TimePicker 组件的 outFormat 由传入的 type 按照【年月日之间用 - 连接，时分秒之间用 : 连接，两者之间用空格连接】的规则生成，比如转入 `'YYYYMMDD'` 对应 `YYYY-MM-DD`，`'YYYYMMDDhh'` 对应 `YYYY-MM-DD hh`，`'hhmmss'` 对应 `hh:mm:ss` 等。当然也可以自定义输出格式。具体使用请参考示例。

需要注意的是，onconfirm 返回的第二个参数是选择的时间对象，方便开发者自行处理。

## 说明

TimePicker 是在 Popup 基础上封装的，通过预先定义一些 Popup 的 Props 实现，因此可以通过传入 Popup 的属性来实现不同的效果。比如示例中通过设置 popup 的 radius 改变圆角风格。



================================================
FILE: docs/mds/components/timePicker/guide_en.md
================================================
## Usage Scenarios

The TimePicker component is used for time selection, supporting both single-column and multi-column selection. By default, it allows selection of time within 10 years before and after the current year, and initially selects the current time.

## Time Types

The TimePicker component determines the time type through the type parameter, which is composed of YYYY MM DD hh mm ss. Currently, it supports the following 13 types. Any type not listed here will use the default 'YYYYMMDDhhmmss' type.

- YYYY: Year
- MM: Month
- DD: Day
- hh: Hour
- mm: Minute
- ss: Second
- YYYYMM: Year and Month
- hhmm: Hour and Minute
- mmss: Minute and Second
- YYYYMMDD: Year, Month and Day
- hhmmss: Hour, Minute and Second
- YYYYMMDDhh: Year, Month, Day and Hour
- YYYYMMDDhhmm: Year, Month, Day, Hour and Minute
- YYYYMMDDhhmmss: Year, Month, Day, Hour, Minute and Second

## Single Column Style

For all column data (year, month, day, hour, minute, second), you can customize three styles by passing corresponding Props: flex, showRow, and align. Please refer to the examples for specific usage.

## Selection Range Limitation

Since the number of days in each month updates dynamically based on the current year and month, all column data except days can have their selection range limited by passing in the corresponding Range, which is an array of corresponding data. However, please ensure that the range array has two items, **each item being of Number type**, and the first item is less than the second item, otherwise the default range will be used. Please refer to the examples for specific usage.

## Initial Selected Value

By default, each column data initially selects the current time, but you can also pass in corresponding initial values to customize the initially selected value. Note that the initial value type should be string type, and **ensure that month, day, hour, minute, and second initial values are padded to two digits if less than two digits**. Please refer to the examples for specific usage.

## Minute and Second Step

Considering practical use, the component supports step settings for minute and second data. The default step is 1, meaning each selection increases by 1 minute or 1 second. Please refer to the examples for specific usage.

## outFormat

By default, the TimePicker component's outFormat is generated from the input type following the rule [years, months, and days are connected by -, hours, minutes, and seconds are connected by :, and the two parts are connected by space]. For example, `'YYYYMMDD'` corresponds to `YYYY-MM-DD`, `'YYYYMMDDhh'` corresponds to `YYYY-MM-DD hh`, `'hhmmss'` corresponds to `hh:mm:ss`, etc. Of course, you can also customize the output format. Please refer to the examples for specific usage.

Note that the second parameter returned by onconfirm is the selected time object, making it convenient for developers to handle themselves.

## Note

TimePicker is encapsulated based on Popup by pre-defining some Popup Props, so different effects can be achieved by passing in Popup properties. For example, in the example, the radius style is changed by setting the popup's radius.



================================================
FILE: docs/mds/components/timePicker/version.md
================================================



================================================
FILE: docs/mds/components/timePicker/version_en.md
================================================



================================================
FILE: docs/mds/components/toast/api.md
================================================
## Toast Props

| 名称             | 类型                                                             | 默认值     | 必传 | 说明                                                                  |     |
| ---------------- | ---------------------------------------------------------------- | ---------- | ---- | --------------------------------------------------------------------- | :-- |
| message          | `string`                                                         | `''`       | N    | 提示内容。                                                            |
| visible          | `boolean`                                                        | `false`    | N    | 是否显示。                                                            |
| duration         | `number`                                                         | `2000`     | N    | 显示时长，为 0 时提示不会自动关闭，单位：ms。                         |
| position         | `'center'\|'top'\|'bottom'`                                      | `'center'` | N    | 显示位置。                                                            |
| py               | `'0'\|'10'\|'20'\|'40'\|'60'\|'80'`                              | `'20'`     | N    | 顶部和底部显示时距离顶部或底部的距离，position 为 'center' 时不生效。 |
| radius           | `'none'\|'xs'\|'sm'\|'md'\|'lg'\|'xl'\|'2xl'\|'full'`            | `'sm'`     | N    | 圆角风格。                                                            |
| transitionType   | `'scale'\|'fly'\|'fade'\|'slide'\|'blur'\|null`                  | `'scale'`  | N    | 动画类型。                                                            |
| transitionParams | [`Transition`](https://svelte.dev/docs/svelte/svelte-transition) | `{}`       | N    | 动画参数，其中 duration 默认 300。                                    |
| outDuration      | `number`                                                         | `0`        | N    | 退出动画时间，单位：ms。                                              |
| type             | `'success'\|'error'\|'warning'\|'info'\|'loading'\|'icon'\|null` | `null`     | N    | 提示图标类型。                                                        |
| mask             | [`Mask`](https://stdf.design/components?nav=mask&tab=1)        | `{}`       | N    | 遮罩层参数。                                                          |
| loading          | [`Loading`](https://stdf.design/components?nav=loading&tab=1)  | `{}`       | N    | 加载组件参数，仅 type 为 `'loading'` 时生效。                         |
| icon             | [`Icon`](https://stdf.design/components?nav=icon&tab=1)        | `{}`       | N    | 图标组件参数，仅 type 为非 `'loading'` 且非 `null` 时生效。           |
| zIndex           | `number`                                                         | `1000`     | N    | z-index。                                                             |
| clickable        | `boolean`                                                        | `false`    | N    | 是否允许点击穿透。                                                    |
| dynamicFixed     | `boolean`                                                        | `true`     | N    | 是否动态固定。                                                        |

## Toast Events

| 名称    | 类型         | 参数 | 描述             |
| ------- | ------------ | ---- | ---------------- |
| onclose | `() => void` | -    | 提示关闭时触发。 |

## Toast Snippets

| 名称     | 类型                                                                | 参数 | 说明                 |
| -------- | ------------------------------------------------------------------- | ---- | -------------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -    | 传入时渲染提示内容。 |



================================================
FILE: docs/mds/components/toast/api_en.md
================================================
## Toast Props

| Name             | Type                                                             | Default    | Required | Description                                                                        |     |
| ---------------- | ---------------------------------------------------------------- | ---------- | -------- | ---------------------------------------------------------------------------------- | :-- |
| message          | `string`                                                         | `''`       | N        | Toast content.                                                                     |
| visible          | `boolean`                                                        | `false`    | N        | Whether to show the toast.                                                         |
| duration         | `number`                                                         | `2000`     | N        | Display duration in ms. Toast won't auto-close if set to 0.                        |
| position         | `'center'\|'top'\|'bottom'`                                      | `'center'` | N        | Display position.                                                                  |
| py               | `'0'\|'10'\|'20'\|'40'\|'60'\|'80'`                              | `'20'`     | N        | Distance from top/bottom when position is 'top'/'bottom'. Ignored for 'center'.    |
| radius           | `'none'\|'xs'\|'sm'\|'md'\|'lg'\|'xl'\|'2xl'\|'full'`            | `'sm'`     | N        | Border radius style.                                                               |
| transitionType   | `'scale'\|'fly'\|'fade'\|'slide'\|'blur'\|null`                  | `'scale'`  | N        | Animation type.                                                                    |
| transitionParams | [`Transition`](https://svelte.dev/docs/svelte/svelte-transition) | `{}`       | N        | Animation parameters, default duration is 300.                                     |
| outDuration      | `number`                                                         | `0`        | N        | Exit animation duration in ms.                                                     |
| type             | `'success'\|'error'\|'warning'\|'info'\|'loading'\|'icon'\|null` | `null`     | N        | Toast icon type.                                                                   |
| mask             | [`Mask`](https://stdf.design/components?nav=mask&tab=1)        | `{}`       | N        | Mask layer parameters.                                                             |
| loading          | [`Loading`](https://stdf.design/components?nav=loading&tab=1)  | `{}`       | N        | Loading component parameters, only works when type is `'loading'`.                 |
| icon             | [`Icon`](https://stdf.design/components?nav=icon&tab=1)        | `{}`       | N        | Icon component parameters, only works when type is not `'loading'` and not `null`. |
| zIndex           | `number`                                                         | `1000`     | N        | z-index value.                                                                     |
| clickable        | `boolean`                                                        | `false`    | N        | Whether to allow click through.                                                    |
| dynamicFixed     | `boolean`                                                        | `true`     | N        | Whether to use dynamic fixed positioning.                                          |

## Toast Events

| Name    | Type         | Parameters | Description                         |
| ------- | ------------ | ---------- | ----------------------------------- |
| onclose | `() => void` | -          | Triggered when the toast is closed. |

## Toast Snippets

| Name     | Type                                                                | Parameters | Description                        |
| -------- | ------------------------------------------------------------------- | ---------- | ---------------------------------- |
| children | [`Snippet`](https://svelte.dev/docs/svelte/snippet#Typing-snippets) | -          | Renders toast content when passed. |



================================================
FILE: docs/mds/components/toast/FAQ.md
================================================



================================================
FILE: docs/mds/components/toast/FAQ_en.md
================================================



================================================
FILE: docs/mds/components/toast/guide.md
================================================
> Toast 使用了图标 ri-checkbox-circle-line、ri-close-circle-line、ri-error-warning-line、ri-information-line，请确保项目的 symbol.svg 文件中包含这些图标。详细信息请参考 [STDF-指南 - 图标](https://stdf.design/guide/icon)。

## 显示位置

提示默认显示在屏幕中央，也可以通过 `position` 属性设置显示位置，当 position 为 `top` 或 `bottom` 时，可以通过 `py` 属性设置距离顶部或底部的距离。

## 动画

提示默认使用 `scale` 动画，也可以通过 `transitionType` 属性设置其他动画类型，通过 `transitionParams` 属性设置动画参数，其中 `duration` 表示进入的动画时间。

transitionParams 具体支持的参数请参考 [svelte/transition](https://svelte.dev/docs#run-time-svelte-transition)。

考虑到用户体验，提示信息出现时有一个较短的动画（默认 300ms），能引起用户的注意力；而提示信息展示完后一般需要迅速关闭，所以退出动画默认为 0ms，当然也可以通过 `outDuration` 属性设置退出的动画时间。

退出动画只允许设置动画时长，其他参数会沿用进入动画的参数，保证动画效果「从哪里来回哪里去」。

## 显示时长

显示时长默认为 2000ms，可以通过 `duration` 属性设置显示时长。当 `duration` 为 0 时，提示不会自动关闭。

注意：由于出现有动画时长（默认 300ms 或自定义其他值），所以 `duration` 不能低于出现的动画时长，否则提示信息还没完全出现就被关闭了 😭。

## type

Toast 内部通过 `type` 属性为 `'success'|'error'|'warning'|'info'` 四种情况设置了对应的图标，图标颜色跟随[颜色系统](https://stdf.design/guide/color)中的功能色，也可以传入 `'loading'` 和 `'icon'` 配合 loading 与 icon 自定义对应的显示内容，传 `null` 不显示。请参考示例。

## Snippet

默认情况下，Toast 内部可以通过 `children` 属性传入任意内容作为提示信息。

## 优化

由于移动端的 Safari、Chrome 或其他一些浏览器滚动页面时会动态显示工具栏或地址栏（多此一举），导致页面的高度也会动态变化，Toast 针对这一情况也做了优化。当 dynamicFixed 为 true 时滚动页面时会动态地更新页面高度，相对应地 Toast 内部元素相对于页面的位置也会动态更新。

当然，这个滚动监听会有微弱的性能损失，如果你的项目中不需要此功能（比如在可控的 webview 内使用），可以设置 dynamicFixed 为 false 来关闭。



================================================
FILE: docs/mds/components/toast/guide_en.md
================================================
> Toast uses icons ri-checkbox-circle-line, ri-close-circle-line, ri-error-warning-line, ri-information-line. Please ensure these icons are included in your project's symbol.svg file. For details, please refer to [STDF-Guide-Icon](https://stdf.design/guide/icon).

## Display Position

By default, the toast appears in the center of the screen. You can also set its position using the `position` prop. When position is set to `top` or `bottom`, you can use the `py` prop to set the distance from the top or bottom.

## Animation

Toast uses `scale` animation by default. You can set other animation types through the `transitionType` prop and configure animation parameters via `transitionParams`, where `duration` represents the entry animation time.

For detailed supported parameters of transitionParams, please refer to [svelte/transition](https://svelte.dev/docs#run-time-svelte-transition).

For better user experience, the toast appears with a short animation (default 300ms) to catch user attention. Since toast messages generally need to close quickly after display, the exit animation is 0ms by default. However, you can set the exit animation duration using the `outDuration` prop.

The exit animation only allows setting the duration, while other parameters inherit from the entry animation to ensure the animation effect "returns where it came from".

## Display Duration

The default display duration is 2000ms, which can be customized using the `duration` prop. When `duration` is 0, the toast won't close automatically.

Note: Since there is an entry animation duration (default 300ms or custom value), `duration` cannot be less than the entry animation duration, otherwise the toast would close before fully appearing 😭.

## type

Toast internally sets corresponding icons for four types: `'success'|'error'|'warning'|'info'` through the `type` prop, and the icon color follows the functional color in the [Color System](https://stdf.design/guide/color). You can also pass `'loading'` and `'icon'` to customize display content with loading and icon components, or pass `null` to display no icon. Please refer to examples.

## Snippet

By default, Toast can accept any content as the prompt message through the `children` prop.

## Optimization

Since mobile Safari, Chrome, and some other browsers dynamically show/hide toolbars or address bars when scrolling (unnecessarily), causing page height to change dynamically, Toast has been optimized for this situation. When dynamicFixed is true, the page height updates dynamically while scrolling, and correspondingly, Toast's internal elements' positions relative to the page update dynamically.

Of course, this scroll monitoring causes slight performance overhead. If your project doesn't need this feature (e.g., when used in a controlled webview), you can disable it by setting dynamicFixed to false.



================================================
FILE: docs/mds/components/toast/version.md
================================================



================================================
FILE: docs/mds/components/toast/version_en.md
================================================



================================================
FILE: docs/mds/guide/about.md
================================================
## STDF 名称

常规解释：S 代表 Simple（简单），T 代表 Tiny（轻量），D 代表 Design（设计），F 代表 Fast（快速），STDF 代表一个使用简单、体积轻量、设计友好、开发快速的组件库。

非常规解释：S 和 T 分别代表 Svelte 和 Tailwind，因为 STDF 是基于 Svelte 和 Tailwind 的。DF 可以看成诗人杜甫，不像李白那么浪漫飘逸，他注重的是实用性与易用性，这也是 STDF 的设计理念。希望每一位使用 STDF 的开发者都能写出诗一般的代码。

## 为什么要做这个库

首先最重要的是补充 Svelte 生态。

关于 UI 组件库，PC 端有很多优秀的产品，但是移动端并没有能与 PC 端比肩的产品，这是由于移动端的特殊性导致的。移动端产品大多数是 To C 业务，这就要求对组件库的灵活性有更高的要求。在设计组件 API 的时候，需要有更多的参数支持可供配置，但又不能设计得太过复杂。而在 UI 设计方面，不能有太多的个性化设计，这样才能达到组件的复用性。

市面上也有很多移动端的组件库，但是使用下来还是有很多痛点，比如一些组件库的设计风格太过个性化，导致组件的复用性不高；一些组件库的可配置 API 太少，无法通过简单的 API 配置出符合业务需求的组件；一些组件库的文档太过高深或简陋，使初上手的人很难理解组件的使用方法；一些组件库的文档和 Demo 中英混杂，难以查阅；一些组件库的 Demo 太少或太简陋，高频使用时无法直接复制使用，降低开发效率等。

在体验过 Svelte 和 Tailwind 之后，发现使用它们开发真的是非常舒服，所以就想着能不能把它们结合起来，做一个移动端的 UI 组件库。这样的话，就能够在移动端也享受到 Svelte 和 Tailwind 带来的开发体验了。

## 适用场景

在移动端有一种业务场景，应用不算复杂，使用 Vue 或者 React 开发其实会显得「大材小用」了，可能整个应用打包之后的 JS 体积也就几十 KB，但是使用 Vue 或者 React 开发，这两个库的基础大小就超过了几十 KB，这样就得不偿失了，而且移动端 To C 应用体积过大是非常不可取的。但是使用纯原生 JS 开发，又会显得开发效率低下，这个时候 Svelte 就是一个很好的选择，它的简洁语法，使原生 JS 代码有了响应式能力。



================================================
FILE: docs/mds/guide/about_en.md
================================================
## STDF Name

Generally speaking, S stands for Simple, T stands for Tiny, D stands for Design, and F stands for Fast. So, STDF is a simple, lightweight, design-friendly, and fast UI component library.

Unconventional explanation: S and T stand for Svelte and Tailwind respectively, because STDF is based on Svelte and Tailwind. DF can be seen as the poet Du Fu, who is not as romantic and elegant as Li Bai. He pays attention to practicality and ease of use, which is also the design concept of STDF. I hope that every developer who uses STDF can write code like a poem.

## Why Create This Library

First and foremost, it's to complement the Svelte ecosystem.

Regarding UI component libraries, there are many excellent products for PC, but there aren't many on the mobile side that can match the PC level. This is due to the unique characteristics of the mobile side. Most mobile products are To C businesses, which require higher flexibility in component libraries. When designing component APIs, more parameter support for configuration is required, but it cannot be designed to be too complex. In terms of UI design, there should not be too many personalized designs so that component reuse can be achieved.

There are also many mobile component libraries on the market, but there are still many pain points in use. For example, some component library design styles are too personalized, resulting in low component reuse. Some component libraries have too few configurable APIs and cannot configure components that meet business requirements through a simple API. Some component library documentation is either too advanced or too rudimentary, making it difficult for beginners to understand how to use the components. Some component library documentation and demo are mixed with Chinese and English, making it difficult to browse. Some component library demos are too few or too simple, making it difficult to directly copy and use when used frequently, which reduces development efficiency, and so on.

After experiencing Svelte and Tailwind, I found that developing with them is really comfortable, so I thought about combining them to create a mobile UI component library. In this way, we can enjoy the development experience brought by Svelte and Tailwind on the mobile side too.

## Applicable Scenarios

There is a mobile business scenario where the application is not too complex, and developing with Vue or React may appear to be "overkill." The entire application package JS size may only be a few tens of KB, but using Vue or React would result in the base sizes of these two libraries exceeding tens of KB, which would be too costly. Additionally, it is not desirable to have a large volume of To C applications on mobile platforms. However, developing with pure native JS would appear to be inefficient. In such cases, Svelte is a good choice. Its concise syntax gives native JS code responsive capabilities.



================================================
FILE: docs/mds/guide/changelog.md
================================================
## 1.0.8 <font size=1>2025-05-04</font>

- 修复 Grids 组件，详见 [Grids](https://stdf.design/components?nav=grids&tab=4)。

## 1.0.7 <font size=1>2025-04-30</font>

- 修复部分类型错误。
- 修复 `id_ID` 语言文件错误。

## 1.0.6 <font size=1>2025-04-27</font>

- 修复 Input 组件，详见 [Input](https://stdf.design/components?nav=input&tab=4)。

## 1.0.5 <font size=1>2025-04-27</font>

- 修复 Input 组件，详见 [Input](https://stdf.design/components?nav=input&tab=4)。

## 1.0.4 <font size=1>2025-04-26</font>

- 增强 Input 组件，详见 [Input](https://stdf.design/components?nav=input&tab=4)。
- 增强 Button 组件，详见 [Button](https://stdf.design/components?nav=button&tab=4)。
- 补充遗漏的语言文件。
- 修复类型导出错误。

## 1.0.3 <font size=1>2025-04-07</font>

- 完整支持 Svelte v5、Tailwind CSS v4 与 TypeScript，包括库、示例、create-stdf、站点。
- 按照 Svelte 官方 CLI [sv create](https://svelte.dev/docs/cli/sv-create) 重构库文件。
- 增强 NavBar 组件，详见 [NavBar](https://stdf.design/components?nav=navBar&tab=4)。
- 修复 Cell 组件，详见 [Cell](https://stdf.design/components?nav=cell&tab=4)。
- 增强 NumKeyboard 组件，详见 [NumKeyboard](https://stdf.design/components?nav=numKeyboard&tab=4)。
- 重写 Checkbox、Radio 等组件，修改部分组件 API，升级时请注意检查。
- 文档组件 API 增加类型。
- 跟随 Tailwind CSS v4，文档站点、主题生成器、组件库等颜色系统统一使用 oklch，参考 [Tailwind CSS](https://tailwindcss.com/docs/colors)。

## 1.0.0 <font size=1>2025-04-07</font>

- 升级至 1.x 版本，重构项目结构。



================================================
FILE: docs/mds/guide/changelog_en.md
================================================
## 1.0.8 <font size=1>2025-05-04</font>

- Fixed Grids component, please see [Grids](https://stdf.design/components?nav=grids&tab=4).

## 1.0.7 <font size=1>2025-04-30</font>

- Fixed some type errors.
- Fixed `id_ID` language file error.

## 1.0.6 <font size=1>2025-04-27</font>

- Fixed Input component, please see [Input](https://stdf.design/components?nav=input&tab=4).

## 1.0.5 <font size=1>2025-04-27</font>

- Fixed Input component, please see [Input](https://stdf.design/components?nav=input&tab=4).

## 1.0.4 <font size=1>2025-04-26</font>

- Enhanced Input component, please see [Input](https://stdf.design/components?nav=input&tab=4).
- Enhanced Button component, please see [Button](https://stdf.design/components?nav=button&tab=4).
- Added missing language files.
- Fixed type export error.

## 1.0.3 <font size=1>2025-04-07</font>

- Full support for Svelte v5, Tailwind CSS v4, and TypeScript, including libraries, demos, create-stdf, and site.
- Rebuilt the library according to Svelte official CLI [sv create](https://svelte.dev/docs/cli/sv-create).
- Enhanced NavBar component, please see [NavBar](https://stdf.design/components?nav=navBar&tab=4).
- Fixed Cell component, please see [Cell](https://stdf.design/components?nav=cell&tab=4).
- Enhanced NumKeyboard component, please see [NumKeyboard](https://stdf.design/components?nav=numKeyboard&tab=4).
- Rewrote Checkbox, Radio, etc. components, modified some component APIs, please check when upgrading.
- Document component API added type.
- Follow Tailwind CSS v4, the color system of document site, theme generator, component library, etc. uses oklch, reference [Tailwind CSS](https://tailwindcss.com/docs/colors).

## 1.0.0 <font size=1>2025-04-07</font>

- Upgrade to 1.x version, refactor project structure.



================================================
FILE: docs/mds/guide/compatibility.md
================================================
> STDF v1.x 基于 Svelte v5 与 Tailwind CSS v4。

## Svelte

市面上能看到的浏览器版本基本都已经支持了 Svelte v5，旧版的 IE 浏览器需要 Polyfills，不过移动端没有 IE，况且微软也已经放弃了 IE，所以这里不做讨论。

## Tailwind CSS

参考 [Browser Support](https://tailwindcss.com/docs/browser-support)，STDF 组件库内已有样式都支持现代浏览器。有问题请参考 [Can I Use](https://caniuse.com)。

## 特殊情况

- Loading 与 Swiper 组件内为优化性能实现懒轮播和懒动画，使用了 [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)，如果需要此功能，请确保浏览器支持 IntersectionObserver。此处查看 [Can I Use](https://caniuse.com/intersectionobserver)。



================================================
FILE: docs/mds/guide/compatibility_en.md
================================================
> STDF v1.x based on Svelte v5 and Tailwind CSS v4.

## Svelte

Most modern browsers on the market already support Svelte v5. Old versions of Internet Explorer may require polyfills, but since mobile devices generally do not use IE and Microsoft has also abandoned IE, we won't discuss it here.

## Tailwind CSS

According to [Browser Support](https://tailwindcss.com/docs/browser-support), the styles within the STDF component library already support modern browsers. If you encounter any issues, please refer to [Can I Use](https://caniuse.com).

## Special Considerations

- The loading and swiper components implement lazy animation and lazy carousel for performance optimization using [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API). If you need this feature, please make sure your browser supports IntersectionObserver. You can check compatibility at [Can I Use](https://caniuse.com/intersectionobserver).



================================================
FILE: docs/mds/guide/contribution.md
================================================
## 介绍

感谢你使用 STDF。

以下是关于向 STDF 提交反馈或代码的指南。在向 STDF 提交 issue 或者 PR 之前，请先花几分钟时间阅读以下内容。

## Issue 规范

- 遇到问题时，请先确认这个问题是否已经在 issue 中有记录或者已被修复。
- 提 issue 时，请用简短的语言描述遇到的问题，并添加出现问题时的环境和复现步骤。

## 本地开发

在进行本地开发前，请先确保你的开发环境中安装了 [Git](https://git-scm.com) 与 [Node.js](https://nodejs.org/zh-cn) 或 [Bun](https://bun.sh) 。

调试 STDF 必须要有个工程环境，为此提供了一个简单的 Demo 工程。STDF 本身不受 Node 版本限制，Demo 使用 Vite 开发，所以请确保你的 Node.js 版本 >= 14.18+，参考 [Vite 官网](https://cn.vitejs.dev/guide/#scaffolding-your-first-vite-project)。

当你修改完成代码之后，提交 PR 之前请确保对代码进行了格式化并通过代码格式检查，可安装相关编辑器插件或通过命令行进行格式化。

推荐安装：

- [pnpm](https://pnpm.io/zh)：包管理工具，使用 Bun 无需安装。
- [Svelte for VS Code](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) 或者 [Svelte](https://plugins.jetbrains.com/plugin/12375-svelte)：Svelte 开发插件。
- [Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) 或者 [WebStorm 集成](https://www.jetbrains.com/help/webstorm/tailwind-css.html)：Tailwind CSS 开发插件。
- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) 或者 [WebStorm 集成](https://www.jetbrains.com/help/webstorm/eslint.html)：代码格式检查插件。
- [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) 或者 [WebStorm 集成](https://www.jetbrains.com/help/webstorm/prettier.html)：代码格式化插件。

按照下面的步骤操作，即可在本地快速启动 STDF Demo。

> 由于 Demo 依赖的 rollup-plugin-stdf-icon 包是本地构建的，所以请先构建一下这个包。

<!-- :::code-groups -->
<!-- pnpm -->
```sh
## 1. 克隆 STDF 仓库并进入
git clone git@github.com:any-tdf/stdf.git
cd stdf

## 2. 构建 rollup-plugin-stdf-icon 包
cd packages/rollup-plugin-stdf-icon
## 安装依赖
pnpm i
## 构建包
pnpm build

## 3. 调试 STDF
cd packages/stdf
## 安装依赖
pnpm i
## 启动 Demo
pnpm dev
```
<!-- :: -->
<!-- npm -->
```sh
## 1. 克隆 STDF 仓库并进入
git clone git@github.com:any-tdf/stdf.git
cd stdf

## 2. 构建 rollup-plugin-stdf-icon 包
cd packages/rollup-plugin-stdf-icon
## 安装依赖
npm i
## 构建包
npm run build

## 3. 调试 STDF
cd packages/stdf
## 安装依赖
npm i
## 启动 Demo
npm run dev
```
<!-- :: -->
<!-- bun -->
```sh
## 1. 克隆 STDF 仓库并进入
git clone git@github.com:any-tdf/stdf.git
cd stdf

## 2. 构建 rollup-plugin-stdf-icon 包
cd packages/rollup-plugin-stdf-icon
## 安装依赖
bun i
## 构建包
bun run build

## 3. 调试 STDF
cd packages/stdf
## 安装依赖
bun i
## 启动 Demo
bun dev
```
<!-- :: -->
<!-- yarn -->
```sh
## 1. 克隆 STDF 仓库并进入
git clone git@github.com:any-tdf/stdf.git
cd stdf

## 2. 构建 rollup-plugin-stdf-icon 包
cd packages/rollup-plugin-stdf-icon
## 安装依赖
yarn
## 构建包
yarn build

## 3. 调试 STDF
cd packages/stdf
## 安装依赖
yarn
## 启动 Demo
yarn dev
```
<!-- ::: -->

启动成功之后，可在浏览器中打开 `http://localhost:8888` 查看效果，请将浏览器的开发者工具切换为移动端模式。

可对 `packages/stdf/src/lib/components` 目录下组件源码进行修改并实时查看修改效果。注意，VS Code 与 WebStorm 都支持在调用组件时直接跳转到组件源码。

如果不想本地开发，可以选择使用 StackBlitz 在线简单调试。直接打开 [STDF Demo](https://stackblitz.com/github/any-tdf/demo-stdf) 即可开始在线调试。

## 提交 PR

如果你是第一次在 GitHub 上提 Pull Request，可以阅读下面这两篇文章来学习：

- [第一次参与开源](https://github.com/firstcontributions/first-contributions/blob/main/translations/README.zh-cn.md)
- [如何优雅地在 GitHub 上贡献代码](https://segmentfault.com/a/1190000000736629)

### 流程

- 请先 fork 一份 [STDF](https://github.com/any-tdf/stdf) 代码到自己的仓库，如果已经 fork 过，请同步主仓库的最新代码。
- 克隆你的仓库至本地。
- 修改组件源码并验证通过。
- 「可选」补充此次修改的中英文档中，文档位于 `docs/mds/components` 目录下。根据具体修改内容可能需要修改 api、FAQ、guide、version 等文档。对 version 的修改请增加 tag，具体参考 [STDF Version tag](https://github.com/any-tdf/stdf/blob/main/docs/mds/components/button/version.md?plain=1)。
- 到仓库 `packages/stdf` 目录，执行 `pnpm i` 或 `npm i` 或 `bun i` 安装依赖。
- 提交修改内容至你的仓库，然后提 Pull Request 到主仓库。
- Pull Request 会在 Review 通过后被合并到主仓库，后续发布新版。

### 注意事项

在提交 Pull Request 时，请注意：

- 保持你的 PR 足够小，一般一个 PR 只解决单个组件文件，解决单个问题或添加单个功能，以便于 Review。
- 当新增组件或者修改原有组件时，记得在 Demo 中验证通过，保证代码的稳定。
- 在 PR 中请添加合适的描述，如果有关联 Issue，请注明一下。



================================================
FILE: docs/mds/guide/contribution_en.md
================================================
## Introduction

Thank you for using STDF.

Below are guidelines for submitting feedback or code to STDF. Please take a few minutes to read through this content before submitting an issue or PR to STDF.

## Issue Guidelines

- When encountering a problem, please first confirm whether this issue has already been recorded or fixed in existing issues.
- When submitting an issue, please use concise language to describe the problem encountered, and include the environment and steps to reproduce the issue.

## Local Development

Before starting local development, please ensure your development environment has [Git](https://git-scm.com) and [Node.js](https://nodejs.org/en) or [Bun](https://bun.sh) installed.

Debugging STDF requires a project environment, for which we provide a simple Demo project. STDF itself is not restricted by Node version, but since the Demo uses Vite for development, please ensure your Node.js version is >= 14.18+, refer to [Vite official website](https://vitejs.dev/guide/#scaffolding-your-first-vite-project).

After modifying the code and before submitting a PR, please ensure the code is formatted and passes code format checks. You can install relevant editor plugins or format through the command line.

Recommended installations:

- [pnpm](https://pnpm.io): Package management tool, not needed when using Bun.
- [Svelte for VS Code](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) or [Svelte](https://plugins.jetbrains.com/plugin/12375-svelte): Svelte development plugin.
- [Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) or [WebStorm Integration](https://www.jetbrains.com/help/webstorm/tailwind-css.html): Tailwind CSS development plugin.
- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) or [WebStorm Integration](https://www.jetbrains.com/help/webstorm/eslint.html): Code format checking plugin.
- [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) or [WebStorm Integration](https://www.jetbrains.com/help/webstorm/prettier.html): Code formatting plugin.

Follow the steps below to quickly start STDF Demo locally.

> Because the rollup-plugin-stdf-icon package that the Demo depends on is built locally, please build this package first.

<!-- :::code-groups -->
<!-- pnpm -->
```sh
## 1. Clone the STDF repository
git clone git@github.com:any-tdf/stdf.git
cd stdf

## 2. Build the rollup-plugin-stdf-icon package
cd packages/rollup-plugin-stdf-icon
## Install dependencies
pnpm i
## Build package
pnpm build

## 3. Debug STDF
cd packages/stdf
## Install dependencies
pnpm i
## Start Demo
pnpm dev
```
<!-- :: -->
<!-- npm -->
```sh
## 1. Clone the STDF repository
git clone git@github.com:any-tdf/stdf.git
cd stdf

## 2. Build the rollup-plugin-stdf-icon package
cd packages/rollup-plugin-stdf-icon
## Install dependencies
npm i
## Build package
npm run build

## 3. Debug STDF
cd packages/stdf
## Install dependencies
npm i
## Start Demo
npm run dev
```
<!-- :: -->
<!-- bun -->
```sh
## 1. Clone the STDF repository
git clone git@github.com:any-tdf/stdf.git
cd stdf

## 2. Build the rollup-plugin-stdf-icon package
cd packages/rollup-plugin-stdf-icon
## Install dependencies
bun i
## Build package
bun run build

## 3. Debug STDF
cd packages/stdf
## Install dependencies
bun i
## Start Demo
bun dev
```
<!-- :: -->
<!-- yarn -->
```sh
## 1. Clone the STDF repository
git clone git@github.com:any-tdf/stdf.git
cd stdf

## 2. Build the rollup-plugin-stdf-icon package
cd packages/rollup-plugin-stdf-icon
## Install dependencies
yarn
## Build package
yarn build

## 3. Debug STDF
cd packages/stdf
## Install dependencies
yarn
## Start Demo
yarn dev
```
<!-- ::: -->

After starting successfully, you can view the effect in the browser by opening `http://localhost:8888`, please switch the developer tools of the browser to the mobile mode.

You can modify the component source code in the `packages/stdf/src/lib/components` directory and view the modification effect in real time. Note that VS Code and WebStorm both support jumping to the component source code when calling the component.

If you don't want to develop locally, you can choose to use StackBlitz for online simple debugging. Simply open [STDF Demo](https://stackblitz.com/github/any-tdf/demo-stdf) to start online debugging.

## Submit PR

If you are submitting your first Pull Request on GitHub, you can read the following two articles to learn:

- [First Contribution to Open Source](https://github.com/firstcontributions/first-contributions/blob/main/translations/README.zh-cn.md)
- [如何优雅地在 GitHub 上贡献代码](https://segmentfault.com/a/1190000000736629)

### Process

- Please first fork a [STDF](https://github.com/any-tdf/stdf) repository to your own repository, if you have already forked it, please sync the latest code from the main repository.
- Clone your repository to your local machine.
- Modify the component source code and verify it.
- (Optional) Supplement the Chinese and English documentation of this modification, the documentation is located in the `docs/mds/components` directory. Depending on the specific modification content, you may need to modify the api, FAQ, guide, version, etc. documents. For the modification of the version, please add the tag, refer to [STDF Version tag](https://github.com/any-tdf/stdf/blob/main/docs/mds/components/button/version.md?plain=1).
- Go to the `packages/stdf` directory, execute `pnpm i` or `npm i` or `bun i` to install dependencies.
- Submit the modified content to your repository, then submit a Pull Request to the main repository.
- Pull Request will be merged into the main repository after being reviewed, and a new version will be released.

### Notes

When submitting a Pull Request, please note the following:

- Keep your PR small, generally one PR solves a single component file, solves a single problem, or adds a single function, so that it is easier to review.
- When adding a new component or modifying an existing component, remember to verify it in the Demo to ensure the stability of the code.
- Please add a suitable description in the PR, if there is an associated Issue, please note it.



================================================
FILE: docs/mds/guide/faq.md
================================================
## 问：为什么没有栅格组件？

答：直接使用 CSS 的 Flexbox 特性，已经可以很方便快速地实现栅格布局，不再需要为了实现栅格布局而引入额外的组件，而且使用 Tailwind CSS 书写会非常简洁。

## 问：部分组件的 Props 需要传入 String 类型，但传入 Number 类型也完全正常使用？

答：由于组件内部这些 Props 作为 Object 的 key，严格来说应该传入 String 类型，若传入数字也会被转为 String，所以传入 Number 或者 String 类型都是可以的，开启类型检查的时候会有类型报错。虽然可以正常使用，但还是建议传入规定的类型。



================================================
FILE: docs/mds/guide/faq_en.md
================================================
## Q: Why isn't there a rasterization component?

A: Using CSS Flexbox directly can easily and quickly achieve rasterization layout. There is no need to introduce additional components to achieve rasterization layout. Moreover, using Tailwind CSS to write will be very concise.

## Q: Some components require props to be of type string, but passing number types is completely normal?

A: Because these Props inside the component are used as keys of an Object, strictly speaking, they should be passed in as String type. If a number is passed in, it will also be converted to String. Therefore, passing in Number or String types are both acceptable. When type checking is enabled, there will be a type error. Although it can still function normally, it is recommended to pass in the specified types.



================================================
FILE: docs/mds/guide/future.md
================================================
## 新增 💪

- [x] 按照 Tailwind CSS 变量规则，实现自定义主题色。
- [ ] 新增 SecurityCode-安全码组件，一般用于输入短信或邮件收到的数字校验码。
- [x] 开发一款 Vite/Rollup 插件，支持将指定目录下的所有 svg 合并为 SVG symbol。
- [x] 开发一款 VS Code 插件，支持光标悬浮显示 STDF 组件 API 等功能。
- [x] 开发一款模板脚手架，支持按照配置初始使用 STDF 的工程，初步考虑支持 Vite、SvelteKit。
- [x] 新增 NumKeyboard-数字键盘组件，一般用于输入数字。
- [x] 新增 Pagination-分页组件。
- [x] 新增 Stepper-步进器组件。
- [x] 完整支持 Svelte 5。
- [x] 完整支持 TypeScript。
- [x] 适配 Tailwind CSS v4。
- [ ] 主题配置支持圆角、间距、字体等。

---

## 优化 👏

- [ ] Skeleton 骨架屏组件增加更多的动画效果。

---

## 持续 💧

- 丰富 Loading 加载组件类型。
- 完成 Figma 设计稿，并按照 Figma 的 Variable 规则实现与组件 API 的连通。
- 根据基础组件，组合一系列业务场景组件。



================================================
FILE: docs/mds/guide/future_en.md
================================================
## New Features 💪

- [x] Implement custom theme colors according to Tailwind CSS variable rules.
- [ ] Add SecurityCode component, which is generally used for entering numeric verification codes received via SMS or email.
- [x] Develop a Vite/Rollup plugin that supports merging all SVGs in a specified directory into an SVG symbol.
- [x] Develop a VS Code plugin that supports displaying STDF component API and other functions when hovering over the cursor.
- [x] Develop a template scaffold that supports initializing STDF projects according to configuration. Initial support for Vite and SvelteKit.
- [x] Add NumKeyboard component, which is generally used for entering numbers.
- [x] Added Pagination component.
- [x] Added Stepper component.
- [x] Complete support for Svelte 5.
- [x] Complete support for TypeScript.
- [x] Adapt to Tailwind CSS v4.
- [ ] Theme configuration supports rounded corners, spacing, fonts, etc.

---

## Improvements 👏

- [ ] Increased the number of animation effects in the Skeleton screen component.

---

## Ongoing Development 💧

- Expand the types of Loading components available.
- Complete the Figma design draft and implement connectivity with component API according to Figma's Variable rules.
- Based on the basic components, combine a series of business scenario components.



================================================
FILE: docs/mds/guide/icon.md
================================================
## 背景

STDF 使用 SVG Sprites 技术使用图标，这样可以减少 HTTP 请求，提高页面性能。

STDF 的 SVG Sprites 是使用 [SVG symbol](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/symbol)，大致原理类似于 CSS 中的 Sprite 技术，将项目中的 SVG 拼接在一个文件内，通过 SVG 中的 use 元素找到对应的图标来显示。

你可以把它类比看成是一种字体，只不过这种字体是由 SVG 组成的，而且可以通过 CSS 控制颜色、大小等属性。所以如果用到比较大或者有多种颜色等比较复杂的图标，建议单独引入 SVG 文件使用，不要放在 symbol 中。

兼容性方面也完全没问题。参考 [MDN symbol](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/symbol#browser_compatibility)。

## rollup-plugin-stdf-icon

STDF 已经开发了一个 Rollup/Vite 插件，用于将项目中的 SVG 文件合并成 SVG Sprites，具体使用请参考 [rollup-plugin-stdf-icon](https://www.npmjs.com/package/rollup-plugin-stdf-icon)，由于 svg 格式的多样性，可能存在 rollup-plugin-stdf-icon 处理不准确的情况，请到 [GitHub](https://github.com/any-tdf/stdf/issues) 提 issue，注明 svg 文件的具体情况。

或使用其他 SVG Sprites 合成工具或手动合成，也可以请设计师提供设计物料时一并提供对应的 SVG Sprites。或类似 Remix Icon 这样的图标库，可以直接将选定的多个图标下载为 SVG Sprites。

## 内置说明

STDF 部分组件内使用的图标源自 [Remix Icon 图标库](https://remixicon.com)（[GitHub](https://github.com/Remix-Design/remixicon)），在此表示感谢 🙏🏻🙏🏻。

**如果使用这些组件，请确保项目的 symbol.svg 中包含了对应图标。**

具体使用如下：

| 图标名称                      | 所属组件         |
| ----------------------------- | ---------------- |
| ri-user-3-line                | Avatar           |
| ri-user-add-line              | Avatars          |
| ri-arrow-right-s-line         | Cell / NoticeBar |
| ri-checkbox-fill              | Checkbox         |
| ri-checkbox-line              | Checkbox         |
| ri-close-circle-fill          | Input            |
| ri-arrow-left-s-line          | NavBar           |
| ri-volume-down-line           | NoticeBar        |
| ri-close-line                 | NoticeBar        |
| ri-delete-back-2-line         | NumKeyboard      |
| ri-skip-down-line             | NumKeyboard      |
| ri-more-line                  | Pagination       |
| ri-more-fill                  | Pagination       |
| ri-radio-button-line          | Radio            |
| ri-checkbox-blank-circle-line | Radio            |
| ri-star-fill                  | Rate             |
| ri-image-2-fill               | Skeleton         |
| ri-movie-2-fill               | Skeleton         |
| ri-code-box-fill              | Skeleton         |
| ri-qr-code-fill               | Skeleton         |
| ri-barcode-fill               | Skeleton         |
| ri-add-line                   | Stepper          |
| ri-subtract-line              | Stepper          |
| ri-checkbox-circle-line       | Toast            |
| ri-close-circle-line          | Toast            |
| ri-error-warning-line         | Toast            |
| ri-information-line           | Toast            |

可到 `node_modules/stdf/dist/assets/svg_base/` 查看这些图标的 SVG 源文件。



================================================
FILE: docs/mds/guide/icon_en.md
================================================
## Background

STDF uses SVG Sprites technology for icons, which helps reduce HTTP requests and improve page performance.

STDF's SVG Sprites use [SVG symbol](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/symbol), which is similar to CSS Sprite technique. It combines SVG files in the project into a single file and uses the `<use>` element in SVG to display the corresponding icons.

You can think of it as a type of font, except that it is composed of SVG and can be styled using CSS properties such as color and size. Therefore, for larger or more complex icons with multiple colors, it is recommended to use individual SVG files instead of placing them in the symbol.

Compatibility is not an issue. Refer to [MDN symbol](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/symbol#browser_compatibility) for more information.

## rollup-plugin-stdf-icon

STDF has developed a Rollup/Vite plugin called rollup-plugin-stdf-icon, which combines SVG files in the project into SVG Sprites. Please refer to [rollup-plugin-stdf-icon](https://www.npmjs.com/package/rollup-plugin-stdf-icon) for specific usage. Due to the diversity of SVG formats, there may be cases where rollup-plugin-stdf-icon does not handle them accurately. In such cases, please raise an issue on [GitHub](https://github.com/any-tdf/stdf/issues) and provide details about the SVG file.

Alternatively, you can use other SVG Sprites synthesis tools or manually combine them. You can also ask the designer to provide the corresponding SVG Sprites along with the design materials.Or, for icon libraries like Remix Icon, you can directly download a selection of multiple icons as SVG Sprites.

## Built-in Icons

Some of the icons used in STDF components are sourced from [Remix Icon Library](https://remixicon.com) ([GitHub](https://github.com/Remix-Design/remixicon)). Many thanks to them! 🙏🏻🙏🏻

**If you are using these components, please make sure that the `symbol.svg` file in your project includes the corresponding icons.**

Here are the icons and their corresponding components:

| Icon Name                     | Component        |
| ----------------------------- | ---------------- |
| ri-user-3-line                | Avatar           |
| ri-user-add-line              | Avatars          |
| ri-arrow-right-s-line         | Cell / NoticeBar |
| ri-checkbox-fill              | Checkbox         |
| ri-checkbox-line              | Checkbox         |
| ri-close-circle-fill          | Input            |
| ri-arrow-left-s-line          | NavBar           |
| ri-volume-down-line           | NoticeBar        |
| ri-close-line                 | NoticeBar        |
| ri-delete-back-2-line         | NumKeyboard      |
| ri-skip-down-line             | NumKeyboard      |
| ri-more-line                  | Pagination       |
| ri-more-fill                  | Pagination       |
| ri-radio-button-line          | Radio            |
| ri-checkbox-blank-circle-line | Radio            |
| ri-star-fill                  | Rate             |
| ri-image-2-fill               | Skeleton         |
| ri-movie-2-fill               | Skeleton         |
| ri-code-box-fill              | Skeleton         |
| ri-qr-code-fill               | Skeleton         |
| ri-barcode-fill               | Skeleton         |
| ri-add-line                   | Stepper          |
| ri-subtract-line              | Stepper          |
| ri-checkbox-circle-line       | Toast            |
| ri-close-circle-line          | Toast            |
| ri-error-warning-line         | Toast            |
| ri-information-line           | Toast            |

You can find the SVG source files for these icons in `node_modules/stdf/dist/assets/svg_base/`.



================================================
FILE: docs/mds/guide/internation.md
================================================
## 配置语言包

STDF 组件使用 Svelte 的 [Context](https://svelte.dev/docs/svelte/context) 实现国际化文案配置，默认配置是中文简体。一般在应用的入口如 `App.svelte` 或 `+layout.svelte` 中配置 Context，例如：

```svelte
<!-- App.svelte/+layout.svelte -->
<script>
	import { setContext } from 'svelte'; // 引入 setContext
	import { en_US } from 'stdf/lang'; // 导入语言文件

	setContext('STDF_lang', en_US); // 设置语言
</script>
```

此组件的所有子孙组件（包含了 STDF 组件）都可以通过 `getContext('STDF_lang')` 获取到当前语言配置。更加灵活的是，甚至可以在应用内的某部分配置另一种语言。

注意 **Context 的切换不是响应式的**，一般应用中语言的切换也不需要实时响应。

目前支持以下语言：

| 语言                 | lang   |
| -------------------- | ------ |
| 阿拉伯语             | ar_EG  |
| 阿塞拜疆语           | az_AZ  |
| 保加利亚语           | bg_BG  |
| 孟加拉语（孟加拉国） | bn_BD  |
| 加泰罗尼亚语         | ca_ES  |
| 捷克语               | cs_CZ  |
| 丹麦语               | da_DK  |
| 德语                 | de_DE  |
| 希腊语               | el_GR  |
| 英语                 | en_GB  |
| 英语（美式）         | en_US  |
| 西班牙语             | es_ES  |
| 巴斯克语             | eu_ES  |
| 爱沙尼亚语           | et_EE  |
| 波斯语               | fa_IR  |
| 芬兰语               | fi_FI  |
| 法语（比利时）       | fr_BE  |
| 法语（加拿大）       | fr_CA  |
| 法语（法国）         | fr_FR  |
| 爱尔兰语             | ga_IE  |
| 加利西亚语（西班牙） | gl_ES  |
| 希伯来语             | he_IL  |
| 印地语               | hi_IN  |
| 克罗地亚语           | hr_HR  |
| 匈牙利语             | hu_HU  |
| 亚美尼亚             | hy_AM  |
| 印度尼西亚语         | id_ID  |
| 意大利语             | it_IT  |
| 冰岛语               | is_IS  |
| 日语                 | ja_JP  |
| 格鲁吉亚语           | ka_GE  |
| 高棉语               | km_KH  |
| 北库尔德语           | kmr_IQ |
| 卡纳达语             | kn_IN  |
| 哈萨克语             | kk_KZ  |
| 韩语/朝鲜语          | ko_KR  |
| 立陶宛语             | lt_LT  |
| 拉脱维亚语           | lv_LV  |
| 马其顿语             | mk_MK  |
| 马拉雅拉姆语         | ml_IN  |
| 蒙古语               | mn_MN  |
| 马来语 (马来西亚)    | ms_MY  |
| 挪威语               | nb_NO  |
| 尼泊尔语             | ne_NP  |
| 荷兰语（比利时）     | nl_BE  |
| 荷兰语               | nl_NL  |
| 波兰语               | pl_PL  |
| 葡萄牙语 (巴西)       | pt_BR  |
| 葡萄牙语             | pt_PT  |
| 罗马尼亚语           | ro_RO  |
| 俄罗斯语             | ru_RU  |
| 僧伽罗语             | si_LK  |
| 斯洛伐克语           | sk_SK  |
| 塞尔维亚语           | sr_RS  |
| 斯洛文尼亚语         | sl_SI  |
| 瑞典语               | sv_SE  |
| 泰米尔语             | ta_IN  |
| 泰语                 | th_TH  |
| 土耳其语             | tr_TR  |
| 土库曼               | tk_TK  |
| 乌尔都语 (巴基斯坦)   | ur_PK  |
| 乌克兰语             | uk_UA  |
| 越南语               | vi_VN  |
| 简体中文             | zh_CN  |
| 繁体中文（中国香港） | zh_HK  |
| 繁体中文（中国台湾） | zh_TW  |

> 多语言文件由机器翻译，如果有不准确的地方，请提交 PR 进行修正。

## 增加语言包

如果找不到你需要的语言包，欢迎你在 [中文语言包](https://github.com/any-tdf/stdf/blob/main/packages/stdf/src/lib/lang/zh_CN.ts) 或 [英文语言包](https://github.com/any-tdf/stdf/blob/main/packages/stdf/src/lib/lang/en_US.ts) 的基础上创建一个新的语言包，并发一个 Pull Request。[语言对照表](http://www.lingoes.net/en/translator/langcode.htm)

基本步骤如下：

- 请先 fork 一份 [STDF](https://github.com/any-tdf/stdf) 代码到自己的仓库，如果已经 fork 过，请同步主仓库的最新代码。
- 克隆你的仓库至本地。
- 在 `packages/stdf/src/lib/lang` 文件夹中增加语言包。
- （可选）更新文档，在 docs/mds/guide 文件夹更新 [internation.md](https://github.com/any-tdf/stdf/edit/main/docs/mds/guide/internation.md) 和 [internation_en.md](https://github.com/any-tdf/stdf/edit/main/docs/mds/guide/internation_en.md) 文件，请在语言列表中按照 lang 的字母顺序更新。
- 提交修改内容至你的仓库，然后提 Pull Request 到主仓库。
- Pull Request 会在 Review 通过后被合并到主仓库，并发布新版本至 npm。



================================================
FILE: docs/mds/guide/internation_en.md
================================================
## Configuring Language Pack

The STDF component uses Svelte's [Context](https://svelte.dev/docs/svelte/context) to implement internationalization configuration of text, with the default configuration being in Simplified Chinese. Usually, the Context is configured in the entry file `App.svelte` or `+layout.svelte`. For example:

```svelte
<!-- App.svelte/+layout.svelte -->
<script>
	import { setContext } from 'svelte'; // import setContext
	import { en_US } from 'stdf/lang'; // import language file

	setContext('STDF_lang', en_US); // set language
</script>
```

All child components of this component (including STDF components) can obtain the current language configuration using `getContext('STDF_lang')`. More flexible is that another language can be configured in some parts of the application.

Note that **Context switching is not reactive**, and language switching in most applications does not require real-time response.

Currently supported languages:

| Language                              | lang   |
| ------------------------------------- | ------ |
| Arabic                                | ar_EG  |
| Azerbaijani                           | az_AZ  |
| Bulgarian                             | bg_BG  |
| Bengali (Bangladesh)                  | bn_BD  |
| Catalan                               | ca_ES  |
| Czech                                 | cs_CZ  |
| Danish                                | da_DK  |
| German                                | de_DE  |
| Greek                                 | el_GR  |
| English                               | en_GB  |
| English (US)                          | en_US  |
| Spanish                               | es_ES  |
| Basque                                | eu_ES  |
| Estonian                              | et_EE  |
| Persian                               | fa_IR  |
| Finnish                               | fi_FI  |
| French (Belgium)                      | fr_BE  |
| French (Canada)                       | fr_CA  |
| French (France)                       | fr_FR  |
| Irish                                 | ga_IE  |
| Galician (Spain)                      | gl_ES  |
| Hebrew                                | he_IL  |
| Hindi                                 | hi_IN  |
| Croatian                              | hr_HR  |
| Hungarian                             | hu_HU  |
| Armenian                              | hy_AM  |
| Indonesian                            | id_ID  |
| Italian                               | it_IT  |
| Icelandic                             | is_IS  |
| Japanese                              | ja_JP  |
| Georgian                              | ka_GE  |
| Khmer                                 | km_KH  |
| Kurdish (Northern)                    | kmr_IQ |
| Kannada                               | kn_IN  |
| Kazakh                                | kk_KZ  |
| Korean                                | ko_KR  |
| Lithuanian                            | lt_LT  |
| Latvian                               | lv_LV  |
| Macedonian                            | mk_MK  |
| Malayalam                             | ml_IN  |
| Mongolian                             | mn_MN  |
| Malay (Malaysia)                      | ms_MY  |
| Norwegian                             | nb_NO  |
| Nepali                                | ne_NP  |
| Dutch (Belgium)                       | nl_BE  |
| Dutch                                 | nl_NL  |
| Polish                                | pl_PL  |
| Portuguese (Brazil)                   | pt_BR  |
| Portuguese                            | pt_PT  |
| Romanian                              | ro_RO  |
| Russian                               | ru_RU  |
| Sinhalese                             | si_LK  |
| Slovak                                | sk_SK  |
| Serbian                               | sr_RS  |
| Slovenian                             | sl_SI  |
| Swedish                               | sv_SE  |
| Tamil                                 | ta_IN  |
| Thai                                  | th_TH  |
| Turkish                               | tr_TR  |
| Turkmen                               | tk_TK  |
| Urdu (Pakistan)                       | ur_PK  |
| Ukrainian                             | uk_UA  |
| Vietnamese                            | vi_VN  |
| Simplified Chinese                    | zh_CN  |
| Traditional Chinese (China Hong Kong) | zh_HK  |
| Traditional Chinese (China Taiwan)    | zh_TW  |

> The multilingual files are translated by machine. If there are any inaccuracies, please submit a PR for correction.

## Adding a Language Pack

If you cannot find the language pack you need, you are welcome to create a new language pack based on the [Chinese language pack](https://github.com/any-tdf/stdf/blob/main/packages/stdf/src/lib/lang/zh_CN.ts) or [English language pack](https://github.com/any-tdf/stdf/blob/main/packages/stdf/src/lib/lang/en_US.ts) and submit it as a Pull Request. [Language code table](http://www.lingoes.net/en/translator/langcode.htm)

The basic steps are as follows:

- Please fork the [STDF](https://github.com/any-tdf/stdf) code to your own repository. If you have already forked it, please sync the latest code from the main repository.
- Clone your repository to your local machine.
- Add language packs in the `packages/stdf/src/lib/lang` folder.
- (Optional) Update the documentation. Update the [internation.md](https://github.com/any-tdf/stdf/edit/main/docs/mds/guide/internation.md) and [internation_en.md](https://github.com/any-tdf/stdf/edit/main/docs/mds/guide/internation_en.md) files in the docs/mds/guide folder. Please update them in alphabetical order according to the lang list.
- Commit the modifications to your repository and then submit a Pull Request to the main repository.
- Once the Pull Request is approved during the review process, it will be merged into the main repository and a new version will be released on npm.



================================================
FILE: docs/mds/guide/milestone.md
================================================
## 2025-04-07

v1 版本发布，完整支持 Svelte v5、Tailwind CSS v4 与 TypeScript。

## 2023-11-03

支持多主题配置 @0.4.0。

## 2023-08-24

完成 STDF 配套的模板脚手架 [create-stdf](https://www.npmjs.com/package/create-stdf)，Vite/Rollup 插件 [rollup-plugin-stdf-icon](https://www.npmjs.com/package/rollup-plugin-stdf-icon)，VS Code 插件 [STDF for VS Code](https://marketplace.visualstudio.com/items?itemName=STDF.stdf-vscode-extension)。

## 2023-07-23

适配 Svelte 4 也兼容 Svelte 3（v0.2.0）。

## 2023-06-16

入选阮一峰老师的[科技爱好者周刊 259 期](https://www.ruanyifeng.com/blog/2023/06/weekly-issue-259.html)。

## 2023-05-03

将组件源码与文档分开，避免 node_modules 体积过大。

## 2023-04-27

第一次 commit。

组件库开发到我认为能用的程度，正式开源。期间工作量包括组件库 UI 设计（后续补充 Figma 源文件），组件库逻辑开发，源码中英双语注释，搭建中英文 Demo 工程，调试各种 API，撰写组件库中英文档，搭建文档站点，设计 LOGO，首页 3D 建模，部署文档站点，购买域名、CDN...

## 2022-07-06

新建文件夹。

早在 2021 年开发 [simple-cloud-music](https://github.com/dufu1991/simple-cloud-music) 的时候就发现写 Svelte 的体验非常好，但是市面上好像没有一款针对移动端的 UI 组件库，就开始萌生开发一个移动端的 Svelte UI 组件库的想法。再后来遇到了 Tailwind CSS，体验过后被它优秀的开发体验深深吸引，于是决定使用 Svelte 结合 Tailwind 开发一个移动端的 UI 组件库。



================================================
FILE: docs/mds/guide/milestone_en.md
================================================
## 2025-04-07

v1 version released, full support for Svelte v5, Tailwind CSS v4, and TypeScript.

## 2023-11-03

Support multi-theme configuration @0.4.0.

## 2023-08-24

Completed the template scaffolding tool [create-stdf](https://www.npmjs.com/package/create-stdf), Vite/Rollup plugin [rollup-plugin-stdf-icon](https://www.npmjs.com/package/rollup-plugin-stdf-icon), and VS Code plugin [STDF for VS Code](https://marketplace.visualstudio.com/items?itemName=STDF.stdf-vscode-extension) for STDF.

## 2023-07-23

Adapted for Svelte 4 while remaining compatible with Svelte 3 (v0.2.0).

## 2023-06-16

Featured in Ruan Yifeng's [weekly-issue No. 259](https://www.ruanyifeng.com/blog/2023/06/weekly-issue-259.html).

## 2023-05-03

Separate component source code and documentation to avoid large node_modules size.

## 2023-04-27

First commit.

The component library has been developed to a usable level and is now officially open source. During this period, the workload included UI design of the component library (Figma source files will be added later), logic development of the component library, bilingual comments in the source code, building demo projects in both Chinese and English, debugging various APIs, writing documentation for the component library in both Chinese and English, setting up a documentation website, designing a logo, creating a 3D model for the homepage, deploying the documentation website, purchasing domain names and CDN...

## 2022-07-06

New folder created.

As early as 2021 when developing [simple-cloud-music](https://github.com/dufu1991/simple-cloud-music), I found that writing Svelte was very enjoyable but there seemed to be no mobile-oriented UI component libraries on the market. So I came up with an idea to develop a mobile-oriented Svelte UI component library. Later on I discovered Tailwind CSS which impressed me deeply with its excellent development experience. Therefore I decided to use Svelte combined with Tailwind to develop a mobile-oriented UI component library.



================================================
FILE: docs/mds/guide/quickStart.md
================================================

> Tip：所有代码或命令可以双击选定词，三击选定行。

## 1. [create-stdf](https://www.npmjs.com/package/create-stdf)（推荐）

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm create stdf
```
<!-- :: -->
<!-- npm -->
```sh
npm create stdf
# 或
npm init stdf
# 或
npx create-stdf
```
<!-- :: -->
<!-- bun -->
```sh
bun create stdf
```
<!-- :: -->
<!-- yarn -->
```sh
yarn create stdf
```
<!-- ::: -->

## 2. 自行搭建

2.1 使用 [Svelte CLI](https://svelte.dev/docs/cli/sv-create) 创建工程

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm dlx sv create
```
<!-- :: -->
<!-- npm -->
```sh
npx sv create
```
<!-- :: -->
<!-- bun -->
```sh
bunx sv create
```
<!-- :: -->
<!-- yarn -->
```sh
yarn dlx sv create
```
<!-- ::: -->

2.2 安装 Tailwind CSS 与 Vite 插件。

参考 [Tailwind CSS 文档](https://tailwindcss.com/docs/guides/vite#svelte) 配置 Tailwind CSS。

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm i tailwindcss @tailwindcss/vite -D
```
<!-- :: -->
<!-- npm -->
```sh
npm i tailwindcss @tailwindcss/vite -D
```
<!-- :: -->
<!-- bun -->
```sh
bun add tailwindcss @tailwindcss/vite -D
```
<!-- :: -->
<!-- yarn -->
```sh
yarn add tailwindcss @tailwindcss/vite -D
```
<!-- ::: -->

2.3 在项目的入口 CSS 文件中引入 Tailwind CSS，设置暗黑模式，添加初始颜色变量，**使用 `@source` 指令指定 Tailwind 自动检测 STDF 组件**。

以下为 STDF 默认主题色，请根据自己的需要进行修改。可参考 [STDF 指南 - 色彩](/guide/color)。

```css
/* app.css */
@import 'tailwindcss';
@custom-variant dark (&:where(.dark, .dark *));
@theme {
	/* 主题色 */
	--color-primary-50: oklch(0.979 0.01 267.36);
	--color-primary-100: oklch(0.95 0.024 270.343);
	--color-primary-200: oklch(0.847 0.074 271.188);
	--color-primary-300: oklch(0.741 0.13 272.232);
	--color-primary-400: oklch(0.634 0.193 271.595);
	--color-primary-500: oklch(0.536 0.252 268.66);
	--color-primary: oklch(0.467 0.296 264.886);
	--color-primary-700: oklch(0.397 0.26 264.877);
	--color-primary-800: oklch(0.331 0.221 264.833);
	--color-primary-900: oklch(0.26 0.178 264.428);
	--color-primary-950: oklch(0.192 0.13 266.64);

	--color-dark-50: oklch(0.995 0.012 101.474);
	--color-dark-100: oklch(0.986 0.025 97.107);
	--color-dark-200: oklch(0.965 0.059 95.884);
	--color-dark-300: oklch(0.938 0.089 92.952);
	--color-dark-400: oklch(0.91 0.114 89.711);
	--color-dark-500: oklch(0.88 0.136 86.375);
	--color-dark: oklch(0.845 0.153 80.597);
	--color-dark-700: oklch(0.71 0.137 75.734);
	--color-dark-800: oklch(0.58 0.118 70.166);
	--color-dark-900: oklch(0.449 0.097 65.209);
	--color-dark-950: oklch(0.321 0.074 62.379);

	--color-primaryBlack: oklch(0.116 0.054 267.087);
	--color-primaryWhite: oklch(0.961 0.001 286.375);
	--color-darkBlack: oklch(0.183 0.035 86.634);
	--color-darkWhite: oklch(0.962 0.001 17.178);

	/* 功能色 */
	--color-success: oklch(0.704 0.142 167.084);
	--color-warning: oklch(0.558 0.154 47.186);
	--color-error: oklch(0.564 0.223 28.46);
	--color-info: oklch(0.482 0.14 261.518);

	/* 扩展色 */
	--color-extend0: oklch(0.703 0.149 235.059);
	--color-Twitter: oklch(0.703 0.149 235.059);
	--color-extend1: oklch(0.702 0.194 38.137);
	--color-Svelte: oklch(0.702 0.194 38.137);
	--color-extend2: oklch(0.482 0.107 161.212);
	--color-Starbucks: oklch(0.482 0.107 161.212);

	/* 中性色 */
	--color-black: oklch(0 0 0);
	--color-white: oklch(1 0 0);
	--color-gray-50: oklch(0.961 0 0);
	--color-gray-100: oklch(0.925 0 0);
	--color-gray-200: oklch(0.845 0 0);
	--color-gray-300: oklch(0.767 0 0);
	--color-gray-400: oklch(0.683 0 0);
	--color-gray-500: oklch(0.6 0 0);
	--color-gray-600: oklch(0.51 0 0);
	--color-gray-700: oklch(0.42 0 0);
	--color-gray-800: oklch(0.321 0 0);
	--color-gray-900: oklch(0.218 0 0);
	--color-gray-950: oklch(0.159 0 0);
	--color-transparent: transparent;
}
@source "../node_modules/stdf/**/*.svelte";
```

2.4 在 Svelte 文件中引入并使用。

```svelte
<script lang="ts">
	import { Button } from 'stdf';
</script>

<Button>点击我</Button>
```

2.5 启动项目。

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm dev
```
<!-- :: -->
<!-- npm -->
```sh
npm run dev
```
<!-- :: -->
<!-- bun -->
```sh
bun dev
```
<!-- :: -->
<!-- yarn -->
```sh
yarn dev
```
<!-- ::: -->


================================================
FILE: docs/mds/guide/quickStart_en.md
================================================

> Tip: All code or commands can be double-clicked to select the word, three clicks to select the line.

## 1. [create-stdf](https://www.npmjs.com/package/create-stdf) (Recommended)

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm create stdf
```
<!-- :: -->
<!-- npm -->
```sh
npm create stdf
# or
npm init stdf
# or
npx create-stdf
```
<!-- :: -->
<!-- bun -->
```sh
bun create stdf
```
<!-- :: -->
<!-- yarn -->
```sh
yarn create stdf
```
<!-- ::: -->

## 2. Self-built

2.1 Use the [Svelte CLI](https://svelte.dev/docs/cli/sv-create) to create the project.

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm dlx sv create
```
<!-- :: -->
<!-- npm -->
```sh
npx sv create
```
<!-- :: -->
<!-- bun -->
```sh
bunx sv create
```
<!-- :: -->
<!-- yarn -->
```sh
yarn dlx sv create
```
<!-- ::: -->

2.2 Install Tailwind CSS and Vite plugins.

Refer to the [Tailwind CSS documentation](https://tailwindcss.com/docs/guides/vite#svelte) to configure Tailwind CSS.

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm i tailwindcss @tailwindcss/vite -D
```
<!-- :: -->
<!-- npm -->
```sh
npm i tailwindcss @tailwindcss/vite -D
```
<!-- :: -->
<!-- bun -->
```sh
bun i tailwindcss @tailwindcss/vite -D
```
<!-- :: -->
<!-- yarn -->
```sh
yarn add tailwindcss @tailwindcss/vite -D
```
<!-- ::: -->

2.3 In the project's entry CSS file, import Tailwind CSS, set the dark mode, add the initial color variables, and **use the `@source` directive to specify that Tailwind CSS automatically detects STDF components**.

The following are the default theme colors of STDF, please modify them according to your needs. For more information, refer to [STDF Guide - Color](/guide/color).

```css
/* app.css */
@import 'tailwindcss';
@custom-variant dark (&:where(.dark, .dark *));
@theme {
	/* Theme Colors */
	--color-primary-50: oklch(0.979 0.01 267.36);
	--color-primary-100: oklch(0.95 0.024 270.343);
	--color-primary-200: oklch(0.847 0.074 271.188);
	--color-primary-300: oklch(0.741 0.13 272.232);
	--color-primary-400: oklch(0.634 0.193 271.595);
	--color-primary-500: oklch(0.536 0.252 268.66);
	--color-primary: oklch(0.467 0.296 264.886);
	--color-primary-700: oklch(0.397 0.26 264.877);
	--color-primary-800: oklch(0.331 0.221 264.833);
	--color-primary-900: oklch(0.26 0.178 264.428);
	--color-primary-950: oklch(0.192 0.13 266.64);

	--color-dark-50: oklch(0.995 0.012 101.474);
	--color-dark-100: oklch(0.986 0.025 97.107);
	--color-dark-200: oklch(0.965 0.059 95.884);
	--color-dark-300: oklch(0.938 0.089 92.952);
	--color-dark-400: oklch(0.91 0.114 89.711);
	--color-dark-500: oklch(0.88 0.136 86.375);
	--color-dark: oklch(0.845 0.153 80.597);
	--color-dark-700: oklch(0.71 0.137 75.734);
	--color-dark-800: oklch(0.58 0.118 70.166);
	--color-dark-900: oklch(0.449 0.097 65.209);
	--color-dark-950: oklch(0.321 0.074 62.379);

	--color-primaryBlack: oklch(0.116 0.054 267.087);
	--color-primaryWhite: oklch(0.961 0.001 286.375);
	--color-darkBlack: oklch(0.183 0.035 86.634);
	--color-darkWhite: oklch(0.962 0.001 17.178);

	/* Functional Colors */
	--color-success: oklch(0.704 0.142 167.084);
	--color-warning: oklch(0.558 0.154 47.186);
	--color-error: oklch(0.564 0.223 28.46);
	--color-info: oklch(0.482 0.14 261.518);

	/* Extended Colors */
	--color-extend0: oklch(0.703 0.149 235.059);
	--color-Twitter: oklch(0.703 0.149 235.059);
	--color-extend1: oklch(0.702 0.194 38.137);
	--color-Svelte: oklch(0.702 0.194 38.137);
	--color-extend2: oklch(0.482 0.107 161.212);
	--color-Starbucks: oklch(0.482 0.107 161.212);

	/* Neutral Colors */
	--color-black: oklch(0 0 0);
	--color-white: oklch(1 0 0);
	--color-gray-50: oklch(0.961 0 0);
	--color-gray-100: oklch(0.925 0 0);
	--color-gray-200: oklch(0.845 0 0);
	--color-gray-300: oklch(0.767 0 0);
	--color-gray-400: oklch(0.683 0 0);
	--color-gray-500: oklch(0.6 0 0);
	--color-gray-600: oklch(0.51 0 0);
	--color-gray-700: oklch(0.42 0 0);
	--color-gray-800: oklch(0.321 0 0);
	--color-gray-900: oklch(0.218 0 0);
	--color-gray-950: oklch(0.159 0 0);
	--color-transparent: transparent;
}
@source "../node_modules/stdf/**/*.svelte";
```

2.4 Import and use components in Svelte files.

```svelte
<script lang="ts">
	import { Button } from 'stdf';
</script>

<Button>Click me</Button>
```

2.5 Start the project.

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm dev
```
<!-- :: -->
<!-- npm -->
```sh
npm run dev
```
<!-- :: -->
<!-- bun -->
```sh
bun dev
```
<!-- :: -->
<!-- yarn -->
```sh
yarn dev
```
<!-- ::: -->


================================================
FILE: docs/mds/guide/theme.md
================================================
## 亮暗模式

### 配置

使用 Tailwind CSS 的暗模式配置，请在项目入口 CSS 文件中做如下 `@custom-variant` 配置，参考 [Dark Mode](https://tailwindcss.com/docs/dark-mode)。

```css
@custom-variant dark (&:where(.dark, .dark *))
```

### 切换

STDF 将切换亮暗模式的方法置于 STDF 的 NPM 包中，本质上是直接给 `html` 标签添加或删除 `dark` 类名。

```javascript
// 引入 darkMode，传入 false 切换为亮模式，不传参或传入 true 切换为暗模式。
import { darkMode } from 'stdf/theme';

// 切换为亮模式
darkMode(false);

// 切换为暗模式
darkMode();
```

## 多主题模式

### 介绍

STDF 支持多主题切换，主题暂支持切换[颜色系统](/guide/color)，后续考虑字体、间距、文字大小等配置也可跟随主题切换。本质原理是将一些属性设置为 CSS 变量，通过修改这些变量实现主题切换。

### 配置

请参考主题生成器生成的主题配置格式配置好主题，主题配置须包含 name 与 color 两个属性，name 为主题名称，color 为此主题搭配的颜色。

> 可到<a href="/guide/generator" target="_blank">主题生成器</a>快速配置颜色系统并生成配置文件。

默认主题配置如下：

```javascript
{
	name: 'STDF',
	color: {
		primary: {
			50: 'oklch(0.979 0.01 267.36)', // #F5F8FF hsl(222, 100%, 98%)
			100: 'oklch(0.95 0.024 270.343)', // #E8EEFF hsl(224, 100%, 96%)
			200: 'oklch(0.847 0.074 271.188)', // #BBCBFE hsl(226, 97%, 87%)
			300: 'oklch(0.741 0.13 272.232)', // #8FA5FD hsl(228, 97%, 78%)
			400: 'oklch(0.634 0.193 271.595)', // #637CFD hsl(230, 98%, 69%)
			500: 'oklch(0.536 0.252 268.66)', // #3751FC hsl(232, 97%, 60%)
			default: 'oklch(0.467 0.296 264.886)', // #0B24FB hsl(234, 97%, 51%)
			700: 'oklch(0.397 0.26 264.877)', // #0714CF hsl(236, 94%, 42%)
			800: 'oklch(0.331 0.221 264.833)', // #0409A4 hsl(238, 95%, 33%)
			900: 'oklch(0.26 0.178 264.428)', // #010178 hsl(240, 98%, 24%)
			950: 'oklch(0.192 0.13 266.64)' // #03004D hsl(242, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.995 0.012 101.474)', // #FFFEF5 hsl(54, 100%, 98%)
			100: 'oklch(0.986 0.025 97.107)', // #FFFBE8 hsl(50, 100%, 96%)
			200: 'oklch(0.965 0.059 95.884)', // #FFF4C7 hsl(48, 100%, 89%)
			300: 'oklch(0.938 0.089 92.952)', // #FFEAA6 hsl(46, 100%, 83%)
			400: 'oklch(0.91 0.114 89.711)', // #FFDE85 hsl(44, 100%, 76%)
			500: 'oklch(0.88 0.136 86.375)', // #FFD164 hsl(42, 100%, 70%)
			default: 'oklch(0.845 0.153 80.597)', // #FFC043 hsl(40, 100%, 63%)
			700: 'oklch(0.71 0.137 75.734)', // #D29429 hsl(38, 67%, 49%)
			800: 'oklch(0.58 0.118 70.166)', // #A66C16 hsl(36, 77%, 37%)
			900: 'oklch(0.449 0.097 65.209)', // #794808 hsl(34, 88%, 25%)
			950: 'oklch(0.321 0.074 62.379)' // #4D2900 hsl(32, 100%, 15%)
		},
		primaryBlack: 'oklch(0.116 0.054 267.087)', // #010319 hsl(234, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(234, 5%, 95%)
		darkBlack: 'oklch(0.183 0.035 86.634)', // #191101 hsl(40, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(40, 5%, 95%)
		functional: {
			success: 'oklch(0.704 0.142 167.084)', // #11bb8d hsl(164, 83%, 40%)
			warning: 'oklch(0.558 0.154 47.186)', // #b95000 hsl(26, 100%, 36%)
			error: 'oklch(0.564 0.223 28.46)', // #da1414 hsl(0, 83%, 47%)
			info: 'oklch(0.482 0.14 261.518)' // #2e5aac hsl(219, 58%, 43%)
		},
		extend: [
			{
				color: 'oklch(0.703 0.149 235.059)', // #00acee hsl(197, 100%, 47%)
				alias: 'Twitter'
			},
			{
				color: 'oklch(0.702 0.194 38.137)', // #ff6937 hsl(15, 100%, 61%)
				alias: 'Svelte'
			},
			{
				color: 'oklch(0.482 0.107 161.212)', // #00704a hsl(160, 100%, 22%)
				alias: 'Starbucks'
			}
		]
	}
}
```

Tailwind v4 推荐使用 oklch 颜色模式，参考 [Using CSS variables](https://tailwindcss.com/docs/customizing-colors#using-css-variables)。

按照颜色系统的配色，加上基础的黑、白、灰、透明，默认配色在入口 CSS 文件中至少包含以下内容：

```css
@theme {
	/* 主题色 */
	--color-primary-50: oklch(0.979 0.01 267.36);
	--color-primary-100: oklch(0.95 0.024 270.343);
	--color-primary-200: oklch(0.847 0.074 271.188);
	--color-primary-300: oklch(0.741 0.13 272.232);
	--color-primary-400: oklch(0.634 0.193 271.595);
	--color-primary-500: oklch(0.536 0.252 268.66);
	--color-primary: oklch(0.467 0.296 264.886);
	--color-primary-700: oklch(0.397 0.26 264.877);
	--color-primary-800: oklch(0.331 0.221 264.833);
	--color-primary-900: oklch(0.26 0.178 264.428);
	--color-primary-950: oklch(0.192 0.13 266.64);

	--color-dark-50: oklch(0.995 0.012 101.474);
	--color-dark-100: oklch(0.986 0.025 97.107);
	--color-dark-200: oklch(0.965 0.059 95.884);
	--color-dark-300: oklch(0.938 0.089 92.952);
	--color-dark-400: oklch(0.91 0.114 89.711);
	--color-dark-500: oklch(0.88 0.136 86.375);
	--color-dark: oklch(0.845 0.153 80.597);
	--color-dark-700: oklch(0.71 0.137 75.734);
	--color-dark-800: oklch(0.58 0.118 70.166);
	--color-dark-900: oklch(0.449 0.097 65.209);
	--color-dark-950: oklch(0.321 0.074 62.379);

	--color-primaryBlack: oklch(0.116 0.054 267.087);
	--color-primaryWhite: oklch(0.961 0.001 286.375);
	--color-darkBlack: oklch(0.183 0.035 86.634);
	--color-darkWhite: oklch(0.962 0.001 17.178);

	/* 功能色 */
	--color-success: oklch(0.704 0.142 167.084);
	--color-warning: oklch(0.558 0.154 47.186);
	--color-error: oklch(0.564 0.223 28.46);
	--color-info: oklch(0.482 0.14 261.518);

	/* 扩展色 */
	--color-extend0: oklch(0.703 0.149 235.059);
	--color-Twitter: oklch(0.703 0.149 235.059);
	--color-extend1: oklch(0.702 0.194 38.137);
	--color-Svelte: oklch(0.702 0.194 38.137);
	--color-extend2: oklch(0.482 0.107 161.212);
	--color-Starbucks: oklch(0.482 0.107 161.212);

 	/* 中性色 */
	--color-black: oklch(0 0 0);
	--color-white: oklch(1 0 0);
	--color-gray-50: oklch(0.961 0 0);
	--color-gray-100: oklch(0.925 0 0);
	--color-gray-200: oklch(0.845 0 0);
	--color-gray-300: oklch(0.767 0 0);
	--color-gray-400: oklch(0.683 0 0);
	--color-gray-500: oklch(0.6 0 0);
	--color-gray-600: oklch(0.51 0 0);
	--color-gray-700: oklch(0.42 0 0);
	--color-gray-800: oklch(0.321 0 0);
	--color-gray-900: oklch(0.218 0 0);
	--color-gray-950: oklch(0.159 0 0);
	--color-transparent: transparent;
	/* ... */
}
```

### 切换

引入 NPM 包中的 switchTheme 方法切换主题，传入主题文件对象即可。

```javascript
// 引入 STDF 主题配置文件和切换主题方法（stdf 的 NPM 包中包含一个 stdf 主题配置文件）
import { stdfTheme, switchTheme } from 'stdf/theme';
// 引入自定义主题配置文件，假定 customTheme 为自定义主题配置文件
import customTheme from './customTheme';

// 切换主题为 STDF 主题
switchTheme(stdfTheme);

// 切换主题为自定义主题
switchTheme(customTheme);
```

详细使用方式可参考 [STDF Demo](https://github.com/any-tdf/demo-stdf)。

## 总结

### 亮暗模式

直接使用 STDF 的 NPM 包中的 darkMode 方法即可。

### 多主题模式

1. 在入口 CSS 文件内配置默认主题 CSS 变量，如 `src/app.css`。
2. 到主题生成器中配置颜色系统并生成主题配置文件。
3. 在需要切换主题的地方引入主题配置文件和切换主题方法，调用切换主题方法。

> 当然，如果你不需要切换主题，只需要配置初始 CSS 变量即可。



================================================
FILE: docs/mds/guide/theme_en.md
================================================
## Light and dark modes

### Configuration

Use the Tailwind CSS dark mode configuration, please make the following `@custom-variant` configuration in the project entry CSS file, reference [Dark Mode](https://tailwindcss.com/docs/dark-mode).

```css
@custom-variant dark (&:where(.dark, .dark *))
```

### Switching

STDF supports switching between multiple themes. The method of switching themes is placed in the NPM package of STDF, essentially adding or removing the `dark` class name to the `html` tag.

```javascript
// Import darkMode, pass false to switch to light mode, or not pass parameters or pass true to switch to dark mode.
import { darkMode } from 'stdf/theme';

// Switch to light mode
darkMode(false);

// Switch to dark mode
darkMode();
```

## Multiple theme mode

### Introduction

STDF supports switching between multiple themes, currently supports switching [color system](/guide/color), and will consider switching font, spacing, text size, etc. in the future. The essential principle is to set some attributes as CSS variables, and switch the theme by modifying these variables.

### Configuration

Please refer to the theme configuration format generated by the theme generator for the theme configuration, the theme configuration must contain the name and color attributes, name is the theme name, and color is the color system configuration.

> Please refer to [Theme Generator](/guide/generator) for the theme configuration format.

Default theme configuration:

```javascript
{
	name: 'STDF',
	color: {
		primary: {
			50: 'oklch(0.979 0.01 267.36)', // #F5F8FF hsl(222, 100%, 98%)
			100: 'oklch(0.95 0.024 270.343)', // #E8EEFF hsl(224, 100%, 96%)
			200: 'oklch(0.847 0.074 271.188)', // #BBCBFE hsl(226, 97%, 87%)
			300: 'oklch(0.741 0.13 272.232)', // #8FA5FD hsl(228, 97%, 78%)
			400: 'oklch(0.634 0.193 271.595)', // #637CFD hsl(230, 98%, 69%)
			500: 'oklch(0.536 0.252 268.66)', // #3751FC hsl(232, 97%, 60%)
			default: 'oklch(0.467 0.296 264.886)', // #0B24FB hsl(234, 97%, 51%)
			700: 'oklch(0.397 0.26 264.877)', // #0714CF hsl(236, 94%, 42%)
			800: 'oklch(0.331 0.221 264.833)', // #0409A4 hsl(238, 95%, 33%)
			900: 'oklch(0.26 0.178 264.428)', // #010178 hsl(240, 98%, 24%)
			950: 'oklch(0.192 0.13 266.64)' // #03004D hsl(242, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.995 0.012 101.474)', // #FFFEF5 hsl(54, 100%, 98%)
			100: 'oklch(0.986 0.025 97.107)', // #FFFBE8 hsl(50, 100%, 96%)
			200: 'oklch(0.965 0.059 95.884)', // #FFF4C7 hsl(48, 100%, 89%)
			300: 'oklch(0.938 0.089 92.952)', // #FFEAA6 hsl(46, 100%, 83%)
			400: 'oklch(0.91 0.114 89.711)', // #FFDE85 hsl(44, 100%, 76%)
			500: 'oklch(0.88 0.136 86.375)', // #FFD164 hsl(42, 100%, 70%)
			default: 'oklch(0.845 0.153 80.597)', // #FFC043 hsl(40, 100%, 63%)
			700: 'oklch(0.71 0.137 75.734)', // #D29429 hsl(38, 67%, 49%)
			800: 'oklch(0.58 0.118 70.166)', // #A3731F hsl(36, 80%, 45%)
			900: 'oklch(0.45 0.094 64.59)', // #744F14 hsl(34, 80%, 39%)
			950: 'oklch(0.32 0.069 59.014)' // #46300A hsl(32, 80%, 32%)
		},
		primaryBlack: 'oklch(0.116 0.054 267.087)', // #010319 hsl(234, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(234, 5%, 95%)
		darkBlack: 'oklch(0.183 0.035 86.634)', // #191101 hsl(40, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(40, 5%, 95%)
		functional: {
			success: 'oklch(0.704 0.142 167.084)', // #11bb8d hsl(164, 83%, 40%)
			warning: 'oklch(0.558 0.154 47.186)', // #b95000 hsl(26, 100%, 36%)
			error: 'oklch(0.564 0.223 28.46)', // #da1414 hsl(0, 83%, 47%)
			info: 'oklch(0.482 0.14 261.518)' // #2e5aac hsl(219, 58%, 43%)
		},
		extend: [
			{
				color: 'oklch(0.703 0.149 235.059)', // #00acee hsl(197, 100%, 47%)
				alias: 'Twitter'
			},
			{
				color: 'oklch(0.702 0.194 38.137)', // #ff6937 hsl(15, 100%, 61%)
				alias: 'Svelte'
			},
			{
				color: 'oklch(0.482 0.107 161.212)', // #00704a hsl(160, 100%, 22%)
				alias: 'Starbucks'
			}
		]
	}
}
```

Tailwind v4 recommends using the oklch color mode, reference [Using CSS variables](https://tailwindcss.com/docs/customizing-colors#using-css-variables).

According to the color system configuration, plus the basic black, white, gray, and transparent, the default color system configuration in the entry CSS file must contain the following content:

```css
@theme {
	/* Theme color */
	--color-primary-50: oklch(0.979 0.01 267.36);
	--color-primary-100: oklch(0.95 0.024 270.343);
	--color-primary-200: oklch(0.847 0.074 271.188);
	--color-primary-300: oklch(0.741 0.13 272.232);
	--color-primary-400: oklch(0.634 0.193 271.595);
	--color-primary-500: oklch(0.536 0.252 268.66);
	--color-primary: oklch(0.467 0.296 264.886);
	--color-primary-700: oklch(0.397 0.26 264.877);
	--color-primary-800: oklch(0.331 0.221 264.833);
	--color-primary-900: oklch(0.26 0.178 264.428);
	--color-primary-950: oklch(0.192 0.13 266.64);

	--color-dark-50: oklch(0.995 0.012 101.474);
	--color-dark-100: oklch(0.986 0.025 97.107);
	--color-dark-200: oklch(0.965 0.059 95.884);
	--color-dark-300: oklch(0.938 0.089 92.952);
	--color-dark-400: oklch(0.91 0.114 89.711);
	--color-dark-500: oklch(0.88 0.136 86.375);
	--color-dark: oklch(0.845 0.153 80.597);
	--color-dark-700: oklch(0.71 0.137 75.734);
	--color-dark-800: oklch(0.58 0.118 70.166);
	--color-dark-900: oklch(0.449 0.097 65.209);
	--color-dark-950: oklch(0.321 0.074 62.379);

	--color-primaryBlack: oklch(0.116 0.054 267.087);
	--color-primaryWhite: oklch(0.961 0.001 286.375);
	--color-darkBlack: oklch(0.183 0.035 86.634);
	--color-darkWhite: oklch(0.962 0.001 17.178);

	/* Functional color */
	--color-success: oklch(0.704 0.142 167.084);
	--color-warning: oklch(0.558 0.154 47.186);
	--color-error: oklch(0.564 0.223 28.46);
	--color-info: oklch(0.482 0.14 261.518);

	/* Extended color */
	--color-extend0: oklch(0.703 0.149 235.059);
	--color-Twitter: oklch(0.703 0.149 235.059);
	--color-extend1: oklch(0.702 0.194 38.137);
	--color-Svelte: oklch(0.702 0.194 38.137);
	--color-extend2: oklch(0.482 0.107 161.212);
	--color-Starbucks: oklch(0.482 0.107 161.212);

	/* Neutral color */
	--color-black: oklch(0 0 0);
	--color-white: oklch(1 0 0);
	--color-gray-50: oklch(0.961 0 0);
	--color-gray-100: oklch(0.925 0 0);
	--color-gray-200: oklch(0.845 0 0);
	--color-gray-300: oklch(0.767 0 0);
	--color-gray-400: oklch(0.683 0 0);
	--color-gray-500: oklch(0.6 0 0);
	--color-gray-600: oklch(0.51 0 0);
	--color-gray-700: oklch(0.42 0 0);
	--color-gray-800: oklch(0.321 0 0);
	--color-gray-900: oklch(0.218 0 0);
	--color-gray-950: oklch(0.159 0 0);
	--color-transparent: transparent;
	/* ... */
}
```

### Switching

Import the theme configuration file and the switch theme method in the NPM package of STDF, and call the switch theme method.

```javascript
// Import the theme configuration file and the switch theme method (the NPM package of STDF contains a STDF theme configuration file)
import { stdfTheme, switchTheme } from 'stdf/theme';
// Import the custom theme configuration file, assume customTheme is the custom theme configuration file
import customTheme from './customTheme';

// Switch to STDF theme
switchTheme(stdfTheme);

// Switch to custom theme
switchTheme(customTheme);
```

Detailed usage can refer to [STDF Demo](https://github.com/any-tdf/demo-stdf).

## Summary

### Light and dark modes

Directly use the darkMode method in the NPM package of STDF.

### Multiple theme mode

1. Configure the default theme CSS variables in the entry CSS file, such as `src/app.css`.
2. Configure the color system in the theme generator and generate the theme configuration file.
3. Import the theme configuration file and the switch theme method in the NPM package of STDF, and call the switch theme method.

> Of course, if you don't need to switch themes, you only need to configure the initial CSS variables.



================================================
FILE: docs/mds/guide/vscode.md
================================================
## VS Code 插件

### 介绍

STDF 提供了一个 VS Code 插件 [STDF for VS Code](https://marketplace.visualstudio.com/items?itemName=STDF.stdf-vscode-extension)，用于在使用 [STDF](https://stdf.design) 开发时提供一些便利。

### 安装

在 VS Code 插件中搜索 `STDF for VS Code` 点击安装，或到 VS Code 插件市场安装 [STDF for VS Code](https://marketplace.visualstudio.com/items?itemName=STDF.stdf-vscode-extension)。

### 功能

光标悬浮于 STDF 组件名称上时悬浮显示。

- 此组件 API。
- 直接打开 STDF 官网此组件的示例/API/指南。
- 直接打开 STDF 此组件源码（GitHub/Gitee）。

![TIP](https://stdf.design/assets/vscode/tip.png)

或者

![TIP](https://stdf.design/assets/vscode/tip2.png)

### 配置

默认显示的 API 为简体中文，可到 VS Code 的设置页开启英文 API。

![SETTING](https://stdf.design/assets/vscode/setting.png)



================================================
FILE: docs/mds/guide/vscode_en.md
================================================
## VS Code Plugin

### Introduction

STDF provides a VS Code plugin called [STDF for VS Code](https://marketplace.visualstudio.com/items?itemName=STDF.stdf-vscode-extension), which provides convenience when developing with [STDF](https://stdf.design).

### Installation

Search for `STDF for VS Code` in the VS Code plugin marketplace and click install, or install [STDF for VS Code](https://marketplace.visualstudio.com/items?itemName=STDF.stdf-vscode-extension) from the VS Code plugin marketplace.

### Features

When hovering over the name of an STDF component, the following information will be displayed:

- The API of this component.
- The example/API/guide of this component on the STDF official website.
- The source code of this component on GitHub/Gitee.

![TIP](https://stdf.design/assets/vscode/tip.png)

or

![TIP](https://stdf.design/assets/vscode/tip2.png)

### Configuration

The default API display is in Simplified Chinese. You can enable English API in the VS Code settings.

![SETTING](https://stdf.design/assets/vscode/setting.png)



================================================
FILE: docs/site/eslint.config.js
================================================
import prettier from 'eslint-config-prettier';
import js from '@eslint/js';
import { includeIgnoreFile } from '@eslint/compat';
import svelte from 'eslint-plugin-svelte';
import globals from 'globals';
import { fileURLToPath } from 'node:url';
import ts from 'typescript-eslint';
const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url));

export default ts.config(
	includeIgnoreFile(gitignorePath),
	js.configs.recommended,
	...ts.configs.recommended,
	...svelte.configs['flat/recommended'],
	prettier,
	...svelte.configs['flat/prettier'],
	{
		languageOptions: {
			globals: {
				...globals.browser,
				...globals.node
			}
		}
	},
	{
		files: ['**/*.svelte'],

		languageOptions: {
			parserOptions: {
				parser: ts.parser
			}
		}
	}
);



================================================
FILE: docs/site/package.json
================================================
{
	"name": "site",
	"version": "0.0.1",
	"type": "module",
	"scripts": {
		"env": "bun run scripts/env.js",
		"dev": "bun run env && vite dev",
		"preview": "vite preview",
		"build": "bun run env && vite build",
		"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
		"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
		"format": "prettier --write .",
		"lint": "prettier --check . && eslint ."
	},
	"devDependencies": {
		"@eslint/compat": "^1.2.4",
		"@sveltejs/adapter-static": "^3.0.6",
		"@sveltejs/kit": "^2.9.0",
		"@sveltejs/vite-plugin-svelte": "^5.0.1",
		"@tailwindcss/typography": "^0.5.15",
		"@tailwindcss/vite": "^4.0.12",
		"@types/color": "^4.2.0",
		"@types/culori": "^2.1.1",
		"beautify-qrcode": "^1.0.3",
		"clipboard": "^2.0.11",
		"color": "^4.2.3",
		"culori": "^4.0.1",
		"eslint": "^9.16.0",
		"eslint-config-prettier": "^9.1.0",
		"eslint-plugin-svelte": "^2.46.1",
		"globals": "^15.13.0",
		"highlight.js": "^11.10.0",
		"highlightjs-svelte": "^1.0.6",
		"prettier": "^3.4.2",
		"prettier-plugin-svelte": "^3.3.2",
		"prettier-plugin-tailwindcss": "^0.6.9",
		"rollup-plugin-md-ts": "file:../../packages/rollup-plugin-md-ts",
		"rollup-plugin-stdf-icon": "file:../../packages/rollup-plugin-stdf-icon",
		"stdf": "file:../../packages/stdf",
		"svelte": "^5.7.1",
		"svelte-check": "^4.1.1",
		"svelte-confetti": "^2.3.1",
		"tailwindcss": "^4.0.12",
		"typescript": "^5.7.2",
		"typescript-eslint": "^8.17.0",
		"vite": "^6.0.3"
	}
}



================================================
FILE: docs/site/svelte.config.js
================================================
import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

/** @type {import('@sveltejs/kit').Config} */
const config = {
	// Consult https://svelte.dev/docs/kit/integrations
	// for more information about preprocessors
	preprocess: vitePreprocess(),

	kit: {
		// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
		// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
		// See https://svelte.dev/docs/kit/adapters for more information about adapters.
		adapter: adapter({ fallback: '404.html' })
	}
};

export default config;



================================================
FILE: docs/site/tsconfig.json
================================================
{
	"extends": "./.svelte-kit/tsconfig.json",
	"compilerOptions": {
		"allowJs": true,
		"checkJs": true,
		"esModuleInterop": true,
		"forceConsistentCasingInFileNames": true,
		"resolveJsonModule": true,
		"skipLibCheck": true,
		"sourceMap": true,
		"strict": true,
		"moduleResolution": "bundler"
	}
	// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
	// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
	//
	// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
	// from the referenced tsconfig.json - TypeScript does not merge them in
}


================================================
FILE: docs/site/vite.config.ts
================================================
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import tailwindcss from '@tailwindcss/vite';
import md from 'rollup-plugin-md-ts';
import svgSprite from 'rollup-plugin-stdf-icon';

export default defineConfig({
	plugins: [
		sveltekit(),
		tailwindcss(),
		md({ marked: {}, include: ['../mds/**/*.md', '../../packages/**/*.md'] }),
		svgSprite([{ inFile: 'src/lib/symbol', outFile: 'static/fonts', fileName: 'symbol' }])
	],
	server: { hmr: true, host: '0.0.0.0', port: 5555 },
	build: { assetsDir: 'build' }
});



================================================
FILE: docs/site/.prettierignore
================================================
# Package Managers
package-lock.json
pnpm-lock.yaml
yarn.lock



================================================
FILE: docs/site/.prettierrc
================================================
{
	"useTabs": true,
	"singleQuote": true,
	"trailingComma": "none",
	"printWidth": 140,
	"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
	"overrides": [
		{
			"files": "*.svelte",
			"options": {
				"parser": "svelte"
			}
		}
	]
}



================================================
FILE: docs/site/scripts/env.js
================================================
import fs from 'node:fs';

//得到标准时区的时间的函数
const getLocalTime = (i) => {
	//参数 i 为时区值数字，比如北京为东八区则输进 8，纽约为西 5 区输入 -5
	if (typeof i !== 'number') return;
	const d = new Date();
	//得到 1970 年一月一日到现在的秒数
	const len = d.getTime();
	//本地时间与 GMT 时间的时间偏移差
	const offset = d.getTimezoneOffset() * 60000;
	//得到现在的格林尼治时间
	const utcTime = len + offset;
	return new Date(utcTime + 3600000 * i);
};

// 获取当前时间，返回中文和英文时间格式，24 小时制
let now_en = getLocalTime(-4).toLocaleString('en-US', { hour12: false });
let now_zh = getLocalTime(+8).toLocaleString('zh-CN', { hour12: false });

// 去掉秒，即去除最后的 ':xx'
now_en = `${now_en.slice(0, -3)} GMT-4`;
now_zh = `${now_zh.slice(0, -3)} GMT+8`;

console.log('now_en', now_en);
console.log('now_zh', now_zh);

// 如果已存在 .env 文件，则删除
if (fs.existsSync('.env')) {
	fs.unlinkSync('.env');
}

// 将当前时间写入 .env 文件
fs.writeFileSync('.env', `VITE_BUILD_TIME_EN=${now_en}\nVITE_BUILD_TIME_ZH=${now_zh}`);



================================================
FILE: docs/site/src/app.css
================================================
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));
@plugin "@tailwindcss/typography";
@theme {
	--color-primary-50: oklch(0.979 0.01 267.36);
	--color-primary-100: oklch(0.95 0.024 270.343);
	--color-primary-200: oklch(0.847 0.074 271.188);
	--color-primary-300: oklch(0.741 0.13 272.232);
	--color-primary-400: oklch(0.634 0.193 271.595);
	--color-primary-500: oklch(0.536 0.252 268.66);
	--color-primary: oklch(0.467 0.296 264.886);
	--color-primary-700: oklch(0.397 0.26 264.877);
	--color-primary-800: oklch(0.331 0.221 264.833);
	--color-primary-900: oklch(0.26 0.178 264.428);
	--color-primary-950: oklch(0.192 0.13 266.64);

	--color-dark-50: oklch(0.995 0.012 101.474);
	--color-dark-100: oklch(0.986 0.025 97.107);
	--color-dark-200: oklch(0.965 0.059 95.884);
	--color-dark-300: oklch(0.938 0.089 92.952);
	--color-dark-400: oklch(0.91 0.114 89.711);
	--color-dark-500: oklch(0.88 0.136 86.375);
	--color-dark: oklch(0.845 0.153 80.597);
	--color-dark-700: oklch(0.71 0.137 75.734);
	--color-dark-800: oklch(0.58 0.118 70.166);
	--color-dark-900: oklch(0.449 0.097 65.209);
	--color-dark-950: oklch(0.321 0.074 62.379);

	--color-primaryBlack: oklch(0.116 0.054 267.087);
	--color-primaryWhite: oklch(0.961 0.001 286.375);
	--color-darkBlack: oklch(0.183 0.035 86.634);
	--color-darkWhite: oklch(0.962 0.001 17.178);

	--color-success: oklch(0.704 0.142 167.084);
	--color-warning: oklch(0.558 0.154 47.186);
	--color-error: oklch(0.564 0.223 28.46);
	--color-info: oklch(0.482 0.14 261.518);

	--color-extend0: oklch(0.703 0.149 235.059);
	--color-Twitter: oklch(0.703 0.149 235.059);
	--color-extend1: oklch(0.702 0.194 38.137);
	--color-Svelte: oklch(0.702 0.194 38.137);
	--color-extend2: oklch(0.482 0.107 161.212);
	--color-Starbucks: oklch(0.482 0.107 161.212);

	--color-black: oklch(0 0 0);
	--color-white: oklch(1 0 0);
	--color-gray-50: oklch(0.961 0 0);
	--color-gray-100: oklch(0.925 0 0);
	--color-gray-200: oklch(0.845 0 0);
	--color-gray-300: oklch(0.767 0 0);
	--color-gray-400: oklch(0.683 0 0);
	--color-gray-500: oklch(0.6 0 0);
	--color-gray-600: oklch(0.51 0 0);
	--color-gray-700: oklch(0.42 0 0);
	--color-gray-800: oklch(0.321 0 0);
	--color-gray-900: oklch(0.218 0 0);
	--color-gray-950: oklch(0.159 0 0);
	--color-transparent: transparent;

	--color-bug1: oklch(0.579 0.214 27.172);
	--color-bug2: oklch(0.749 0.162 66.986);
	--color-bug3: oklch(0.912 0.192 103.116);
	--color-bug4: oklch(0.779 0.141 229.596);
	--color-tailwind: oklch(0.746 0.16 232.661);
	--color-svelte: oklch(0.702 0.194 38.137);

	/* 抖动动效 */
	--animate-shake: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
	@keyframes shake {
		10%,
		90% {
			transform: translate3d(-1px, 0, 0);
		}
		20%,
		80% {
			transform: translate3d(2px, 0, 0);
		}
		30%,
		50%,
		70% {
			transform: translate3d(-4px, 0, 0);
		}
		40%,
		60% {
			transform: translate3d(4px, 0, 0);
		}
	}

	/* 闪电动效 */
	--animate-lightning: lightning 3s linear infinite;
	@keyframes lightning {
		0% {
			opacity: 0;
		}
		10% {
			opacity: 1;
		}
		20% {
			opacity: 0;
		}
		30% {
			opacity: 1;
		}
		100% {
			opacity: 0;
		}
	}

	/* 路径动效 */
	--animate-path: path 3s linear infinite;
	@keyframes path {
		0% {
			stroke-dashoffset: 400;
			fill: transparent;
		}
		31% {
			stroke-dashoffset: 0;
			fill: transparent;
		}
		32% {
			stroke-dashoffset: 0;
			fill: currentColor;
			opacity: 1;
		}
		33% {
			opacity: 0;
		}
		35% {
			opacity: 1;
		}
		37% {
			opacity: 0;
		}
		39% {
			opacity: 1;
		}
		41% {
			opacity: 0;
		}
		43% {
			opacity: 1;
		}
		44% {
			stroke-dashoffset: 0;
			fill: currentColor;
		}
		99% {
			stroke-dashoffset: 0;
			fill: currentColor;
		}
		100% {
			stroke-dashoffset: 400;
			fill: transparent;
		}
	}

	/* 动态背景动效 */
	--animate-dynamicsBg: dynamicsBg 8s linear infinite;
	@keyframes dynamicsBg {
		0% {
			transform: rotate(360deg);
			height: 14rem;
			width: 14rem;
		}
		50% {
			height: 7rem;
			width: 7rem;
		}
		100% {
			transform: rotate(0deg);
			height: 14rem;
			width: 14rem;
		}
	}

	/* 云朵移动动效 */
	--animate-cloudMove: cloudMove 40s linear infinite;
	@keyframes cloudMove {
		0% {
			transform: translateX(20%) translateY(-20%);
		}
		50% {
			transform: translateX(-100%) translateY(-20%);
		}
		100% {
			transform: translateX(20%) translateY(-20%);
		}
	}

	/* 星星闪烁动效 */
	--animate-starTwinkle: starTwinkle 8s linear infinite;
	--animate-starTwinkle2: starTwinkle 3s linear infinite;
	--animate-starTwinkle3: starTwinkle 6s linear infinite;
	--animate-starTwinkle4: starTwinkle 4s linear infinite;
	@keyframes starTwinkle {
		0% {
			opacity: 1;
		}
		40% {
			opacity: 1;
		}
		50% {
			opacity: 0;
		}
		60% {
			opacity: 1;
		}
		100% {
			opacity: 1;
		}
	}

	/* 元素上下慢慢循环移动动效 */
	--animate-elementUpDownMove1: elementUpDownMove 12s linear infinite;
	--animate-elementUpDownMove2: elementUpDownMove 10s linear infinite -12s;
	--animate-elementUpDownMove3: elementUpDownMove 12s linear infinite -14s;
	--animate-elementUpDownMove4: elementUpDownMove 8s linear infinite -10s;
	--animate-elementUpDownMove5: elementUpDownMove 10s linear infinite -8s;
	--animate-elementUpDownMove6: elementUpDownMove 12s linear infinite -6s;
	@keyframes elementUpDownMove {
		0% {
			transform: translateY(-20px);
		}
		50% {
			transform: translateY(20px);
		}
		100% {
			transform: translateY(-20px);
		}
	}
}
@source "../../../packages/stdf/dist/**/*.svelte";

pre {
	background-color: transparent;
	padding: 0;
}

*::-webkit-scrollbar {
	width: 4px;
}

*::-webkit-scrollbar-thumb {
	border-radius: 2px;
	background-color: rgba(133, 133, 133, 0.5);
}

*::-webkit-scrollbar-track {
	background-color: rgba(133, 133, 133, 0.2);
}

html {
	overflow-x: hidden;
	overflow-y: overlay;
	/*scrollbar-gutter: stable;*/
	/* scrollbar-gutter: stable both-edges; */
	-webkit-tap-highlight-color: transparent;
}
* {
	scrollbar-width: thin;
}

.prose :where(code):not(:where([class~='not-prose'] *))::before {
	content: '' !important;
}

.prose :where(code):not(:where([class~='not-prose'] *))::after {
	content: '' !important;
}

.prose :where(code):not(:where([class~='not-prose'] *)) {
	padding-left: 4px;
	padding-right: 4px;
	border-radius: 2px;
	background: #e4e4e4 !important;
}

.dark .dark\:prose-invert :where(code):not(:where([class~='not-prose'] *)) {
	background: #202020 !important;
}

/*!
  Theme: GitHub Light
*/
.prose pre code.hljs {
	background: #e4e4e4 !important;
}

.prose pre code.hljs {
	display: block;
	overflow-x: auto;
	padding: 1em;
}

.prose code.hljs {
	padding: 3px 5px;
}

.prose .hljs {
	/* background: #ebebeb !important; */
	color: #434f54;
}

.prose .hljs-subst {
	color: #434f54;
}

.prose .hljs-attribute,
.prose .hljs-doctag,
.prose .hljs-keyword,
.prose .hljs-name,
.prose .hljs-selector-tag {
	/* color: #00979d; */
	/* color: #0B24FB; */
	/* color: #ff3e00; */
	color: #af10a7;
}

.prose .hljs-addition,
.prose .hljs-built_in,
.prose .hljs-bullet,
.prose .hljs-code,
.prose .hljs-literal {
	color: #d35400;
}

.prose .hljs-link,
.prose .hljs-regexp,
.prose .hljs-selector-attr,
.prose .hljs-selector-pseudo,
.prose .hljs-symbol,
.prose .hljs-template-variable,
.prose .hljs-variable {
	/* color: #00979d; */
	color: #0b24fb;
	/* font-weight: bold; */
	/* color: #8a3ce2; */
}

.prose .hljs-deletion,
.prose .hljs-quote,
.prose .hljs-selector-class,
.prose .hljs-selector-id,
.prose .hljs-string,
.prose .hljs-template-tag,
.prose .hljs-type {
	/* color: #005c5f; */
	color: rgb(56, 189, 248);
}

.prose .hljs-comment {
	color: rgba(149, 165, 166, 0.8);
}

.prose .hljs-meta .hljs-keyword {
	color: #728e00;
}

.prose .hljs-meta {
	color: #434f54;
}

.prose .hljs-emphasis {
	font-style: italic;
}

.prose .hljs-strong {
	font-weight: 700;
}

.prose .hljs-function {
	color: #728e00;
}

.prose .hljs-section,
.prose .hljs-title {
	/* color: #800; */
	color: #0b24fb;
	font-weight: 700;
}

.prose .hljs-number {
	color: #8a7b52;
}

.dark .dark\:prose-invert pre code.hljs {
	background: #202020 !important;
}

.dark .dark\:prose-invert pre code.hljs {
	display: block;
	overflow-x: auto;
	padding: 1em;
}

.dark .dark\:prose-invert code.hljs {
	padding: 3px 5px;
}

/*!
  Theme: GitHub Dark
*/
.dark .dark\:prose-invert .hljs {
	color: #c9d1d9;
	/* background: #0d1117; */
}

.dark .dark\:prose-invert .hljs-doctag,
.dark .dark\:prose-invert .hljs-keyword,
.dark .dark\:prose-invert .hljs-meta .hljs-keyword,
.dark .dark\:prose-invert .hljs-template-tag,
.dark .dark\:prose-invert .hljs-template-variable,
.dark .dark\:prose-invert .hljs-type,
.dark .dark\:prose-invert .hljs-variable.language_ {
	/* color: #ff7b72; */
	color: #ffc043;
}

.dark .dark\:prose-invert .hljs-title,
.dark .dark\:prose-invert .hljs-title.class_,
.dark .dark\:prose-invert .hljs-title.class_.inherited__,
.dark .dark\:prose-invert .hljs-title.function_ {
	color: #d2a8ff;
}

.dark .dark\:prose-invert .hljs-attr,
.dark .dark\:prose-invert .hljs-attribute,
.dark .dark\:prose-invert .hljs-literal,
.dark .dark\:prose-invert .hljs-meta,
.dark .dark\:prose-invert .hljs-number,
.dark .dark\:prose-invert .hljs-operator,
.dark .dark\:prose-invert .hljs-selector-attr,
.dark .dark\:prose-invert .hljs-selector-class,
.dark .dark\:prose-invert .hljs-selector-id,
.dark .dark\:prose-invert .hljs-variable {
	color: #79c0ff;
}

.dark .dark\:prose-invert .hljs-meta .hljs-string,
.dark .dark\:prose-invert .hljs-regexp,
.dark .dark\:prose-invert .hljs-string {
	color: #a5d6ff;
}

.dark .dark\:prose-invert .hljs-built_in,
.dark .dark\:prose-invert .hljs-symbol {
	color: #ffa657;
}

.dark .dark\:prose-invert .hljs-code,
.dark .dark\:prose-invert .hljs-comment,
.dark .dark\:prose-invert .hljs-formula {
	color: #8b949e;
}

.dark .dark\:prose-invert .hljs-name,
.dark .dark\:prose-invert .hljs-quote,
.dark .dark\:prose-invert .hljs-selector-pseudo,
.dark .dark\:prose-invert .hljs-selector-tag {
	color: #7ee787;
}

.dark .dark\:prose-invert .hljs-subst {
	color: #c9d1d9;
}

.dark .dark\:prose-invert .hljs-section {
	color: #1f6feb;
	font-weight: 700;
}

.dark .dark\:prose-invert .hljs-bullet {
	color: #f2cc60;
}

.dark .dark\:prose-invert .hljs-emphasis {
	color: #c9d1d9;
	font-style: italic;
}

.dark .dark\:prose-invert .hljs-strong {
	color: #c9d1d9;
	font-weight: 700;
}

.dark .dark\:prose-invert .hljs-addition {
	color: #aff5b4;
	background-color: #033a16;
}

.dark .dark\:prose-invert .hljs-deletion {
	color: #ffdcd7;
	background-color: #67060c;
}

@font-face {
	font-family: 'JetBrainsMono';
	src: url('/assets/fonts/JetBrainsMono-Regular.woff2');
}

code {
	font-family: 'JetBrainsMono' !important;
}

/* 模拟设计软件的透明层 */
.transparent-background {
	background-image: linear-gradient(45deg, #666 25%, transparent 25%, transparent 75%, #666 75%),
		linear-gradient(45deg, #666 25%, transparent 25%, transparent 75%, #666 75%);
	background-position:
		0 0,
		10px 10px;
	background-size: 20px 20px;
}

@keyframes clip {
	from {
		clip-path: circle(0% at var(--x) var(--y));
	}
	to {
		clip-path: circle(100% at var(--x) var(--y));
	}
}

::view-transition-old(root) {
	animation: none;
}
::view-transition-new(root) {
	mix-blend-mode: normal;
	animation: clip 0.6s ease-in;
}




================================================
FILE: docs/site/src/app.d.ts
================================================
// See https://svelte.dev/docs/kit/types#app.d.ts
// for information about these interfaces
declare global {
	namespace App {
		// interface Error {}
		// interface Locals {}
		// interface PageData {}
		// interface PageState {}
		// interface Platform {}
	}
}

export {};



================================================
FILE: docs/site/src/app.html
================================================
<!doctype html>
<html lang="zh-CN">
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width,initial-scale=1" />
		<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)" />
		<meta name="theme-color" content="#23262B" media="(prefers-color-scheme: dark)" />
		<meta itemprop="name" content="STDF" />
		<meta name="description" itemprop="description" content="Mobile web component library based on Svelte and Tailwind" />
		<meta itemprop="image" content="./assets/images/logo.png" />
		<title>STDF - 移动 web 组件库</title>
		<link href="/favicon.ico" rel="icon" media="(prefers-color-scheme: light)" />
		<link href="/favicon_black.ico" rel="icon" media="(prefers-color-scheme: dark)" />
		%sveltekit.head%
	</head>
	<body
		data-sveltekit-preload-data="hover"
		class="selection:bg-primary dark:selection:bg-dark selection:text-white dark:selection:text-black"
	>
		<div style="display: contents">%sveltekit.body%</div>
	</body>
</html>



================================================
FILE: docs/site/src/global.d.ts
================================================
/// <reference types="vite-plugin-md-to-html/types" />



================================================
FILE: docs/site/src/store.ts
================================================
import { writable } from 'svelte/store';

// 是否显示导航
export const isShowNavStore = writable(false);
// 文档 theme 模式，dark、light、auto。
export const themeStore = writable(localStorage.getItem('theme') || 'auto');
// 系统 theme 模式，dark、light
export const sysThemeStore = writable(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
// 当前 theme 模式，dark、light
const currentTheme =
	(localStorage.getItem('theme') || 'auto') === 'auto'
		? window.matchMedia('(prefers-color-scheme: dark)').matches
			? 'dark'
			: 'light'
		: localStorage.getItem('theme') || 'auto';
export const currentThemeStore = writable(currentTheme);
// 是否开启 cmdK
export const isCmdKStore = writable(false);
// 是否显示赞赏
export const isShowFundStore = writable(false);
// 当前主题色
export const currentColorStore = writable(localStorage.getItem('theme_color') || 'STDF');
// 显示主题色选择器
export const showThemeSwitchStore = writable(false);
// 宽屏显示还是窄屏显示
export const isWideScreenStore = writable(localStorage.getItem('isFull') && localStorage.getItem('isFull') === 'full');



================================================
FILE: docs/site/src/data/color.ts
================================================
import { colorConvertFunc } from '../utils';

const colors = [
	['000000', 'Black'],
	['000080', 'Navy Blue'],
	['0000C8', 'Dark Blue'],
	['0000FF', 'Blue'],
	['000741', 'Stratos'],
	['001B1C', 'Swamp'],
	['002387', 'Resolution Blue'],
	['002900', 'Deep Fir'],
	['002E20', 'Burnham'],
	['002FA7', 'Klein Blue'],
	['003153', 'Prussian Blue'],
	['003366', 'Midnight Blue'],
	['003399', 'Smalt'],
	['003532', 'Deep Teal'],
	['003E40', 'Cyprus'],
	['004620', 'Kaitoke Green'],
	['0047AB', 'Cobalt'],
	['004816', 'Crusoe'],
	['004950', 'Sherpa Blue'],
	['0056A7', 'Endeavour'],
	['00581A', 'Camarone'],
	['0066CC', 'Science Blue'],
	['0066FF', 'Blue Ribbon'],
	['00755E', 'Tropical Rain Forest'],
	['0076A3', 'Allports'],
	['007BA7', 'Deep Cerulean'],
	['007EC7', 'Lochmara'],
	['007FFF', 'Azure Radiance'],
	['008080', 'Teal'],
	['0095B6', 'Bondi Blue'],
	['009DC4', 'Pacific Blue'],
	['00A693', 'Persian Green'],
	['00A86B', 'Jade'],
	['00CC99', 'Caribbean Green'],
	['00CCCC', "Robin's Egg Blue"],
	['00FF00', 'Green'],
	['00FF7F', 'Spring Green'],
	['00FFFF', 'Cyan / Aqua'],
	['010D1A', 'Blue Charcoal'],
	['011635', 'Midnight'],
	['011D13', 'Holly'],
	['012731', 'Daintree'],
	['01361C', 'Cardin Green'],
	['01371A', 'County Green'],
	['013E62', 'Astronaut Blue'],
	['013F6A', 'Regal Blue'],
	['014B43', 'Aqua Deep'],
	['015E85', 'Orient'],
	['016162', 'Blue Stone'],
	['016D39', 'Fun Green'],
	['01796F', 'Pine Green'],
	['017987', 'Blue Lagoon'],
	['01826B', 'Deep Sea'],
	['01A368', 'Green Haze'],
	['022D15', 'English Holly'],
	['02402C', 'Sherwood Green'],
	['02478E', 'Congress Blue'],
	['024E46', 'Evening Sea'],
	['026395', 'Bahama Blue'],
	['02866F', 'Observatory'],
	['02A4D3', 'Cerulean'],
	['03163C', 'Tangaroa'],
	['032B52', 'Green Vogue'],
	['036A6E', 'Mosque'],
	['041004', 'Midnight Moss'],
	['041322', 'Black Pearl'],
	['042E4C', 'Blue Whale'],
	['044022', 'Zuccini'],
	['044259', 'Teal Blue'],
	['051040', 'Deep Cove'],
	['051657', 'Gulf Blue'],
	['055989', 'Venice Blue'],
	['056F57', 'Watercourse'],
	['062A78', 'Catalina Blue'],
	['063537', 'Tiber'],
	['069B81', 'Gossamer'],
	['06A189', 'Niagara'],
	['073A50', 'Tarawera'],
	['080110', 'Jaguar'],
	['081910', 'Black Bean'],
	['082567', 'Deep Sapphire'],
	['088370', 'Elf Green'],
	['08E8DE', 'Bright Turquoise'],
	['092256', 'Downriver'],
	['09230F', 'Palm Green'],
	['09255D', 'Madison'],
	['093624', 'Bottle Green'],
	['095859', 'Deep Sea Green'],
	['097F4B', 'Salem'],
	['0A001C', 'Black Russian'],
	['0A480D', 'Dark Fern'],
	['0A6906', 'Japanese Laurel'],
	['0A6F75', 'Atoll'],
	['0B0B0B', 'Cod Gray'],
	['0B0F08', 'Marshland'],
	['0B1107', 'Gordons Green'],
	['0B1304', 'Black Forest'],
	['0B6207', 'San Felix'],
	['0BDA51', 'Malachite'],
	['0C0B1D', 'Ebony'],
	['0C0D0F', 'Woodsmoke'],
	['0C1911', 'Racing Green'],
	['0C7A79', 'Surfie Green'],
	['0C8990', 'Blue Chill'],
	['0D0332', 'Black Rock'],
	['0D1117', 'Bunker'],
	['0D1C19', 'Aztec'],
	['0D2E1C', 'Bush'],
	['0E0E18', 'Cinder'],
	['0E2A30', 'Firefly'],
	['0F2D9E', 'Torea Bay'],
	['10121D', 'Vulcan'],
	['101405', 'Green Waterloo'],
	['105852', 'Eden'],
	['110C6C', 'Arapawa'],
	['120A8F', 'Ultramarine'],
	['123447', 'Elephant'],
	['126B40', 'Jewel'],
	['130000', 'Diesel'],
	['130A06', 'Asphalt'],
	['13264D', 'Blue Zodiac'],
	['134F19', 'Parsley'],
	['140600', 'Nero'],
	['1450AA', 'Tory Blue'],
	['151F4C', 'Bunting'],
	['1560BD', 'Denim'],
	['15736B', 'Genoa'],
	['161928', 'Mirage'],
	['161D10', 'Hunter Green'],
	['162A40', 'Big Stone'],
	['163222', 'Celtic'],
	['16322C', 'Timber Green'],
	['163531', 'Gable Green'],
	['171F04', 'Pine Tree'],
	['175579', 'Chathams Blue'],
	['182D09', 'Deep Forest Green'],
	['18587A', 'Blumine'],
	['19330E', 'Palm Leaf'],
	['193751', 'Nile Blue'],
	['1959A8', 'Fun Blue'],
	['1A1A68', 'Lucky Point'],
	['1AB385', 'Mountain Meadow'],
	['1B0245', 'Tolopea'],
	['1B1035', 'Haiti'],
	['1B127B', 'Deep Koamaru'],
	['1B1404', 'Acadia'],
	['1B2F11', 'Seaweed'],
	['1B3162', 'Biscay'],
	['1B659D', 'Matisse'],
	['1C1208', 'Crowshead'],
	['1C1E13', 'Rangoon Green'],
	['1C39BB', 'Persian Blue'],
	['1C402E', 'Everglade'],
	['1C7C7D', 'Elm'],
	['1D6142', 'Green Pea'],
	['1E0F04', 'Creole'],
	['1E1609', 'Karaka'],
	['1E1708', 'El Paso'],
	['1E385B', 'Cello'],
	['1E433C', 'Te Papa Green'],
	['1E90FF', 'Dodger Blue'],
	['1E9AB0', 'Eastern Blue'],
	['1F120F', 'Night Rider'],
	['1FC2C2', 'Java'],
	['20208D', 'Jacksons Purple'],
	['202E54', 'Cloud Burst'],
	['204852', 'Blue Dianne'],
	['211A0E', 'Eternity'],
	['220878', 'Deep Blue'],
	['228B22', 'Forest Green'],
	['233418', 'Mallard'],
	['240A40', 'Violet'],
	['240C02', 'Kilamanjaro'],
	['242A1D', 'Log Cabin'],
	['242E16', 'Black Olive'],
	['24500F', 'Green House'],
	['251607', 'Graphite'],
	['251706', 'Cannon Black'],
	['251F4F', 'Port Gore'],
	['25272C', 'Shark'],
	['25311C', 'Green Kelp'],
	['2596D1', 'Curious Blue'],
	['260368', 'Paua'],
	['26056A', 'Paris M'],
	['261105', 'Wood Bark'],
	['261414', 'Gondola'],
	['262335', 'Steel Gray'],
	['26283B', 'Ebony Clay'],
	['273A81', 'Bay of Many'],
	['27504B', 'Plantation'],
	['278A5B', 'Eucalyptus'],
	['281E15', 'Oil'],
	['283A77', 'Astronaut'],
	['286ACD', 'Mariner'],
	['290C5E', 'Violent Violet'],
	['292130', 'Bastille'],
	['292319', 'Zeus'],
	['292937', 'Charade'],
	['297B9A', 'Jelly Bean'],
	['29AB87', 'Jungle Green'],
	['2A0359', 'Cherry Pie'],
	['2A140E', 'Coffee Bean'],
	['2A2630', 'Baltic Sea'],
	['2A380B', 'Turtle Green'],
	['2A52BE', 'Cerulean Blue'],
	['2B0202', 'Sepia Black'],
	['2B194F', 'Valhalla'],
	['2B3228', 'Heavy Metal'],
	['2C0E8C', 'Blue Gem'],
	['2C1632', 'Revolver'],
	['2C2133', 'Bleached Cedar'],
	['2C8C84', 'Lochinvar'],
	['2D2510', 'Mikado'],
	['2D383A', 'Outer Space'],
	['2D569B', 'St Tropaz'],
	['2E0329', 'Jacaranda'],
	['2E1905', 'Jacko Bean'],
	['2E3222', 'Rangitoto'],
	['2E3F62', 'Rhino'],
	['2E8B57', 'Sea Green'],
	['2EBFD4', 'Scooter'],
	['2F270E', 'Onion'],
	['2F3CB3', 'Governor Bay'],
	['2F519E', 'Sapphire'],
	['2F5A57', 'Spectra'],
	['2F6168', 'Casal'],
	['300529', 'Melanzane'],
	['301F1E', 'Cocoa Brown'],
	['302A0F', 'Woodrush'],
	['304B6A', 'San Juan'],
	['30D5C8', 'Turquoise'],
	['311C17', 'Eclipse'],
	['314459', 'Pickled Bluewood'],
	['315BA1', 'Azure'],
	['31728D', 'Calypso'],
	['317D82', 'Paradiso'],
	['32127A', 'Persian Indigo'],
	['32293A', 'Blackcurrant'],
	['323232', 'Mine Shaft'],
	['325D52', 'Stromboli'],
	['327C14', 'Bilbao'],
	['327DA0', 'Astral'],
	['33036B', 'Christalle'],
	['33292F', 'Thunder'],
	['33CC99', 'Shamrock'],
	['341515', 'Tamarind'],
	['350036', 'Mardi Gras'],
	['350E42', 'Valentino'],
	['350E57', 'Jagger'],
	['353542', 'Tuna'],
	['354E8C', 'Chambray'],
	['363050', 'Martinique'],
	['363534', 'Tuatara'],
	['363C0D', 'Waiouru'],
	['36747D', 'Ming'],
	['368716', 'La Palma'],
	['370202', 'Chocolate'],
	['371D09', 'Clinker'],
	['37290E', 'Brown Tumbleweed'],
	['373021', 'Birch'],
	['377475', 'Oracle'],
	['380474', 'Blue Diamond'],
	['381A51', 'Grape'],
	['383533', 'Dune'],
	['384555', 'Oxford Blue'],
	['384910', 'Clover'],
	['394851', 'Limed Spruce'],
	['396413', 'Dell'],
	['3A0020', 'Toledo'],
	['3A2010', 'Sambuca'],
	['3A2A6A', 'Jacarta'],
	['3A686C', 'William'],
	['3A6A47', 'Killarney'],
	['3AB09E', 'Keppel'],
	['3B000B', 'Temptress'],
	['3B0910', 'Aubergine'],
	['3B1F1F', 'Jon'],
	['3B2820', 'Treehouse'],
	['3B7A57', 'Amazon'],
	['3B91B4', 'Boston Blue'],
	['3C0878', 'Windsor'],
	['3C1206', 'Rebel'],
	['3C1F76', 'Meteorite'],
	['3C2005', 'Dark Ebony'],
	['3C3910', 'Camouflage'],
	['3C4151', 'Bright Gray'],
	['3C4443', 'Cape Cod'],
	['3C493A', 'Lunar Green'],
	['3D0C02', 'Bean  '],
	['3D2B1F', 'Bistre'],
	['3D7D52', 'Goblin'],
	['3E0480', 'Kingfisher Daisy'],
	['3E1C14', 'Cedar'],
	['3E2B23', 'English Walnut'],
	['3E2C1C', 'Black Marlin'],
	['3E3A44', 'Ship Gray'],
	['3EABBF', 'Pelorous'],
	['3F2109', 'Bronze'],
	['3F2500', 'Cola'],
	['3F3002', 'Madras'],
	['3F307F', 'Minsk'],
	['3F4C3A', 'Cabbage Pont'],
	['3F583B', 'Tom Thumb'],
	['3F5D53', 'Mineral Green'],
	['3FC1AA', 'Puerto Rico'],
	['3FFF00', 'Harlequin'],
	['401801', 'Brown Pod'],
	['40291D', 'Cork'],
	['403B38', 'Masala'],
	['403D19', 'Thatch Green'],
	['405169', 'Fiord'],
	['40826D', 'Viridian'],
	['40A860', 'Chateau Green'],
	['410056', 'Ripe Plum'],
	['411F10', 'Paco'],
	['412010', 'Deep Oak'],
	['413C37', 'Merlin'],
	['414257', 'Gun Powder'],
	['414C7D', 'East Bay'],
	['4169E1', 'Royal Blue'],
	['41AA78', 'Ocean Green'],
	['420303', 'Burnt Maroon'],
	['423921', 'Lisbon Brown'],
	['427977', 'Faded Jade'],
	['431560', 'Scarlet Gum'],
	['433120', 'Iroko'],
	['433E37', 'Armadillo'],
	['434C59', 'River Bed'],
	['436A0D', 'Green Leaf'],
	['44012D', 'Barossa'],
	['441D00', 'Morocco Brown'],
	['444954', 'Mako'],
	['454936', 'Kelp'],
	['456CAC', 'San Marino'],
	['45B1E8', 'Picton Blue'],
	['460B41', 'Loulou'],
	['462425', 'Crater Brown'],
	['465945', 'Gray Asparagus'],
	['4682B4', 'Steel Blue'],
	['480404', 'Rustic Red'],
	['480607', 'Bulgarian Rose'],
	['480656', 'Clairvoyant'],
	['481C1C', 'Cocoa Bean'],
	['483131', 'Woody Brown'],
	['483C32', 'Taupe'],
	['49170C', 'Van Cleef'],
	['492615', 'Brown Derby'],
	['49371B', 'Metallic Bronze'],
	['495400', 'Verdun Green'],
	['496679', 'Blue Bayoux'],
	['497183', 'Bismark'],
	['4A2A04', 'Bracken'],
	['4A3004', 'Deep Bronze'],
	['4A3C30', 'Mondo'],
	['4A4244', 'Tundora'],
	['4A444B', 'Gravel'],
	['4A4E5A', 'Trout'],
	['4B0082', 'Pigment Indigo'],
	['4B5D52', 'Nandor'],
	['4C3024', 'Saddle'],
	['4C4F56', 'Abbey'],
	['4D0135', 'Blackberry'],
	['4D0A18', 'Cab Sav'],
	['4D1E01', 'Indian Tan'],
	['4D282D', 'Cowboy'],
	['4D282E', 'Livid Brown'],
	['4D3833', 'Rock'],
	['4D3D14', 'Punga'],
	['4D400F', 'Bronzetone'],
	['4D5328', 'Woodland'],
	['4E0606', 'Mahogany'],
	['4E2A5A', 'Bossanova'],
	['4E3B41', 'Matterhorn'],
	['4E420C', 'Bronze Olive'],
	['4E4562', 'Mulled Wine'],
	['4E6649', 'Axolotl'],
	['4E7F9E', 'Wedgewood'],
	['4EABD1', 'Shakespeare'],
	['4F1C70', 'Honey Flower'],
	['4F2398', 'Daisy Bush'],
	['4F69C6', 'Indigo'],
	['4F7942', 'Fern Green'],
	['4F9D5D', 'Fruit Salad'],
	['4FA83D', 'Apple'],
	['504351', 'Mortar'],
	['507096', 'Kashmir Blue'],
	['507672', 'Cutty Sark'],
	['50C878', 'Emerald'],
	['514649', 'Emperor'],
	['516E3D', 'Chalet Green'],
	['517C66', 'Como'],
	['51808F', 'Smalt Blue'],
	['52001F', 'Castro'],
	['520C17', 'Maroon Oak'],
	['523C94', 'Gigas'],
	['533455', 'Voodoo'],
	['534491', 'Victoria'],
	['53824B', 'Hippie Green'],
	['541012', 'Heath'],
	['544333', 'Judge Gray'],
	['54534D', 'Fuscous Gray'],
	['549019', 'Vida Loca'],
	['55280C', 'Cioccolato'],
	['555B10', 'Saratoga'],
	['556D56', 'Finlandia'],
	['5590D9', 'Havelock Blue'],
	['56B4BE', 'Fountain Blue'],
	['578363', 'Spring Leaves'],
	['583401', 'Saddle Brown'],
	['585562', 'Scarpa Flow'],
	['587156', 'Cactus'],
	['589AAF', 'Hippie Blue'],
	['591D35', 'Wine Berry'],
	['592804', 'Brown Bramble'],
	['593737', 'Congo Brown'],
	['594433', 'Millbrook'],
	['5A6E9C', 'Waikawa Gray'],
	['5A87A0', 'Horizon'],
	['5B3013', 'Jambalaya'],
	['5C0120', 'Bordeaux'],
	['5C0536', 'Mulberry Wood'],
	['5C2E01', 'Carnaby Tan'],
	['5C5D75', 'Comet'],
	['5D1E0F', 'Redwood'],
	['5D4C51', 'Don Juan'],
	['5D5C58', 'Chicago'],
	['5D5E37', 'Verdigris'],
	['5D7747', 'Dingley'],
	['5DA19F', 'Breaker Bay'],
	['5E483E', 'Kabul'],
	['5E5D3B', 'Hemlock'],
	['5F3D26', 'Irish Coffee'],
	['5F5F6E', 'Mid Gray'],
	['5F6672', 'Shuttle Gray'],
	['5FA777', 'Aqua Forest'],
	['5FB3AC', 'Tradewind'],
	['604913', 'Horses Neck'],
	['605B73', 'Smoky'],
	['606E68', 'Corduroy'],
	['6093D1', 'Danube'],
	['612718', 'Espresso'],
	['614051', 'Eggplant'],
	['615D30', 'Costa Del Sol'],
	['61845F', 'Glade Green'],
	['622F30', 'Buccaneer'],
	['623F2D', 'Quincy'],
	['624E9A', 'Butterfly Bush'],
	['625119', 'West Coast'],
	['626649', 'Finch'],
	['639A8F', 'Patina'],
	['63B76C', 'Fern'],
	['6456B7', 'Blue Violet'],
	['646077', 'Dolphin'],
	['646463', 'Storm Dust'],
	['646A54', 'Siam'],
	['646E75', 'Nevada'],
	['6495ED', 'Cornflower Blue'],
	['64CCDB', 'Viking'],
	['65000B', 'Rosewood'],
	['651A14', 'Cherrywood'],
	['652DC1', 'Purple Heart'],
	['657220', 'Fern Frond'],
	['65745D', 'Willow Grove'],
	['65869F', 'Hoki'],
	['660045', 'Pompadour'],
	['660099', 'Purple'],
	['66023C', 'Tyrian Purple'],
	['661010', 'Dark Tan'],
	['66B58F', 'Silver Tree'],
	['66FF00', 'Bright Green'],
	['66FF66', "Screamin' Green"],
	['67032D', 'Black Rose'],
	['675FA6', 'Scampi'],
	['676662', 'Ironside Gray'],
	['678975', 'Viridian Green'],
	['67A712', 'Christi'],
	['683600', 'Nutmeg Wood Finish'],
	['685558', 'Zambezi'],
	['685E6E', 'Salt Box'],
	['692545', 'Tawny Port'],
	['692D54', 'Finn'],
	['695F62', 'Scorpion'],
	['697E9A', 'Lynch'],
	['6A442E', 'Spice'],
	['6A5D1B', 'Himalaya'],
	['6A6051', 'Soya Bean'],
	['6B2A14', 'Hairy Heath'],
	['6B3FA0', 'Royal Purple'],
	['6B4E31', 'Shingle Fawn'],
	['6B5755', 'Dorado'],
	['6B8BA2', 'Bermuda Gray'],
	['6B8E23', 'Olive Drab'],
	['6C3082', 'Eminence'],
	['6CDAE7', 'Turquoise Blue'],
	['6D0101', 'Lonestar'],
	['6D5E54', 'Pine Cone'],
	['6D6C6C', 'Dove Gray'],
	['6D9292', 'Juniper'],
	['6D92A1', 'Gothic'],
	['6E0902', 'Red Oxide'],
	['6E1D14', 'Moccaccino'],
	['6E4826', 'Pickled Bean'],
	['6E4B26', 'Dallas'],
	['6E6D57', 'Kokoda'],
	['6E7783', 'Pale Sky'],
	['6F440C', 'Cafe Royale'],
	['6F6A61', 'Flint'],
	['6F8E63', 'Highland'],
	['6F9D02', 'Limeade'],
	['6FD0C5', 'Downy'],
	['701C1C', 'Persian Plum'],
	['704214', 'Sepia'],
	['704A07', 'Antique Bronze'],
	['704F50', 'Ferra'],
	['706555', 'Coffee'],
	['708090', 'Slate Gray'],
	['711A00', 'Cedar Wood Finish'],
	['71291D', 'Metallic Copper'],
	['714693', 'Affair'],
	['714AB2', 'Studio'],
	['715D47', 'Tobacco Brown'],
	['716338', 'Yellow Metal'],
	['716B56', 'Peat'],
	['716E10', 'Olivetone'],
	['717486', 'Storm Gray'],
	['718080', 'Sirocco'],
	['71D9E2', 'Aquamarine Blue'],
	['72010F', 'Venetian Red'],
	['724A2F', 'Old Copper'],
	['726D4E', 'Go Ben'],
	['727B89', 'Raven'],
	['731E8F', 'Seance'],
	['734A12', 'Raw Umber'],
	['736C9F', 'Kimberly'],
	['736D58', 'Crocodile'],
	['737829', 'Crete'],
	['738678', 'Xanadu'],
	['74640D', 'Spicy Mustard'],
	['747D63', 'Limed Ash'],
	['747D83', 'Rolling Stone'],
	['748881', 'Blue Smoke'],
	['749378', 'Laurel'],
	['74C365', 'Mantis'],
	['755A57', 'Russett'],
	['7563A8', 'Deluge'],
	['76395D', 'Cosmic'],
	['7666C6', 'Blue Marguerite'],
	['76BD17', 'Lima'],
	['76D7EA', 'Sky Blue'],
	['770F05', 'Dark Burgundy'],
	['771F1F', 'Crown of Thorns'],
	['773F1A', 'Walnut'],
	['776F61', 'Pablo'],
	['778120', 'Pacifika'],
	['779E86', 'Oxley'],
	['77DD77', 'Pastel Green'],
	['780109', 'Japanese Maple'],
	['782D19', 'Mocha'],
	['782F16', 'Peanut'],
	['78866B', 'Camouflage Green'],
	['788A25', 'Wasabi'],
	['788BBA', 'Ship Cove'],
	['78A39C', 'Sea Nymph'],
	['795D4C', 'Roman Coffee'],
	['796878', 'Old Lavender'],
	['796989', 'Rum'],
	['796A78', 'Fedora'],
	['796D62', 'Sandstone'],
	['79DEEC', 'Spray'],
	['7A013A', 'Siren'],
	['7A58C1', 'Fuchsia Blue'],
	['7A7A7A', 'Boulder'],
	['7A89B8', 'Wild Blue Yonder'],
	['7AC488', 'De York'],
	['7B3801', 'Red Beech'],
	['7B3F00', 'Cinnamon'],
	['7B6608', 'Yukon Gold'],
	['7B7874', 'Tapa'],
	['7B7C94', 'Waterloo '],
	['7B8265', 'Flax Smoke'],
	['7B9F80', 'Amulet'],
	['7BA05B', 'Asparagus'],
	['7C1C05', 'Kenyan Copper'],
	['7C7631', 'Pesto'],
	['7C778A', 'Topaz'],
	['7C7B7A', 'Concord'],
	['7C7B82', 'Jumbo'],
	['7C881A', 'Trendy Green'],
	['7CA1A6', 'Gumbo'],
	['7CB0A1', 'Acapulco'],
	['7CB7BB', 'Neptune'],
	['7D2C14', 'Pueblo'],
	['7DA98D', 'Bay Leaf'],
	['7DC8F7', 'Malibu'],
	['7DD8C6', 'Bermuda'],
	['7E3A15', 'Copper Canyon'],
	['7F1734', 'Claret'],
	['7F3A02', 'Peru Tan'],
	['7F626D', 'Falcon'],
	['7F7589', 'Mobster'],
	['7F76D3', 'Moody Blue'],
	['7FFF00', 'Chartreuse'],
	['7FFFD4', 'Aquamarine'],
	['800000', 'Maroon'],
	['800B47', 'Rose Bud Cherry'],
	['801818', 'Falu Red'],
	['80341F', 'Red Robin'],
	['803790', 'Vivid Violet'],
	['80461B', 'Russet'],
	['807E79', 'Friar Gray'],
	['808000', 'Olive'],
	['808080', 'Gray'],
	['80B3AE', 'Gulf Stream'],
	['80B3C4', 'Glacier'],
	['80CCEA', 'Seagull'],
	['81422C', 'Nutmeg'],
	['816E71', 'Spicy Pink'],
	['817377', 'Empress'],
	['819885', 'Spanish Green'],
	['826F65', 'Sand Dune'],
	['828685', 'Gunsmoke'],
	['828F72', 'Battleship Gray'],
	['831923', 'Merlot'],
	['837050', 'Shadow'],
	['83AA5D', 'Chelsea Cucumber'],
	['83D0C6', 'Monte Carlo'],
	['843179', 'Plum'],
	['84A0A0', 'Granny Smith'],
	['8581D9', 'Chetwode Blue'],
	['858470', 'Bandicoot'],
	['859FAF', 'Bali Hai'],
	['85C4CC', 'Half Baked'],
	['860111', 'Red Devil'],
	['863C3C', 'Lotus'],
	['86483C', 'Ironstone'],
	['864D1E', 'Bull Shot'],
	['86560A', 'Rusty Nail'],
	['868974', 'Bitter'],
	['86949F', 'Regent Gray'],
	['871550', 'Disco'],
	['87756E', 'Americano'],
	['877C7B', 'Hurricane'],
	['878D91', 'Oslo Gray'],
	['87AB39', 'Sushi'],
	['885342', 'Spicy Mix'],
	['886221', 'Kumera'],
	['888387', 'Suva Gray'],
	['888D65', 'Avocado'],
	['893456', 'Camelot'],
	['893843', 'Solid Pink'],
	['894367', 'Cannon Pink'],
	['897D6D', 'Makara'],
	['8A3324', 'Burnt Umber'],
	['8A73D6', 'True V'],
	['8A8360', 'Clay Creek'],
	['8A8389', 'Monsoon'],
	['8A8F8A', 'Stack'],
	['8AB9F1', 'Jordy Blue'],
	['8B00FF', 'Electric Violet'],
	['8B0723', 'Monarch'],
	['8B6B0B', 'Corn Harvest'],
	['8B8470', 'Olive Haze'],
	['8B847E', 'Schooner'],
	['8B8680', 'Natural Gray'],
	['8B9C90', 'Mantle'],
	['8B9FEE', 'Portage'],
	['8BA690', 'Envy'],
	['8BA9A5', 'Cascade'],
	['8BE6D8', 'Riptide'],
	['8C055E', 'Cardinal Pink'],
	['8C472F', 'Mule Fawn'],
	['8C5738', 'Potters Clay'],
	['8C6495', 'Trendy Pink'],
	['8D0226', 'Paprika'],
	['8D3D38', 'Sanguine Brown'],
	['8D3F3F', 'Tosca'],
	['8D7662', 'Cement'],
	['8D8974', 'Granite Green'],
	['8D90A1', 'Manatee'],
	['8DA8CC', 'Polo Blue'],
	['8E0000', 'Red Berry'],
	['8E4D1E', 'Rope'],
	['8E6F70', 'Opium'],
	['8E775E', 'Domino'],
	['8E8190', 'Mamba'],
	['8EABC1', 'Nepal'],
	['8F021C', 'Pohutukawa'],
	['8F3E33', 'El Salva'],
	['8F4B0E', 'Korma'],
	['8F8176', 'Squirrel'],
	['8FD6B4', 'Vista Blue'],
	['900020', 'Burgundy'],
	['901E1E', 'Old Brick'],
	['907874', 'Hemp'],
	['907B71', 'Almond Frost'],
	['908D39', 'Sycamore'],
	['92000A', 'Sangria'],
	['924321', 'Cumin'],
	['926F5B', 'Beaver'],
	['928573', 'Stonewall'],
	['928590', 'Venus'],
	['9370DB', 'Medium Purple'],
	['93CCEA', 'Cornflower'],
	['93DFB8', 'Algae Green'],
	['944747', 'Copper Rust'],
	['948771', 'Arrowtown'],
	['950015', 'Scarlett'],
	['956387', 'Strikemaster'],
	['959396', 'Mountain Mist'],
	['960018', 'Carmine'],
	['964B00', 'Brown'],
	['967059', 'Leather'],
	['9678B6', "Purple Mountain's Majesty"],
	['967BB6', 'Lavender Purple'],
	['96A8A1', 'Pewter'],
	['96BBAB', 'Summer Green'],
	['97605D', 'Au Chico'],
	['9771B5', 'Wisteria'],
	['97CD2D', 'Atlantis'],
	['983D61', 'Vin Rouge'],
	['9874D3', 'Lilac Bush'],
	['98777B', 'Bazaar'],
	['98811B', 'Hacienda'],
	['988D77', 'Pale Oyster'],
	['98FF98', 'Mint Green'],
	['990066', 'Fresh Eggplant'],
	['991199', 'Violet Eggplant'],
	['991613', 'Tamarillo'],
	['991B07', 'Totem Pole'],
	['996666', 'Copper Rose'],
	['9966CC', 'Amethyst'],
	['997A8D', 'Mountbatten Pink'],
	['9999CC', 'Blue Bell'],
	['9A3820', 'Prairie Sand'],
	['9A6E61', 'Toast'],
	['9A9577', 'Gurkha'],
	['9AB973', 'Olivine'],
	['9AC2B8', 'Shadow Green'],
	['9B4703', 'Oregon'],
	['9B9E8F', 'Lemon Grass'],
	['9C3336', 'Stiletto'],
	['9D5616', 'Hawaiian Tan'],
	['9DACB7', 'Gull Gray'],
	['9DC209', 'Pistachio'],
	['9DE093', 'Granny Smith Apple'],
	['9DE5FF', 'Anakiwa'],
	['9E5302', 'Chelsea Gem'],
	['9E5B40', 'Sepia Skin'],
	['9EA587', 'Sage'],
	['9EA91F', 'Citron'],
	['9EB1CD', 'Rock Blue'],
	['9EDEE0', 'Morning Glory'],
	['9F381D', 'Cognac'],
	['9F821C', 'Reef Gold'],
	['9F9F9C', 'Star Dust'],
	['9FA0B1', 'Santas Gray'],
	['9FD7D3', 'Sinbad'],
	['9FDD8C', 'Feijoa'],
	['A02712', 'Tabasco'],
	['A1750D', 'Buttered Rum'],
	['A1ADB5', 'Hit Gray'],
	['A1C50A', 'Citrus'],
	['A1DAD7', 'Aqua Island'],
	['A1E9DE', 'Water Leaf'],
	['A2006D', 'Flirt'],
	['A23B6C', 'Rouge'],
	['A26645', 'Cape Palliser'],
	['A2AAB3', 'Gray Chateau'],
	['A2AEAB', 'Edward'],
	['A3807B', 'Pharlap'],
	['A397B4', 'Amethyst Smoke'],
	['A3E3ED', 'Blizzard Blue'],
	['A4A49D', 'Delta'],
	['A4A6D3', 'Wistful'],
	['A4AF6E', 'Green Smoke'],
	['A50B5E', 'Jazzberry Jam'],
	['A59B91', 'Zorba'],
	['A5CB0C', 'Bahia'],
	['A62F20', 'Roof Terracotta'],
	['A65529', 'Paarl'],
	['A68B5B', 'Barley Corn'],
	['A69279', 'Donkey Brown'],
	['A6A29A', 'Dawn'],
	['A72525', 'Mexican Red'],
	['A7882C', 'Luxor Gold'],
	['A85307', 'Rich Gold'],
	['A86515', 'Reno Sand'],
	['A86B6B', 'Coral Tree'],
	['A8989B', 'Dusty Gray'],
	['A899E6', 'Dull Lavender'],
	['A8A589', 'Tallow'],
	['A8AE9C', 'Bud'],
	['A8AF8E', 'Locust'],
	['A8BD9F', 'Norway'],
	['A8E3BD', 'Chinook'],
	['A9A491', 'Gray Olive'],
	['A9ACB6', 'Aluminium'],
	['A9B2C3', 'Cadet Blue'],
	['A9B497', 'Schist'],
	['A9BDBF', 'Tower Gray'],
	['A9BEF2', 'Perano'],
	['A9C6C2', 'Opal'],
	['AA375A', 'Night Shadz'],
	['AA4203', 'Fire'],
	['AA8B5B', 'Muesli'],
	['AA8D6F', 'Sandal'],
	['AAA5A9', 'Shady Lady'],
	['AAA9CD', 'Logan'],
	['AAABB7', 'Spun Pearl'],
	['AAD6E6', 'Regent St Blue'],
	['AAF0D1', 'Magic Mint'],
	['AB0563', 'Lipstick'],
	['AB3472', 'Royal Heath'],
	['AB917A', 'Sandrift'],
	['ABA0D9', 'Cold Purple'],
	['ABA196', 'Bronco'],
	['AC8A56', 'Limed Oak'],
	['AC91CE', 'East Side'],
	['AC9E22', 'Lemon Ginger'],
	['ACA494', 'Napa'],
	['ACA586', 'Hillary'],
	['ACA59F', 'Cloudy'],
	['ACACAC', 'Silver Chalice'],
	['ACB78E', 'Swamp Green'],
	['ACCBB1', 'Spring Rain'],
	['ACDD4D', 'Conifer'],
	['ACE1AF', 'Celadon'],
	['AD781B', 'Mandalay'],
	['ADBED1', 'Casper'],
	['ADDFAD', 'Moss Green'],
	['ADE6C4', 'Padua'],
	['ADFF2F', 'Green Yellow'],
	['AE4560', 'Hippie Pink'],
	['AE6020', 'Desert'],
	['AE809E', 'Bouquet'],
	['AF4035', 'Medium Carmine'],
	['AF4D43', 'Apple Blossom'],
	['AF593E', 'Brown Rust'],
	['AF8751', 'Driftwood'],
	['AF8F2C', 'Alpine'],
	['AF9F1C', 'Lucky'],
	['AFA09E', 'Martini'],
	['AFB1B8', 'Bombay'],
	['AFBDD9', 'Pigeon Post'],
	['B04C6A', 'Cadillac'],
	['B05D54', 'Matrix'],
	['B05E81', 'Tapestry'],
	['B06608', 'Mai Tai'],
	['B09A95', 'Del Rio'],
	['B0E0E6', 'Powder Blue'],
	['B0E313', 'Inch Worm'],
	['B10000', 'Bright Red'],
	['B14A0B', 'Vesuvius'],
	['B1610B', 'Pumpkin Skin'],
	['B16D52', 'Santa Fe'],
	['B19461', 'Teak'],
	['B1E2C1', 'Fringy Flower'],
	['B1F4E7', 'Ice Cold'],
	['B20931', 'Shiraz'],
	['B2A1EA', 'Biloba Flower'],
	['B32D29', 'Tall Poppy'],
	['B35213', 'Fiery Orange'],
	['B38007', 'Hot Toddy'],
	['B3AF95', 'Taupe Gray'],
	['B3C110', 'La Rioja'],
	['B43332', 'Well Read'],
	['B44668', 'Blush'],
	['B4CFD3', 'Jungle Mist'],
	['B57281', 'Turkish Rose'],
	['B57EDC', 'Lavender'],
	['B5A27F', 'Mongoose'],
	['B5B35C', 'Olive Green'],
	['B5D2CE', 'Jet Stream'],
	['B5ECDF', 'Cruise'],
	['B6316C', 'Hibiscus'],
	['B69D98', 'Thatch'],
	['B6B095', 'Heathered Gray'],
	['B6BAA4', 'Eagle'],
	['B6D1EA', 'Spindle'],
	['B6D3BF', 'Gum Leaf'],
	['B7410E', 'Rust'],
	['B78E5C', 'Muddy Waters'],
	['B7A214', 'Sahara'],
	['B7A458', 'Husk'],
	['B7B1B1', 'Nobel'],
	['B7C3D0', 'Heather'],
	['B7F0BE', 'Madang'],
	['B81104', 'Milano Red'],
	['B87333', 'Copper'],
	['B8B56A', 'Gimblet'],
	['B8C1B1', 'Green Spring'],
	['B8C25D', 'Celery'],
	['B8E0F9', 'Sail'],
	['B94E48', 'Chestnut'],
	['B95140', 'Crail'],
	['B98D28', 'Marigold'],
	['B9C46A', 'Wild Willow'],
	['B9C8AC', 'Rainee'],
	['BA0101', 'Guardsman Red'],
	['BA450C', 'Rock Spray'],
	['BA6F1E', 'Bourbon'],
	['BA7F03', 'Pirate Gold'],
	['BAB1A2', 'Nomad'],
	['BAC7C9', 'Submarine'],
	['BAEEF9', 'Charlotte'],
	['BB3385', 'Medium Red Violet'],
	['BB8983', 'Brandy Rose'],
	['BBD009', 'Rio Grande'],
	['BBD7C1', 'Surf'],
	['BCC9C2', 'Powder Ash'],
	['BD5E2E', 'Tuscany'],
	['BD978E', 'Quicksand'],
	['BDB1A8', 'Silk'],
	['BDB2A1', 'Malta'],
	['BDB3C7', 'Chatelle'],
	['BDBBD7', 'Lavender Gray'],
	['BDBDC6', 'French Gray'],
	['BDC8B3', 'Clay Ash'],
	['BDC9CE', 'Loblolly'],
	['BDEDFD', 'French Pass'],
	['BEA6C3', 'London Hue'],
	['BEB5B7', 'Pink Swan'],
	['BEDE0D', 'Fuego'],
	['BF5500', 'Rose of Sharon'],
	['BFB8B0', 'Tide'],
	['BFBED8', 'Blue Haze'],
	['BFC1C2', 'Silver Sand'],
	['BFC921', 'Key Lime Pie'],
	['BFDBE2', 'Ziggurat'],
	['BFFF00', 'Lime'],
	['C02B18', 'Thunderbird'],
	['C04737', 'Mojo'],
	['C08081', 'Old Rose'],
	['C0C0C0', 'Silver'],
	['C0D3B9', 'Pale Leaf'],
	['C0D8B6', 'Pixie Green'],
	['C1440E', 'Tia Maria'],
	['C154C1', 'Fuchsia Pink'],
	['C1A004', 'Buddha Gold'],
	['C1B7A4', 'Bison Hide'],
	['C1BAB0', 'Tea'],
	['C1BECD', 'Gray Suit'],
	['C1D7B0', 'Sprout'],
	['C1F07C', 'Sulu'],
	['C26B03', 'Indochine'],
	['C2955D', 'Twine'],
	['C2BDB6', 'Cotton Seed'],
	['C2CAC4', 'Pumice'],
	['C2E8E5', 'Jagged Ice'],
	['C32148', 'Maroon Flush'],
	['C3B091', 'Indian Khaki'],
	['C3BFC1', 'Pale Slate'],
	['C3C3BD', 'Gray Nickel'],
	['C3CDE6', 'Periwinkle Gray'],
	['C3D1D1', 'Tiara'],
	['C3DDF9', 'Tropical Blue'],
	['C41E3A', 'Cardinal'],
	['C45655', 'Fuzzy Wuzzy Brown'],
	['C45719', 'Orange Roughy'],
	['C4C4BC', 'Mist Gray'],
	['C4D0B0', 'Coriander'],
	['C4F4EB', 'Mint Tulip'],
	['C54B8C', 'Mulberry'],
	['C59922', 'Nugget'],
	['C5994B', 'Tussock'],
	['C5DBCA', 'Sea Mist'],
	['C5E17A', 'Yellow Green'],
	['C62D42', 'Brick Red'],
	['C6726B', 'Contessa'],
	['C69191', 'Oriental Pink'],
	['C6A84B', 'Roti'],
	['C6C3B5', 'Ash'],
	['C6C8BD', 'Kangaroo'],
	['C6E610', 'Las Palmas'],
	['C7031E', 'Monza'],
	['C71585', 'Red Violet'],
	['C7BCA2', 'Coral Reef'],
	['C7C1FF', 'Melrose'],
	['C7C4BF', 'Cloud'],
	['C7C9D5', 'Ghost'],
	['C7CD90', 'Pine Glade'],
	['C7DDE5', 'Botticelli'],
	['C88A65', 'Antique Brass'],
	['C8A2C8', 'Lilac'],
	['C8A528', 'Hokey Pokey'],
	['C8AABF', 'Lily'],
	['C8B568', 'Laser'],
	['C8E3D7', 'Edgewater'],
	['C96323', 'Piper'],
	['C99415', 'Pizza'],
	['C9A0DC', 'Light Wisteria'],
	['C9B29B', 'Rodeo Dust'],
	['C9B35B', 'Sundance'],
	['C9B93B', 'Earls Green'],
	['C9C0BB', 'Silver Rust'],
	['C9D9D2', 'Conch'],
	['C9FFA2', 'Reef'],
	['C9FFE5', 'Aero Blue'],
	['CA3435', 'Flush Mahogany'],
	['CABB48', 'Turmeric'],
	['CADCD4', 'Paris White'],
	['CAE00D', 'Bitter Lemon'],
	['CAE6DA', 'Skeptic'],
	['CB8FA9', 'Viola'],
	['CBCAB6', 'Foggy Gray'],
	['CBD3B0', 'Green Mist'],
	['CBDBD6', 'Nebula'],
	['CC3333', 'Persian Red'],
	['CC5500', 'Burnt Orange'],
	['CC7722', 'Ochre'],
	['CC8899', 'Puce'],
	['CCCAA8', 'Thistle Green'],
	['CCCCFF', 'Periwinkle'],
	['CCFF00', 'Electric Lime'],
	['CD5700', 'Tenn'],
	['CD5C5C', 'Chestnut Rose'],
	['CD8429', 'Brandy Punch'],
	['CDF4FF', 'Onahau'],
	['CEB98F', 'Sorrell Brown'],
	['CEBABA', 'Cold Turkey'],
	['CEC291', 'Yuma'],
	['CEC7A7', 'Chino'],
	['CFA39D', 'Eunry'],
	['CFB53B', 'Old Gold'],
	['CFDCCF', 'Tasman'],
	['CFE5D2', 'Surf Crest'],
	['CFF9F3', 'Humming Bird'],
	['CFFAF4', 'Scandal'],
	['D05F04', 'Red Stage'],
	['D06DA1', 'Hopbush'],
	['D07D12', 'Meteor'],
	['D0BEF8', 'Perfume'],
	['D0C0E5', 'Prelude'],
	['D0F0C0', 'Tea Green'],
	['D18F1B', 'Geebung'],
	['D1BEA8', 'Vanilla'],
	['D1C6B4', 'Soft Amber'],
	['D1D2CA', 'Celeste'],
	['D1D2DD', 'Mischka'],
	['D1E231', 'Pear'],
	['D2691E', 'Hot Cinnamon'],
	['D27D46', 'Raw Sienna'],
	['D29EAA', 'Careys Pink'],
	['D2B48C', 'Tan'],
	['D2DA97', 'Deco'],
	['D2F6DE', 'Blue Romance'],
	['D2F8B0', 'Gossip'],
	['D3CBBA', 'Sisal'],
	['D3CDC5', 'Swirl'],
	['D47494', 'Charm'],
	['D4B6AF', 'Clam Shell'],
	['D4BF8D', 'Straw'],
	['D4C4A8', 'Akaroa'],
	['D4CD16', 'Bird Flower'],
	['D4D7D9', 'Iron'],
	['D4DFE2', 'Geyser'],
	['D4E2FC', 'Hawkes Blue'],
	['D54600', 'Grenadier'],
	['D591A4', 'Can Can'],
	['D59A6F', 'Whiskey'],
	['D5D195', 'Winter Hazel'],
	['D5F6E3', 'Granny Apple'],
	['D69188', 'My Pink'],
	['D6C562', 'Tacha'],
	['D6CEF6', 'Moon Raker'],
	['D6D6D1', 'Quill Gray'],
	['D6FFDB', 'Snowy Mint'],
	['D7837F', 'New York Pink'],
	['D7C498', 'Pavlova'],
	['D7D0FF', 'Fog'],
	['D84437', 'Valencia'],
	['D87C63', 'Japonica'],
	['D8BFD8', 'Thistle'],
	['D8C2D5', 'Maverick'],
	['D8FCFA', 'Foam'],
	['D94972', 'Cabaret'],
	['D99376', 'Burning Sand'],
	['D9B99B', 'Cameo'],
	['D9D6CF', 'Timberwolf'],
	['D9DCC1', 'Tana'],
	['D9E4F5', 'Link Water'],
	['D9F7FF', 'Mabel'],
	['DA3287', 'Cerise'],
	['DA5B38', 'Flame Pea'],
	['DA6304', 'Bamboo'],
	['DA6A41', 'Red Damask'],
	['DA70D6', 'Orchid'],
	['DA8A67', 'Copperfield'],
	['DAA520', 'Golden Grass'],
	['DAECD6', 'Zanah'],
	['DAF4F0', 'Iceberg'],
	['DAFAFF', 'Oyster Bay'],
	['DB5079', 'Cranberry'],
	['DB9690', 'Petite Orchid'],
	['DB995E', 'Di Serria'],
	['DBDBDB', 'Alto'],
	['DBFFF8', 'Frosted Mint'],
	['DC143C', 'Crimson'],
	['DC4333', 'Punch'],
	['DCB20C', 'Galliano'],
	['DCB4BC', 'Blossom'],
	['DCD747', 'Wattle'],
	['DCD9D2', 'Westar'],
	['DCDDCC', 'Moon Mist'],
	['DCEDB4', 'Caper'],
	['DCF0EA', 'Swans Down'],
	['DDD6D5', 'Swiss Coffee'],
	['DDF9F1', 'White Ice'],
	['DE3163', 'Cerise Red'],
	['DE6360', 'Roman'],
	['DEA681', 'Tumbleweed'],
	['DEBA13', 'Gold Tips'],
	['DEC196', 'Brandy'],
	['DECBC6', 'Wafer'],
	['DED4A4', 'Sapling'],
	['DED717', 'Barberry'],
	['DEE5C0', 'Beryl Green'],
	['DEF5FF', 'Pattens Blue'],
	['DF73FF', 'Heliotrope'],
	['DFBE6F', 'Apache'],
	['DFCD6F', 'Chenin'],
	['DFCFDB', 'Lola'],
	['DFECDA', 'Willow Brook'],
	['DFFF00', 'Chartreuse Yellow'],
	['E0B0FF', 'Mauve'],
	['E0B646', 'Anzac'],
	['E0B974', 'Harvest Gold'],
	['E0C095', 'Calico'],
	['E0FFFF', 'Baby Blue'],
	['E16865', 'Sunglo'],
	['E1BC64', 'Equator'],
	['E1C0C8', 'Pink Flare'],
	['E1E6D6', 'Periglacial Blue'],
	['E1EAD4', 'Kidnapper'],
	['E1F6E8', 'Tara'],
	['E25465', 'Mandy'],
	['E2725B', 'Terracotta'],
	['E28913', 'Golden Bell'],
	['E292C0', 'Shocking'],
	['E29418', 'Dixie'],
	['E29CD2', 'Light Orchid'],
	['E2D8ED', 'Snuff'],
	['E2EBED', 'Mystic'],
	['E2F3EC', 'Apple Green'],
	['E30B5C', 'Razzmatazz'],
	['E32636', 'Alizarin Crimson'],
	['E34234', 'Cinnabar'],
	['E3BEBE', 'Cavern Pink'],
	['E3F5E1', 'Peppermint'],
	['E3F988', 'Mindaro'],
	['E47698', 'Deep Blush'],
	['E49B0F', 'Gamboge'],
	['E4C2D5', 'Melanie'],
	['E4CFDE', 'Twilight'],
	['E4D1C0', 'Bone'],
	['E4D422', 'Sunflower'],
	['E4D5B7', 'Grain Brown'],
	['E4D69B', 'Zombie'],
	['E4F6E7', 'Frostee'],
	['E4FFD1', 'Snow Flurry'],
	['E52B50', 'Amaranth'],
	['E5841B', 'Zest'],
	['E5CCC9', 'Dust Storm'],
	['E5D7BD', 'Stark White'],
	['E5D8AF', 'Hampton'],
	['E5E0E1', 'Bon Jour'],
	['E5E5E5', 'Mercury'],
	['E5F9F6', 'Polar'],
	['E64E03', 'Trinidad'],
	['E6BE8A', 'Gold Sand'],
	['E6BEA5', 'Cashmere'],
	['E6D7B9', 'Double Spanish White'],
	['E6E4D4', 'Satin Linen'],
	['E6F2EA', 'Harp'],
	['E6F8F3', 'Off Green'],
	['E6FFE9', 'Hint of Green'],
	['E6FFFF', 'Tranquil'],
	['E77200', 'Mango Tango'],
	['E7730A', 'Christine'],
	['E79F8C', 'Tonys Pink'],
	['E79FC4', 'Kobi'],
	['E7BCB4', 'Rose Fog'],
	['E7BF05', 'Corn'],
	['E7CD8C', 'Putty'],
	['E7ECE6', 'Gray Nurse'],
	['E7F8FF', 'Lily White'],
	['E7FEFF', 'Bubbles'],
	['E89928', 'Fire Bush'],
	['E8B9B3', 'Shilo'],
	['E8E0D5', 'Pearl Bush'],
	['E8EBE0', 'Green White'],
	['E8F1D4', 'Chrome White'],
	['E8F2EB', 'Gin'],
	['E8F5F2', 'Aqua Squeeze'],
	['E96E00', 'Clementine'],
	['E97451', 'Burnt Sienna'],
	['E97C07', 'Tahiti Gold'],
	['E9CECD', 'Oyster Pink'],
	['E9D75A', 'Confetti'],
	['E9E3E3', 'Ebb'],
	['E9F8ED', 'Ottoman'],
	['E9FFFD', 'Clear Day'],
	['EA88A8', 'Carissma'],
	['EAAE69', 'Porsche'],
	['EAB33B', 'Tulip Tree'],
	['EAC674', 'Rob Roy'],
	['EADAB8', 'Raffia'],
	['EAE8D4', 'White Rock'],
	['EAF6EE', 'Panache'],
	['EAF6FF', 'Solitude'],
	['EAF9F5', 'Aqua Spring'],
	['EAFFFE', 'Dew'],
	['EB9373', 'Apricot'],
	['EBC2AF', 'Zinnwaldite'],
	['ECA927', 'Fuel Yellow'],
	['ECC54E', 'Ronchi'],
	['ECC7EE', 'French Lilac'],
	['ECCDB9', 'Just Right'],
	['ECE090', 'Wild Rice'],
	['ECEBBD', 'Fall Green'],
	['ECEBCE', 'Aths Special'],
	['ECF245', 'Starship'],
	['ED0A3F', 'Red Ribbon'],
	['ED7A1C', 'Tango'],
	['ED9121', 'Carrot Orange'],
	['ED989E', 'Sea Pink'],
	['EDB381', 'Tacao'],
	['EDC9AF', 'Desert Sand'],
	['EDCDAB', 'Pancho'],
	['EDDCB1', 'Chamois'],
	['EDEA99', 'Primrose'],
	['EDF5DD', 'Frost'],
	['EDF5F5', 'Aqua Haze'],
	['EDF6FF', 'Zumthor'],
	['EDF9F1', 'Narvik'],
	['EDFC84', 'Honeysuckle'],
	['EE82EE', 'Lavender Magenta'],
	['EEC1BE', 'Beauty Bush'],
	['EED794', 'Chalky'],
	['EED9C4', 'Almond'],
	['EEDC82', 'Flax'],
	['EEDEDA', 'Bizarre'],
	['EEE3AD', 'Double Colonial White'],
	['EEEEE8', 'Cararra'],
	['EEEF78', 'Manz'],
	['EEF0C8', 'Tahuna Sands'],
	['EEF0F3', 'Athens Gray'],
	['EEF3C3', 'Tusk'],
	['EEF4DE', 'Loafer'],
	['EEF6F7', 'Catskill White'],
	['EEFDFF', 'Twilight Blue'],
	['EEFF9A', 'Jonquil'],
	['EEFFE2', 'Rice Flower'],
	['EF863F', 'Jaffa'],
	['EFEFEF', 'Gallery'],
	['EFF2F3', 'Porcelain'],
	['F091A9', 'Mauvelous'],
	['F0D52D', 'Golden Dream'],
	['F0DB7D', 'Golden Sand'],
	['F0DC82', 'Buff'],
	['F0E2EC', 'Prim'],
	['F0E68C', 'Khaki'],
	['F0EEFD', 'Selago'],
	['F0EEFF', 'Titan White'],
	['F0F8FF', 'Alice Blue'],
	['F0FCEA', 'Feta'],
	['F18200', 'Gold Drop'],
	['F19BAB', 'Wewak'],
	['F1E788', 'Sahara Sand'],
	['F1E9D2', 'Parchment'],
	['F1E9FF', 'Blue Chalk'],
	['F1EEC1', 'Mint Julep'],
	['F1F1F1', 'Seashell'],
	['F1F7F2', 'Saltpan'],
	['F1FFAD', 'Tidal'],
	['F1FFC8', 'Chiffon'],
	['F2552A', 'Flamingo'],
	['F28500', 'Tangerine'],
	['F2C3B2', 'Mandys Pink'],
	['F2F2F2', 'Concrete'],
	['F2FAFA', 'Black Squeeze'],
	['F34723', 'Pomegranate'],
	['F3AD16', 'Buttercup'],
	['F3D69D', 'New Orleans'],
	['F3D9DF', 'Vanilla Ice'],
	['F3E7BB', 'Sidecar'],
	['F3E9E5', 'Dawn Pink'],
	['F3EDCF', 'Wheatfield'],
	['F3FB62', 'Canary'],
	['F3FBD4', 'Orinoco'],
	['F3FFD8', 'Carla'],
	['F400A1', 'Hollywood Cerise'],
	['F4A460', 'Sandy brown'],
	['F4C430', 'Saffron'],
	['F4D81C', 'Ripe Lemon'],
	['F4EBD3', 'Janna'],
	['F4F2EE', 'Pampas'],
	['F4F4F4', 'Wild Sand'],
	['F4F8FF', 'Zircon'],
	['F57584', 'Froly'],
	['F5C85C', 'Cream Can'],
	['F5C999', 'Manhattan'],
	['F5D5A0', 'Maize'],
	['F5DEB3', 'Wheat'],
	['F5E7A2', 'Sandwisp'],
	['F5E7E2', 'Pot Pourri'],
	['F5E9D3', 'Albescent White'],
	['F5EDEF', 'Soft Peach'],
	['F5F3E5', 'Ecru White'],
	['F5F5DC', 'Beige'],
	['F5FB3D', 'Golden Fizz'],
	['F5FFBE', 'Australian Mint'],
	['F64A8A', 'French Rose'],
	['F653A6', 'Brilliant Rose'],
	['F6A4C9', 'Illusion'],
	['F6F0E6', 'Merino'],
	['F6F7F7', 'Black Haze'],
	['F6FFDC', 'Spring Sun'],
	['F7468A', 'Violet Red'],
	['F77703', 'Chilean Fire'],
	['F77FBE', 'Persian Pink'],
	['F7B668', 'Rajah'],
	['F7C8DA', 'Azalea'],
	['F7DBE6', 'We Peep'],
	['F7F2E1', 'Quarter Spanish White'],
	['F7F5FA', 'Whisper'],
	['F7FAF7', 'Snow Drift'],
	['F8B853', 'Casablanca'],
	['F8C3DF', 'Chantilly'],
	['F8D9E9', 'Cherub'],
	['F8DB9D', 'Marzipan'],
	['F8DD5C', 'Energy Yellow'],
	['F8E4BF', 'Givry'],
	['F8F0E8', 'White Linen'],
	['F8F4FF', 'Magnolia'],
	['F8F6F1', 'Spring Wood'],
	['F8F7DC', 'Coconut Cream'],
	['F8F7FC', 'White Lilac'],
	['F8F8F7', 'Desert Storm'],
	['F8F99C', 'Texas'],
	['F8FACD', 'Corn Field'],
	['F8FDD3', 'Mimosa'],
	['F95A61', 'Carnation'],
	['F9BF58', 'Saffron Mango'],
	['F9E0ED', 'Carousel Pink'],
	['F9E4BC', 'Dairy Cream'],
	['F9E663', 'Portica'],
	['F9EAF3', 'Amour'],
	['F9F8E4', 'Rum Swizzle'],
	['F9FF8B', 'Dolly'],
	['F9FFF6', 'Sugar Cane'],
	['FA7814', 'Ecstasy'],
	['FA9D5A', 'Tan Hide'],
	['FAD3A2', 'Corvette'],
	['FADFAD', 'Peach Yellow'],
	['FAE600', 'Turbo'],
	['FAEAB9', 'Astra'],
	['FAECCC', 'Champagne'],
	['FAF0E6', 'Linen'],
	['FAF3F0', 'Fantasy'],
	['FAF7D6', 'Citrine White'],
	['FAFAFA', 'Alabaster'],
	['FAFDE4', 'Hint of Yellow'],
	['FAFFA4', 'Milan'],
	['FB607F', 'Brink Pink'],
	['FB8989', 'Geraldine'],
	['FBA0E3', 'Lavender Rose'],
	['FBA129', 'Sea Buckthorn'],
	['FBAC13', 'Sun'],
	['FBAED2', 'Lavender Pink'],
	['FBB2A3', 'Rose Bud'],
	['FBBEDA', 'Cupid'],
	['FBCCE7', 'Classic Rose'],
	['FBCEB1', 'Apricot Peach'],
	['FBE7B2', 'Banana Mania'],
	['FBE870', 'Marigold Yellow'],
	['FBE96C', 'Festival'],
	['FBEA8C', 'Sweet Corn'],
	['FBEC5D', 'Candy Corn'],
	['FBF9F9', 'Hint of Red'],
	['FBFFBA', 'Shalimar'],
	['FC0FC0', 'Shocking Pink'],
	['FC80A5', 'Tickle Me Pink'],
	['FC9C1D', 'Tree Poppy'],
	['FCC01E', 'Lightning Yellow'],
	['FCD667', 'Goldenrod'],
	['FCD917', 'Candlelight'],
	['FCDA98', 'Cherokee'],
	['FCF4D0', 'Double Pearl Lusta'],
	['FCF4DC', 'Pearl Lusta'],
	['FCF8F7', 'Vista White'],
	['FCFBF3', 'Bianca'],
	['FCFEDA', 'Moon Glow'],
	['FCFFE7', 'China Ivory'],
	['FCFFF9', 'Ceramic'],
	['FD0E35', 'Torch Red'],
	['FD5B78', 'Wild Watermelon'],
	['FD7B33', 'Crusta'],
	['FD7C07', 'Sorbus'],
	['FD9FA2', 'Sweet Pink'],
	['FDD5B1', 'Light Apricot'],
	['FDD7E4', 'Pig Pink'],
	['FDE1DC', 'Cinderella'],
	['FDE295', 'Golden Glow'],
	['FDE910', 'Lemon'],
	['FDF5E6', 'Old Lace'],
	['FDF6D3', 'Half Colonial White'],
	['FDF7AD', 'Drover'],
	['FDFEB8', 'Pale Prim'],
	['FDFFD5', 'Cumulus'],
	['FE28A2', 'Persian Rose'],
	['FE4C40', 'Sunset Orange'],
	['FE6F5E', 'Bittersweet'],
	['FE9D04', 'California'],
	['FEA904', 'Yellow Sea'],
	['FEBAAD', 'Melon'],
	['FED33C', 'Bright Sun'],
	['FED85D', 'Dandelion'],
	['FEDB8D', 'Salomie'],
	['FEE5AC', 'Cape Honey'],
	['FEEBF3', 'Remy'],
	['FEEFCE', 'Oasis'],
	['FEF0EC', 'Bridesmaid'],
	['FEF2C7', 'Beeswax'],
	['FEF3D8', 'Bleach White'],
	['FEF4CC', 'Pipi'],
	['FEF4DB', 'Half Spanish White'],
	['FEF4F8', 'Wisp Pink'],
	['FEF5F1', 'Provincial Pink'],
	['FEF7DE', 'Half Dutch White'],
	['FEF8E2', 'Solitaire'],
	['FEF8FF', 'White Pointer'],
	['FEF9E3', 'Off Yellow'],
	['FEFCED', 'Orange White'],
	['FF0000', 'Red'],
	['FF007F', 'Rose'],
	['FF00CC', 'Purple Pizzazz'],
	['FF00FF', 'Magenta / Fuchsia'],
	['FF2400', 'Scarlet'],
	['FF3399', 'Wild Strawberry'],
	['FF33CC', 'Razzle Dazzle Rose'],
	['FF355E', 'Radical Red'],
	['FF3F34', 'Red Orange'],
	['FF4040', 'Coral Red'],
	['FF4D00', 'Vermilion'],
	['FF4F00', 'International Orange'],
	['FF6037', 'Outrageous Orange'],
	['FF6600', 'Blaze Orange'],
	['FF66FF', 'Pink Flamingo'],
	['FF681F', 'Orange'],
	['FF69B4', 'Hot Pink'],
	['FF6B53', 'Persimmon'],
	['FF6FFF', 'Blush Pink'],
	['FF7034', 'Burning Orange'],
	['FF7518', 'Pumpkin'],
	['FF7D07', 'Flamenco'],
	['FF7F00', 'Flush Orange'],
	['FF7F50', 'Coral'],
	['FF8C69', 'Salmon'],
	['FF9000', 'Pizazz'],
	['FF910F', 'West Side'],
	['FF91A4', 'Pink Salmon'],
	['FF9933', 'Neon Carrot'],
	['FF9966', 'Atomic Tangerine'],
	['FF9980', 'Vivid Tangerine'],
	['FF9E2C', 'Sunshade'],
	['FFA000', 'Orange Peel'],
	['FFA194', 'Mona Lisa'],
	['FFA500', 'Web Orange'],
	['FFA6C9', 'Carnation Pink'],
	['FFAB81', 'Hit Pink'],
	['FFAE42', 'Yellow Orange'],
	['FFB0AC', 'Cornflower Lilac'],
	['FFB1B3', 'Sundown'],
	['FFB31F', 'My Sin'],
	['FFB555', 'Texas Rose'],
	['FFB7D5', 'Cotton Candy'],
	['FFB97B', 'Macaroni and Cheese'],
	['FFBA00', 'Selective Yellow'],
	['FFBD5F', 'Koromiko'],
	['FFBF00', 'Amber'],
	['FFC0A8', 'Wax Flower'],
	['FFC0CB', 'Pink'],
	['FFC3C0', 'Your Pink'],
	['FFC901', 'Supernova'],
	['FFCBA4', 'Flesh'],
	['FFCC33', 'Sunglow'],
	['FFCC5C', 'Golden Tainoi'],
	['FFCC99', 'Peach Orange'],
	['FFCD8C', 'Chardonnay'],
	['FFD1DC', 'Pastel Pink'],
	['FFD2B7', 'Romantic'],
	['FFD38C', 'Grandis'],
	['FFD700', 'Gold'],
	['FFD800', 'School bus Yellow'],
	['FFD8D9', 'Cosmos'],
	['FFDB58', 'Mustard'],
	['FFDCD6', 'Peach Schnapps'],
	['FFDDAF', 'Caramel'],
	['FFDDCD', 'Tuft Bush'],
	['FFDDCF', 'Watusi'],
	['FFDDF4', 'Pink Lace'],
	['FFDEAD', 'Navajo White'],
	['FFDEB3', 'Frangipani'],
	['FFE1DF', 'Pippin'],
	['FFE1F2', 'Pale Rose'],
	['FFE2C5', 'Negroni'],
	['FFE5A0', 'Cream Brulee'],
	['FFE5B4', 'Peach'],
	['FFE6C7', 'Tequila'],
	['FFE772', 'Kournikova'],
	['FFEAC8', 'Sandy Beach'],
	['FFEAD4', 'Karry'],
	['FFEC13', 'Broom'],
	['FFEDBC', 'Colonial White'],
	['FFEED8', 'Derby'],
	['FFEFA1', 'Vis Vis'],
	['FFEFC1', 'Egg White'],
	['FFEFD5', 'Papaya Whip'],
	['FFEFEC', 'Fair Pink'],
	['FFF0DB', 'Peach Cream'],
	['FFF0F5', 'Lavender blush'],
	['FFF14F', 'Gorse'],
	['FFF1B5', 'Buttermilk'],
	['FFF1D8', 'Pink Lady'],
	['FFF1EE', 'Forget Me Not'],
	['FFF1F9', 'Tutu'],
	['FFF39D', 'Picasso'],
	['FFF3F1', 'Chardon'],
	['FFF46E', 'Paris Daisy'],
	['FFF4CE', 'Barley White'],
	['FFF4DD', 'Egg Sour'],
	['FFF4E0', 'Sazerac'],
	['FFF4E8', 'Serenade'],
	['FFF4F3', 'Chablis'],
	['FFF5EE', 'Seashell Peach'],
	['FFF5F3', 'Sauvignon'],
	['FFF6D4', 'Milk Punch'],
	['FFF6DF', 'Varden'],
	['FFF6F5', 'Rose White'],
	['FFF8D1', 'Baja White'],
	['FFF9E2', 'Gin Fizz'],
	['FFF9E6', 'Early Dawn'],
	['FFFACD', 'Lemon Chiffon'],
	['FFFAF4', 'Bridal Heath'],
	['FFFBDC', 'Scotch Mist'],
	['FFFBF9', 'Soapstone'],
	['FFFC99', 'Witch Haze'],
	['FFFCEA', 'Buttery White'],
	['FFFCEE', 'Island Spice'],
	['FFFDD0', 'Cream'],
	['FFFDE6', 'Chilean Heath'],
	['FFFDE8', 'Travertine'],
	['FFFDF3', 'Orchid White'],
	['FFFDF4', 'Quarter Pearl Lusta'],
	['FFFEE1', 'Half and Half'],
	['FFFEEC', 'Apricot White'],
	['FFFEF0', 'Rice Cake'],
	['FFFEF6', 'Black White'],
	['FFFEFD', 'Romance'],
	['FFFF00', 'Yellow'],
	['FFFF66', 'Laser Lemon'],
	['FFFF99', 'Pale Canary'],
	['FFFFB4', 'Portafino'],
	['FFFFF0', 'Ivory'],
	['FFFFFF', 'White'],

	['5c2223', '暗玉紫'],
	['eea2a4', '牡丹粉红'],
	['5a191b', '栗紫'],
	['f07c82', '香叶红'],
	['5a1216', '葡萄酱紫'],
	['ed5a65', '艳红'],
	['c04851', '玉红'],
	['ee3f4d', '茶花红'],
	['c02c38', '高粱红'],
	['a7535a', '满江红'],
	['e3b4b8', '鼠鼻红'],
	['f0a1a8', '合欢红'],
	['f1939c', '春梅红'],
	['a61b29', '苋菜红'],
	['894e54', '烟红'],
	['c45a65', '莓红'],
	['d11a2d', '鹅冠红'],
	['c21f30', '枫叶红'],
	['de1c31', '唐菖蒲红'],
	['7c1823', '枣红'],
	['541e24', '猪肝紫'],
	['4c1f24', '葡萄紫'],
	['82202b', '暗紫苑红'],
	['82111f', '殷红'],
	['ef475d', '草茉莉红'],
	['4d1018', '酱紫'],
	['ed556a', '山茶红'],
	['7a7374', '锌灰'],
	['f03752', '海棠红'],
	['e6d2d5', '蓟粉红'],
	['f0c9cf', '石蕊红'],
	['ee2746', '淡曙红'],
	['2b1216', '李紫'],
	['ee4863', '石竹红'],
	['e77c8e', '淡茜红'],
	['500a16', '金鱼紫'],
	['c27c88', '山黎豆红'],
	['73575c', '鼠背灰'],
	['ee4866', '淡蕊香红'],
	['621624', '甘蔗紫'],
	['ce5777', '月季红'],
	['cc163a', '尖晶玉红'],
	['f1c4cd', '水红'],
	['eeb8c3', '姜红'],
	['856d72', '芦灰'],
	['2d0c13', '茄皮紫'],
	['36282b', '苍蝇灰'],
	['bf3553', '锦葵红'],
	['ec9bad', '粉团花红'],
	['63071c', '石竹紫'],
	['30161c', '卵石紫'],
	['eea6b7', '晶红'],
	['e9ccd3', '芝兰紫'],
	['eba0b3', '芍药耕红'],
	['4f383e', '暮云灰'],
	['ed9db2', '豇豆红'],
	['ec8aa4', '报春红'],
	['ec7696', '淡绛红'],
	['ea7293', '凤仙花红'],
	['ef82a0', '霞光红'],
	['ec2c64', '喜蛋红'],
	['eb507e', '夹竹桃红'],
	['eb3c70', '松叶牡丹红'],
	['ea517f', '莲瓣红'],
	['de7897', '白芨红'],
	['b598a1', '隐红灰'],
	['ed2f6a', '榲桲红'],
	['c5708b', '酢酱草红'],
	['33141e', '火鹅紫'],
	['621d34', '鹞冠紫'],
	['ef3473', '品红'],
	['382129', '磨石紫'],
	['310f1b', '墨紫'],
	['381924', '檀紫'],
	['e16c96', '初荷红'],
	['951c48', '菜头紫'],
	['62102e', '葡萄酒红'],
	['e0c8d1', '淡青紫'],
	['d13c74', '菠根红'],
	['4b1e2f', '海象紫'],
	['ec4e8a', '兔眼红'],
	['de3f7c', '嫩菱红'],
	['a8456b', '洋葱紫'],
	['ce5e8a', '吊钟花红'],
	['461629', '绀紫'],
	['ee2c79', '紫荆红'],
	['ef498b', '扁豆花红'],
	['ede3e7', '马鞭草紫'],
	['ec2d7a', '藏花红'],
	['482936', '斑鸠灰'],
	['440e25', '古铜紫'],
	['d2568c', '丹紫红'],
	['e9d7df', '丁香淡紫'],
	['d2357d', '玫瑰红'],
	['36292f', '古鼎灰'],
	['d276a3', '菱锰红'],
	['c06f98', '樱草紫'],
	['cc5595', '龙须红'],
	['c35691', '电气石红'],
	['ba2f7b', '玫瑰紫'],
	['9b1e64', '苋菜紫'],
	['5d3f51', '紫灰'],
	['4e2a40', '龙睛鱼紫'],
	['bc84a8', '青蛤壳紫'],
	['c08eaf', '萝兰紫'],
	['411c35', '荸荠紫'],
	['ad6598', '豆蔻紫'],
	['a35c8f', '扁豆紫'],
	['681752', '牵牛紫'],
	['894276', '芓紫'],
	['7e2065', '葛巾紫'],
	['8b2671', '青莲'],
	['983680', '芥花紫'],
	['c8adc4', '凤信紫'],
	['1c0d1a', '深牵牛紫'],
	['7e1671', '魏紫'],
	['1e131d', '乌梅紫'],
	['813c85', '桔梗紫'],
	['d1c2d3', '淡牵牛紫'],
	['3e3841', '剑锋紫'],
	['815c94', '蕈紫'],
	['806d9e', '槿紫'],
	['e2e1e4', '芡食白'],
	['322f3b', '龙葵紫'],
	['8076a3', '藤萝紫'],
	['35333c', '沙鱼灰'],
	['22202e', '暗龙胆紫'],
	['131124', '暗蓝紫'],
	['302f4b', '野葡萄紫'],
	['525288', '野菊紫'],
	['2f2f35', '水牛灰'],
	['ccccd6', '远山紫'],
	['74759b', '螺甸紫'],
	['1f2040', '晶石紫'],
	['2e317c', '满天星紫'],
	['a7a8bd', '淡蓝紫'],
	['61649f', '山梗紫'],
	['2d2e36', '牛角灰'],
	['5e616d', '鱼尾灰'],
	['47484c', '瓦罐灰'],
	['0f1423', '钢蓝'],
	['131824', '燕颔蓝'],
	['475164', '鲸鱼灰'],
	['2b333e', '青灰'],
	['1c2938', '鸽蓝'],
	['101f30', '暗蓝'],
	['142334', '钢青'],
	['15559a', '海涛蓝'],
	['0f59a4', '飞燕草蓝'],
	['1661ab', '靛青'],
	['3170a7', '安安蓝'],
	['346c9c', '海军蓝'],
	['2775b6', '景泰蓝'],
	['2b73af', '品蓝'],
	['2474b5', '尼罗蓝'],
	['4e7ca1', '蝶翅蓝'],
	['2376b7', '花青'],
	['144a74', '鷃蓝'],
	['93b5cf', '星蓝'],
	['2177b8', '虹蓝'],
	['126bae', '柏林蓝'],
	['1772b4', '群青'],
	['baccd9', '云水蓝'],
	['619ac3', '羽扇豆蓝'],
	['495c69', '战舰灰'],
	['8fb2c9', '晴山蓝'],
	['5698c3', '睛蓝'],
	['11659a', '搪磁蓝'],
	['2983bb', '潮蓝'],
	['1677b3', '天蓝'],
	['c4cbcf', '大理石灰'],
	['1177b0', '牵牛花蓝'],
	['2486b9', '宝石蓝'],
	['5e7987', '淡蓝灰'],
	['74787a', '嫩灰'],
	['cdd1d3', '银鱼白'],
	['1781b5', '釉蓝'],
	['66a9c9', '涧石蓝'],
	['d0dfe6', '远天蓝'],
	['2f90b9', '云山蓝'],
	['8abcd1', '秋波蓝'],
	['c3d7df', '井天蓝'],
	['158bb8', '鸢尾蓝'],
	['d8e3e7', '云峰白'],
	['b2bbbe', '星灰'],
	['1a94bc', '钴蓝'],
	['5cb3cc', '碧青'],
	['134857', '苍蓝'],
	['132c33', '深灰蓝'],
	['21373d', '灰蓝'],
	['b0d5df', '湖水蓝'],
	['22a2c3', '海青'],
	['474b4c', '黄昏灰'],
	['63bbd0', '霁青'],
	['126e82', '玉鈫蓝'],
	['0f95b0', '胆矾蓝'],
	['1491a8', '樫鸟蓝'],
	['c7d2d4', '鸥蓝'],
	['1e9eb3', '翠蓝'],
	['3b818c', '蜻蜓蓝'],
	['0eb0c9', '孔雀蓝'],
	['29b7cb', '蔚蓝'],
	['51c4d3', '瀑布蓝'],
	['7cabb1', '闪蓝'],
	['10aec2', '甸子蓝'],
	['648e93', '晚波蓝'],
	['93d5dc', '清水蓝'],
	['617172', '夏云灰'],
	['c6e6e8', '海天蓝'],
	['869d9d', '虾壳青'],
	['57c3c2', '石绿'],
	['c4d7d6', '穹灰'],
	['12aa9c', '美蝶绿'],
	['737c7b', '垩灰'],
	['12a182', '蓝绿'],
	['1ba784', '竹绿'],
	['428675', '亚丁绿'],
	['c0c4c3', '月影白'],
	['248067', '海王绿'],
	['1a3b32', '深海绿'],
	['314a43', '绿灰'],
	['2c9678', '青矾绿'],
	['223e36', '苍绿'],
	['497568', '飞泉绿'],
	['141e1b', '莽丛绿'],
	['69a794', '梧枝绿'],
	['2bae85', '铜绿'],
	['9abeaf', '草原远绿'],
	['45b787', '蛙绿'],
	['92b3a5', '浪花绿'],
	['1f2623', '苷蓝绿'],
	['83cbac', '粉绿'],
	['70887d', '淡绿灰'],
	['55bb8a', '麦苗绿'],
	['20a162', '翠绿'],
	['40a070', '葱绿'],
	['1a6840', '荷叶绿'],
	['61ac85', '淡绿'],
	['68b88e', '田园绿'],
	['a4cab6', '玉簪绿'],
	['3c9566', '蟾绿'],
	['5dbe8a', '蔻梢绿'],
	['207f4c', '薄荷绿'],
	['eef7f2', '月白'],
	['579572', '蛋白石绿'],
	['b9dec9', '竹篁绿'],
	['229453', '孔雀绿'],
	['20894d', '宫殿绿'],
	['15231b', '云杉绿'],
	['66c18c', '毛绿'],
	['a4aca7', '冰山蓝'],
	['8a988e', '明灰'],
	['9eccab', '明绿'],
	['83a78d', '松霜绿'],
	['485b4d', '白屈菜绿'],
	['5d655f', '狼烟灰'],
	['6e8b74', '瓦松绿'],
	['2b312c', '槲寄生绿'],
	['c6dfc8', '淡翠绿'],
	['41b349', '玉髓绿'],
	['43b244', '鲜绿'],
	['253d24', '油绿'],
	['41ae3c', '宝石绿'],
	['add5a2', '嘉陵水绿'],
	['5e665b', '田螺绿'],
	['8cc269', '水绿'],
	['5bae23', '鹦鹉绿'],
	['dfecd5', '艾背绿'],
	['cad3c3', '艾绿'],
	['9fa39a', '镍灰'],
	['b2cf87', '橄榄石绿'],
	['96c24e', '芽绿'],
	['f0f5e5', '嫩菊绿'],
	['b7d07a', '芦苇绿'],
	['d0deaa', '姚黄'],
	['373834', '蒽油绿'],
	['bacf65', '苹果绿'],
	['e2e7bf', '海沬绿'],
	['bec936', '橄榄黄绿'],
	['d2d97a', '槐花黄绿'],
	['e2d849', '蝶黄'],
	['fffef8', '象牙白'],
	['5e5314', '橄榄绿'],
	['fffef9', '雪白'],
	['ad9e5f', '淡灰绿'],
	['fed71a', '佛手黄'],
	['f9f4dc', '乳白'],
	['e4bf11', '香蕉黄'],
	['d2b116', '新禾绿'],
	['fbda41', '油菜花黄'],
	['eed045', '秋葵黄'],
	['f1ca17', '柚黄'],
	['d2b42c', '草黄'],
	['f2ce2b', '硫华黄'],
	['e2c027', '姜黄'],
	['645822', '潭水绿'],
	['fcd217', '金瓜黄'],
	['f8df70', '麦秆黄'],
	['dfc243', '蒿黄'],
	['f8df72', '茉莉黄'],
	['ffd111', '藤黄'],
	['ddc871', '芒果黄'],
	['fffefa', '海参灰'],
	['867018', '碧螺春绿'],
	['887322', '苔绿'],
	['fcd337', '柠檬黄'],
	['8e804b', '草灰绿'],
	['fecc11', '向日葵黄'],
	['fccb16', '素馨黄'],
	['ffc90c', '乳鸭黄'],
	['b7ae8f', '月灰'],
	['f8d86a', '葵扇黄'],
	['fbcd31', '大豆黄'],
	['fcc307', '金盏黄'],
	['e9ddb6', '菊蕾白'],
	['fcc515', '黄连黄'],
	['f7e8aa', '杏仁黄'],
	['e8b004', '谷黄'],
	['f9c116', '木瓜黄'],
	['f9d770', '淡茧黄'],
	['fbc82f', '雅梨黄'],
	['f1f0ed', '银白'],
	['5b4913', '棕榈绿'],
	['f6c430', '鹦鹉冠黄'],
	['b78d12', '枯绿'],
	['f9bd10', '浅烙黄'],
	['f9d367', '淡密黄'],
	['d9a40e', '芥黄'],
	['ebb10d', '栀子黄'],
	['584717', '暗海水绿'],
	['f7de98', '篾黄'],
	['f9f1db', '蚌肉白'],
	['f4ce69', '炒米黄'],
	['feba07', '琥珀黄'],
	['8a6913', '灰绿'],
	['876818', '粽叶绿'],
	['b6a476', '尘灰'],
	['fcb70a', '鼬黄'],
	['f0d695', '象牙黄'],
	['87723e', '鲛青'],
	['f8e8c1', '豆汁黄'],
	['d6a01d', '土黄'],
	['f7da94', '香水玫瑰黄'],
	['eaad1a', '虎皮黄'],
	['fbb612', '鸡蛋黄'],
	['b5aa90', '银鼠灰'],
	['f7f4ed', '鱼肚白'],
	['f8bc31', '初熟杏黄'],
	['b78b26', '山鸡黄'],
	['e5d3aa', '莲子白'],
	['695e45', '蟹壳灰'],
	['e5b751', '沙石黄'],
	['f3bf4c', '甘草黄'],
	['685e48', '燕羽灰'],
	['fbb929', '鹅掌黄'],
	['f9d27d', '麦芽糖黄'],
	['e2c17c', '浅驼色'],
	['b4a992', '百灵鸟灰'],
	['f6dead', '酪黄'],
	['f2e6ce', '荔肉白'],
	['f8e0b0', '淡肉色'],
	['393733', '河豚灰'],
	['835e1d', '蜴蜊绿'],
	['f8f4ed', '汉白玉'],
	['fca104', '橙皮黄'],
	['815f25', '莱阳梨黄'],
	['fca106', '枇杷黄'],
	['ffa60f', '金叶黄'],
	['806332', '苍黄'],
	['fbf2e3', '粉白'],
	['fba414', '淡橘橙'],
	['e4dfd7', '珍珠灰'],
	['826b48', '龟背黄'],
	['dad4cb', '浅灰'],
	['bbb5ac', '铅灰'],
	['bbb5ac', '中灰'],
	['ff9900', '雄黄'],
	['fbb957', '蜜黄'],
	['dc9123', '风帆黄'],
	['c09351', '桂皮淡棕'],
	['f4a83a', '金莺黄'],
	['f7c173', '肉色'],
	['e7a23f', '凋叶棕'],
	['533c1b', '古铜绿'],
	['f9e8d0', '落英淡粉'],
	['de9e44', '软木黄'],
	['f9cb8b', '瓜瓤粉'],
	['f9a633', '榴萼黄'],
	['daa45a', '玳瑁黄'],
	['553b18', '焦茶绿'],
	['513c20', '蟹壳绿'],
	['986524', '山鸡褐'],
	['97846c', '猴毛灰'],
	['e3bd8d', '鹿角棕'],
	['4d4030', '淡松烟'],
	['fb8b05', '万寿菊黄'],
	['f8c387', '蛋壳黄'],
	['f28e16', '杏黄'],
	['503e2a', '橄榄灰'],
	['4a4035', '鹤灰'],
	['cfccc9', '玛瑙灰'],
	['c1b2a3', '淡银灰'],
	['867e76', '瓦灰'],
	['847c74', '夜灰'],
	['fc8c23', '北瓜黄'],
	['fbecde', '荷花白'],
	['4f4032', '松鼠灰'],
	['fbeee2', '淡米粉'],
	['81776e', '深灰'],
	['9a8878', '海鸥灰'],
	['5d3d21', '茶褐'],
	['66462a', '驼色'],
	['918072', '银灰'],
	['d99156', '鹿皮褐'],
	['c1651a', '槟榔综'],
	['d4c4b7', '晓灰'],
	['be7e4a', '淡赭'],
	['5c3719', '古铜褐'],
	['de7622', '麂棕'],
	['db8540', '醉瓜肉'],
	['80766e', '雁灰'],
	['f09c5a', '鲑鱼红'],
	['f97d1c', '橘橙'],
	['f26b1f', '金黄'],
	['f8b37f', '玫瑰粉'],
	['fa7e23', '美人焦橙'],
	['f9e9cd', '米色'],
	['b7a091', '蛛网灰'],
	['945833', '淡咖啡'],
	['f0945d', '海螺橙'],
	['964d22', '岩石棕'],
	['954416', '芒果棕'],
	['e16723', '陶瓷红'],
	['fc7930', '菠萝红'],
	['cf7543', '余烬红'],
	['f86b1d', '金莲花橙'],
	['cd6227', '火砖红'],
	['f6dcce', '初桃粉红'],
	['d85916', '铁棕'],
	['f7cfba', '介壳淡粉红'],
	['f27635', '蟹壳红'],
	['e46828', '金驼'],
	['fc6315', '燕颔红'],
	['b7511d', '淡可可棕'],
	['ea8958', '晨曦红'],
	['e8b49a', '玉粉红'],
	['fb9968', '野蔷薇红'],
	['edc3ae', '藕荷'],
	['363433', '长石灰'],
	['8b614d', '中红灰'],
	['aa6a4c', '火泥棕'],
	['a6522c', '绀红'],
	['fa5d19', '莓酱红'],
	['71361d', '丁香棕'],
	['b89485', '淡玫瑰灰'],
	['f68c60', '瓜瓤红'],
	['f6ad8f', '淡藏花红'],
	['732e12', '筍皮棕'],
	['f7cdbc', '润红'],
	['ef632b', '龙睛鱼红'],
	['8c4b31', '淡土黄'],
	['64483d', '珠母灰'],
	['f9723d', '芙蓉红'],
	['cf4813', '落霞红'],
	['ee8055', '法螺红'],
	['f8ebe6', '草珠红'],
	['753117', '咖啡'],
	['603d30', '中灰驼'],
	['883a1e', '椰壳棕'],
	['b14b28', '蟹蝥红'],
	['873d24', '淡豆沙'],
	['f6cec1', '淡桃红'],
	['5b423a', '淡铁灰'],
	['624941', '石板灰'],
	['673424', '淡栗棕'],
	['f43e06', '银朱'],
	['ef6f48', '草莓红'],
	['f4c7ba', '洋水仙红'],
	['ed5126', '朱红'],
	['f34718', '榴花红'],
	['f2481b', '柿红'],
	['652b1c', '可可棕'],
	['eea08c', '淡罂粟红'],
	['f04b22', '大红'],
	['692a1b', '柞叶棕'],
	['f1441d', '蜻蜓红'],
	['773d31', '橡树棕'],
	['eeaa9c', '颊红'],
	['f0ada0', '桃红'],
	['863020', '火岩棕'],
	['f2e7e5', '淡藤萝紫'],
	['862617', '赭石'],
	['f5391c', '铁水红'],
	['f03f24', '胭脂红'],
	['f33b1f', '极光红'],
	['f23e23', '红汞红'],
	['f13c22', '萝卜红'],
	['f05a46', '曲红'],
	['f17666', '谷鞘红'],
	['f15642', '苹果红'],
	['f25a47', '桂红'],
	['f2b9b2', '粉红'],
	['592620', '暗驼棕'],
	['de2a18', '夕阳红'],
	['ed3321', '樱桃红'],
	['f04a3a', '珊瑚红'],
	['482522', '火山棕'],
	['5c1e19', '栗棕'],
	['d42517', '鹤顶红'],
	['f19790', '舌红'],
	['ab372f', '鹅血石红'],
	['5a1f1b', '酱棕'],
	['ed3b2f', '鱼鳃红'],
	['bdaead', '芦穗灰'],
	['eb261a', '丽春红'],
	['ac1f18', '覆盆子红'],
	['483332', '海报灰'],
	['481e1c', '豆沙'],
	['f1908c', '榴子红'],
	['ec2b24', '秋海棠红'],
	['efafad', '无花果红'],
	['f2cac9', '淡绯'],
	['4b2e2b', '玫瑰灰'],
	['ed4845', '淡菽红'],
	['ed3333', '枸枢红'],
	['5d3131', '貂紫']
];

// 传入 hsl(0, 0%, 0%) 格式的颜色，返回 h s l 的值组成的数组
const hslFunc = (color: string) => {
	const hslArr = color.match(/\d+/g);
	return hslArr;
};

// 将 colors 转为 rgb 和 hsl 格式，每一项包含 name hex rgb hsl，colorConvertFunc 为转换函数
type colorObj = {
	name: string;
	hex: string;
	rgb: string[];
	hsl: string[];
	hsl_h: string | null;
	hsl_s: string | null;
	hsl_l: string | null;
	mode: string;
};
let colorList: colorObj[] = [];
colors.forEach((item) => {
	const hex = '#' + item[0];
	const obj = {
		name: item[1],
		hex,
		rgb: colorConvertFunc(hex).rgb.split(','),
		hsl: colorConvertFunc(hex).hsl.split(','),
		hsl_h: hslFunc(colorConvertFunc(hex).hsl)?.[0] ?? null,
		hsl_s: hslFunc(colorConvertFunc(hex).hsl)?.[1] ?? null,
		hsl_l: hslFunc(colorConvertFunc(hex).hsl)?.[2] ?? null,
		mode: hslFunc(colorConvertFunc(hex).hsl)?.[2] !== undefined && Number(hslFunc(colorConvertFunc(hex).hsl)?.[2]) > 50 ? 'light' : 'dark'
	};
	colorList.push(obj);
});

// 过滤出 hsl_l 在 20-45 和 55-80 之间的颜色，区分明显
colorList = colorList.filter((item) => {
	const hslL = item.hsl_l ? Number(item.hsl_l) : null;
	return hslL !== null && ((hslL >= 20 && hslL < 45) || (hslL > 55 && hslL <= 80));
});

export default colorList;



================================================
FILE: docs/site/src/data/menuList.ts
================================================
export type MenuListChild = {
	title: string;
	title_zh: string;
	title_en: string;
	nav: string;
	tip: string;
	tip_en: string;
	alias: string;
};
export type MenuList = { class: string; class_en: string; childs: MenuListChild[] };

export const menuList: MenuList[] = [
	{
		class: '通用',
		class_en: 'Universal',
		childs: [
			{
				title: '按钮 Button',
				title_zh: '按钮',
				title_en: 'Button',
				nav: 'button',
				tip: '按下它，让世界变得更美好吧。',
				tip_en: 'Press it and make the world a better place.',
				alias: 'button|按钮'
			},
			{
				title: '底部浮窗 BottomSheet',
				title_zh: '底部浮窗',
				title_en: 'BottomSheet',
				nav: 'bottomSheet',
				tip: '浮窗犹如小偷，突然出现让你焦灼，却也能唤起你的警觉。',
				tip_en: 'The floating window is like a thief, suddenly appearing to make you anxious, but it can also arouse your alertness.',
				alias:
					'bottomSheet|底部浮窗 | 底部 | 底|部 | 浮窗|bottomSheet 底部浮窗|bottomSheet 底部浮窗 | 底部弹窗|bottomSheet 底部弹窗|bottomSheet 底部弹窗 | 底部弹出框|bottomSheet 底部弹出框|bottomSheet 底部弹出框 | 底部弹出层|bottomSheet 底部弹出层|bottomSheet 底部弹出层'
			},
			{
				title: '图标 Icon',
				title_zh: '图标',
				title_en: 'Icon',
				nav: 'icon',
				tip: '使用 SVG Sprites，请参照指南引入与使用。',
				tip_en: 'Use SVG Sprites, please refer to the guide to import and use.',
				alias: 'icon|图标|svg'
			},
			{
				title: '遮罩 Mask',
				title_zh: '遮罩',
				title_en: 'Mask',
				nav: 'mask',
				tip: '遮罩虽能掩盖身形，却无法掩藏内心。',
				tip_en: 'Although the mask can cover the figure, it cannot hide the heart.',
				alias: 'mask|遮罩 | 遮|罩|mask 遮罩|mask 遮罩 | 遮罩层|mask 遮罩层|mask 遮罩层|Overlay|maskOverlay|mask Overlay'
			},
			{
				title: '弹出层 Popup',
				title_zh: '弹出层',
				title_en: 'Popup',
				nav: 'popup',
				tip: '机会就像弹珠，只有你努力地推它，它才会弹出来。',
				tip_en: 'Opportunity is like a marble, only if you push it hard, it will pop out.',
				alias:
					'popup|弹出层 | 弹出 | 弹|出 | 层|popup 弹出层|popup 弹出层 | 弹窗|popup 弹窗|popup 弹窗 | 弹出框|popup 弹出框|popup 弹出框 | 弹出层|popup 弹出层|popup 弹出层'
			}
		]
	},
	{
		class: '布局',
		class_en: 'Layout',
		childs: [
			{
				title: '分割线 Divider',
				title_zh: '分割线',
				title_en: 'Divider',
				nav: 'divider',
				tip: '分开的日子越久，最初的喜悦越发淡薄。',
				tip_en: 'The longer the days are separated, the more the initial joy fades.',
				alias: 'divider|分割线 | 分割|line'
			},
			{
				title: '网格 Grids',
				title_zh: '网格',
				title_en: 'Grids',
				nav: 'grids',
				tip: '可是怎么说，总觉得，我们之间留了太多空白格。',
				tip_en: 'How can I say, I always feel that there are too many blank grids between us.',
				alias: 'grids|网格|grid|row|col|column'
			},
			{
				title: '占位符 Placeholder',
				title_zh: '占位符',
				title_en: 'Placeholder',
				nav: 'placeholder',
				tip: '人生重要的不是所站的位置，而是所朝的方向。',
				tip_en: 'What is important in life is not the position you stand, but the direction you face.',
				alias: 'placeholder|占位符 | 占位'
			},
			{
				title: '骨架屏 Skeleton',
				title_zh: '骨架屏',
				title_en: 'Skeleton',
				nav: 'skeleton',
				tip: '骨架是支撑身体的关键，而人生信念则是支撑生命的骨架。',
				tip_en: 'The skeleton is the key to supporting the body, and the belief in life is the skeleton that supports life.',
				alias: 'skeleton|骨架屏 | 骨架'
			}
		]
	},
	{
		class: '导航',
		class_en: 'Navigation',
		childs: [
			{
				title: '索引栏 IndexBar',
				title_zh: '索引栏',
				title_en: 'IndexBar',
				nav: 'indexBar',
				tip: '你不迷途知返，我怎么给你以索引？',
				tip_en: "If you don't know the way back, how can I give you an index?",
				alias: 'indexBar|索引栏|indexbar|index|bar|索引|index 栏 | 索引条|index 条|index 条'
			},
			{
				title: '导航栏 NavBar',
				title_zh: '导航栏',
				title_en: 'NavBar',
				nav: 'navBar',
				tip: '没有指引，在黑暗中只能乱撞。',
				tip_en: 'Without guidance, you can only bump in the dark.',
				alias: 'navBar|导航栏|navbar|nav|bar|导航|nav-bar|nav bar'
			},
			{
				title: '分页 Pagination',
				title_zh: '分页',
				title_en: 'Pagination',
				nav: 'pagination',
				tip: '人生就像一部电影，不论多么精彩，也有谢幕的时候。',
				tip_en: 'Life is like a movie, no matter how wonderful it is, there is a curtain call.',
				alias: 'pagination|分页|page|分 | 页|pagination 分页|pagination 分页|page 分页|page 分页'
			},
			{
				title: '步骤条 Steps',
				title_zh: '步骤条',
				title_en: 'Steps',
				nav: 'steps',
				tip: '人生没有白走的路，每一步都算数。',
				tip_en: 'Life has no wasted steps, every step counts.',
				alias: 'steps|step|步骤条 | 步骤|step 条|step 条 | 步骤栏|step 栏|step 栏'
			},
			{
				title: '标签栏 TabBar',
				title_zh: '标签栏',
				title_en: 'TabBar',
				nav: 'tabBar',
				tip: '看脚下一片黑暗，望头顶星光璀璨。',
				tip_en: "Looking down, it's all darkness; looking up, the stars are shining brightly.",
				alias: 'tabBar|标签栏|tabbar|tab|bar|标签|tab 栏'
			},
			{
				title: '标签页 Tabs',
				title_zh: '标签页',
				title_en: 'Tabs',
				nav: 'tabs',
				tip: '偶尔隐藏，是为了在合适的时候更好地绽放。',
				tip_en: 'Occasionally hide, it is to bloom better at the right time.',
				alias: 'tabs|tab|标签页 | 标签|tab 页'
			}
		]
	},
	{
		class: '数据输入',
		class_en: 'Data entry',
		childs: [
			{
				title: '动作面板 ActionSheet',
				title_zh: '动作面板',
				title_en: 'ActionSheet',
				nav: 'actionSheet',
				tip: '我的世界只有一个选项，就是你。',
				tip_en: 'There is only one option in my world, and that is you.',
				alias:
					'actionSheet|动作面板 | 动作 | 动|作 | 面板|actionSheet 动作面板|actionSheet 动作面板 | 动作面板|actionSheet 动作面板|actionSheet 动作面板 | 动作面板|actionSheet 动作面板|actionSheet 动作面板'
			},
			{
				title: '异步选择器 AsyncPicker',
				title_zh: '异步选择器',
				title_en: 'AsyncPicker',
				nav: 'asyncPicker',
				tip: '错过的话，就请错过一辈子吧！',
				tip_en: 'If you miss it, please miss it for a lifetime!',
				alias: 'asyncPicker|异步选择器 | 异步|asyncPicker 异步选择器|asyncPicker 异步选择器|async picker|asyncpicker|异步 picker|异步 picker'
			},
			{
				title: '日历 Calendar',
				title_zh: '日历',
				title_en: 'Calendar',
				nav: 'calendar',
				tip: '在无人问津日子里，正是登峰造极的好时机。',
				tip_en: 'In the days when no one cares, it is a good time to reach the peak.',
				alias:
					'calendar|日历 | 日|历|calendar 日历|calendar 日历 | 日期|calendar 日期|calendar 日期 | 周选择|calendar 周选择|calendar 周选择 | 周|calendar 周|calendar 周 | 日期区间 | 月选择 | 日期范围选择'
			},
			{
				title: '复选框 Checkbox',
				title_zh: '复选框',
				title_en: 'Checkbox',
				nav: 'checkbox',
				tip: '要么全不，要么全部。',
				tip_en: 'Either all or none.',
				alias:
					'checkbox|复选框 | 复选|checkbox 复选框|checkbox 复选框 | 复选按钮|checkbox 复选按钮|checkbox 复选按钮 | 多选框 | 多选|checkbox 多选框|checkbox 多选框 | 多选按钮|checkbox 多选按钮|checkbox 多选按钮'
			},
			{
				title: '输入框 Input',
				title_zh: '输入框',
				title_en: 'Input',
				nav: 'input',
				tip: '对方正在输入......',
				tip_en: 'The other party is typing...',
				alias:
					'input|输入框 | 输入|input 输入框|input 输入框|Textarea|textarea|文本域 | 文本框 | 文本|textarea 文本域|textarea 文本域 | 多行输入框 | 多行输入 | 多行|textarea 多行输入框|textarea 多行输入框'
			},
			{
				title: '数字键盘 NumKeyboard',
				title_zh: '数字键盘',
				title_en: 'NumKeyboard',
				nav: 'numKeyboard',
				tip: '3 0624700 | 3 0624770 | 5 34202 13942 | 4314 0624',
				tip_en: '3 0624700 | 3 0624770 | 5 34202 13942 | 4314 0624',
				alias:
					'numKeyboard|数字键盘 | 数字 | 键盘|numKeyboard 数字键盘|numKeyboard 数字键盘 | 金额键盘|numKeyboard 金额键盘|numKeyboard 金额键盘|number|keyboard|amount|money|'
			},
			{
				title: '选择器 Picker',
				title_zh: '选择器',
				title_en: 'Picker',
				nav: 'picker',
				tip: '采摘花瓣时，你得不到花的美丽。',
				tip_en: 'When you pick petals, you don’t get the beauty of the flower.',
				alias: 'picker|选择器 | 选择|picker 选择器|picker 选择器'
			},
			{
				title: '单选框 Radio',
				title_zh: '单选框',
				title_en: 'Radio',
				nav: 'radio',
				tip: '如果要在正确和善良中选择一个，请选择善良。',
				tip_en: 'If you have to choose between right and good, choose good.',
				alias: 'radio|单选框 | 单选|radio 单选框|radio 单选框 | 单选按钮|radio 单选按钮|radio 单选按钮'
			},
			{
				title: '评分 Rate',
				title_zh: '评分',
				title_en: 'Rate',
				nav: 'rate',
				tip: '散场时，对方剩余的手机电量，就是这场约会的评分。',
				tip_en: 'At the end of the game, the remaining battery power of the other party is the score of this date.',
				alias: 'rate|评分 | 评|分|rate 评分|rate 评分'
			},
			{
				title: '滑块 Slider',
				title_zh: '滑块',
				title_en: 'Slider',
				nav: 'slider',
				tip: '请滑动解锁您的烦恼。',
				tip_en: 'Please slide to unlock your troubles.',
				alias: 'slider|滑块 | 滑|块|slider 滑块|slider 滑块'
			},
			{
				title: '开关 Switch',
				title_zh: '开关',
				title_en: 'Switch',
				nav: 'switch',
				tip: '死亡是一个开关，活着却是一根绳索。',
				tip_en: 'Death is a switch, but life is a rope.',
				alias: 'switch|开关 | 开|关|switch 开关|switch 开关'
			},
			{
				title: '步进器 Stepper',
				title_zh: '步进器',
				title_en: 'Stepper',
				nav: 'stepper',
				tip: '人生如同诗行，或进或退皆成章。保持心灵节奏，生命之诗韵味悠长。',
				tip_en:
					'Life is like a poem, advancing or retreating all form chapters. Maintain the rhythm of the soul, and the poetic flavor of life will last long.',
				alias: 'stepper|步进器 | 步|进 | 器|stepper 步进器|stepper 步进器'
			},
			{
				title: '时间选择器 TimePicker',
				title_zh: '时间选择器',
				title_en: 'TimePicker',
				nav: 'timePicker',
				tip: '死亡不是失去生命，而是走出了时间的枷锁。',
				tip_en: 'Death is not the loss of life, but the release of the shackles of time.',
				alias:
					'timePicker|时间选择器 | 时间|timePicker 时间选择器|timePicker 时间选择器|time picker|timepicker|时间 picker|时间 picker|日期选择器 | 日期|datePicker 日期选择器|datePicker 日期选择器|date picker|datepicker|日期 picker|日期 picker'
			}
		]
	},
	{
		class: '信息展示',
		class_en: 'Info display',
		childs: [
			{
				title: '头像 Avatar',
				title_zh: '头像',
				title_en: 'Avatar',
				nav: 'avatar',
				tip: '其实我发给您的头像，是情侣头像...',
				tip_en: 'Actually, the avatar I sent to you is a couple avatar...',
				alias: 'avatar|头像 | 头|像|avatar 头像|avatar 头像'
			},
			{
				title: '徽标 Badge',
				title_zh: '徽标',
				title_en: 'Badge',
				nav: 'badge',
				tip: '在标记消失之前，回到我身边。',
				tip_en: 'Before the mark disappears, come back to me.',
				alias: 'badge|徽标 | 徽|标|badge 徽标|badge 徽标 | 标记|badge 标记|badge 标记'
			},
			{
				title: '单元格 Cell',
				title_zh: '单元格',
				title_en: 'Cell',
				nav: 'cell',
				tip: '当全世界抛弃您的时候请记住，您身上有几亿细胞都在为你而活。',
				tip_en: 'When the whole world abandons you, remember that there are billions of cells on your body that are living for you.',
				alias: 'cell|单元格 | 单元|cell 单元格|cell 单元格'
			},
			{
				title: '通告栏 NoticeBar',
				title_zh: '通告栏',
				title_en: 'NoticeBar',
				nav: 'noticeBar',
				tip: '我方开放地下城，这是告知，不是商量。',
				tip_en: 'Our side opens the dungeon, this is to inform, not to discuss.',
				alias:
					'noticeBar|通告栏 | 通告 | 通|栏|noticeBar 通告栏|noticeBar 通告栏 | 通知栏|noticeBar 通知栏|noticeBar 通知栏 | 公告栏|noticeBar 公告栏|noticeBar 公告栏'
			},
			{
				title: '进度条 Progress',
				title_zh: '进度条',
				title_en: 'Progress',
				nav: 'progress',
				tip: '好运进度：▓▓▓▓▓▓▓▓▓▓▓▓ 100%',
				tip_en: 'Good luck progr: ▓▓▓▓▓▓▓▓▓▓▓▓ 100%',
				alias: 'progress|进度条 | 进度 | 进|度|progress 进度条|progress 进度条'
			},
			{
				title: '进度环 ProgressLoop',
				title_zh: '进度环',
				title_en: 'ProgressLoop',
				nav: 'progressLoop',
				tip: '人生不是一个完美的圆环，一旦完美，你就再没有任何可能性。',
				tip_en: 'Life is not a perfect circle. Once perfect, you have no possibility.',
				alias:
					'progressLoop|进度环 | 进度 | 进|度|progressLoop 进度环|progressLoop 进度环 | 环形进度条|progressLoop 环形进度条|progressLoop 环形进度条|progress loop|progress-loop'
			},
			{
				title: '轮播 Swiper',
				title_zh: '轮播',
				title_en: 'Swiper',
				nav: 'swiper',
				tip: '人世间悲喜烂剧，昼夜轮播不停。',
				tip_en: 'The ups and downs of life, day and night, are not stopping.',
				alias: 'swiper|轮播 | 轮|播|swiper 轮播|swiper 轮播 | 轮播图|swiper 轮播图|swiper 轮播图 | 走马灯|swiper 走马灯|swiper 走马灯|carousel'
			}
		]
	},
	{
		class: '反馈',
		class_en: 'Feedback',
		childs: [
			{
				title: '对话框 Dialog',
				title_zh: '对话框',
				title_en: 'Dialog',
				nav: 'dialog',
				tip: '无法确定任何事情，尤其是按下“确定”键的那一刻，我最不确定。',
				tip_en: 'Nothing can be determined, especially at the moment when the "OK" button is pressed, I am the most uncertain.',
				alias:
					'dialog|对话框 | 对话 | 对|话 | 框|dialog 对话框|dialog 对话框 | 对话框|dialog 对话框|dialog 对话框 | 对话框|dialog 对话框|dialog 对话框 | 对话框|dialog 对话框|dialog 对话框'
			},
			{
				title: '加载 Loading',
				title_zh: '加载',
				title_en: 'Loading',
				nav: 'loading',
				tip: '不要再苦苦等待答案了，没有回复已是答案。',
				tip_en: "Don't wait for the answer, no reply is the answer.",
				alias: 'loading|加载 | 加载中|loading 加载|loading 加载|loading 加载中|loading 加载中|loading 加载中...|loading 加载中...'
			},
			{
				title: '弹框 Modal',
				title_zh: '弹框',
				title_en: 'Modal',
				nav: 'modal',
				tip: '弹框即人生，要么选择关闭，要么选择继续。',
				tip_en: 'The modal is life, either choose to close or choose to continue.',
				alias:
					'modal|弹框 | 弹|框|modal 弹框|modal 弹框 | 弹窗|modal 弹窗|modal 弹窗 | 弹出框|modal 弹出框|modal 弹出框 | 弹框|modal 弹框|modal 弹框 | 模态框|modal 模态框|modal 模态框'
			},
			{
				title: '轻提示 Toast',
				title_zh: '轻提示',
				title_en: 'Toast',
				nav: 'toast',
				tip: '总有一些东西，要用消失来证明它的珍贵。',
				tip_en: 'There are always some things that have to disappear to prove their value.',
				alias:
					'toast|轻提示 | 轻|提示|toast 轻提示|toast 轻提示 | 轻弹窗|toast 轻弹窗|toast 轻弹窗 | 轻提示框|toast 轻提示框|toast 轻提示框 | 吐司|toast 吐司|toast 吐司'
			}
		]
	}
];



================================================
FILE: docs/site/src/data/themes/aqua.ts
================================================
import type { ThemeProps } from 'stdf/theme';

const Aqua: ThemeProps = {
	name: 'Aqua',
	color: {
		primary: {
			50: 'oklch(0.987 0.008 225.079)', // #F5FCFF hsl(198, 100%, 98%)
			100: 'oklch(0.969 0.019 225.712)', // #E8F8FF hsl(198, 100%, 96%)
			200: 'oklch(0.832 0.048 227.654)', // #A8CFE1 hsl(199, 49%, 77%)
			300: 'oklch(0.699 0.07 233.534)', // #72A6C3 hsl(202, 40%, 61%)
			400: 'oklch(0.575 0.083 237.386)', // #4580A4 hsl(203, 41%, 46%)
			500: 'oklch(0.46 0.09 243.106)', // #235D86 hsl(205, 59%, 33%)
			default: 'oklch(0.355 0.089 248.677)', // #0A3E68 hsl(207, 83%, 22%)
			700: 'oklch(0.329 0.09 251.443)', // #073661 hsl(209, 87%, 20%)
			800: 'oklch(0.302 0.09 253.945)', // #042E5A hsl(211, 92%, 18%)
			900: 'oklch(0.277 0.09 255.696)', // #022753 hsl(213, 95%, 17%)
			950: 'oklch(0.253 0.091 257.423)' // #00204D hsl(215, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.997 0.013 111.26)', // #FEFFF5 hsl(66, 100%, 98%)
			100: 'oklch(0.992 0.03 110.976)', // #FDFFE8 hsl(65, 100%, 96%)
			200: 'oklch(0.946 0.068 113.937)', // #ECF3BF hsl(68, 68%, 85%)
			300: 'oklch(0.9 0.101 116.179)', // #DAE799 hsl(70, 62%, 75%)
			400: 'oklch(0.857 0.13 118.796)', // #C7DC76 hsl(72, 59%, 66%)
			500: 'oklch(0.812 0.152 121.068)', // #B3D055 hsl(74, 57%, 58%)
			default: 'oklch(0.767 0.167 123.364)', // #9FC438 hsl(76, 56%, 49%)
			700: 'oklch(0.673 0.157 125.534)', // #7FA624 hsl(78, 64%, 40%)
			800: 'oklch(0.577 0.143 127.636)', // #618813 hsl(80, 76%, 30%)
			900: 'oklch(0.479 0.124 129.495)', // #466A08 hsl(82, 86%, 22%)
			950: 'oklch(0.381 0.104 130.976)' // #2E4D00 hsl(84, 100%, 15%)
		},
		primaryBlack: 'oklch(0.156 0.033 240.386)', // #010E19 hsl(207, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(207, 5%, 95%)
		darkBlack: 'oklch(0.199 0.046 122.93)', // #121901 hsl(76, 95%, 5%)
		darkWhite: 'oklch(0.964 0.001 106.424)', // #F3F3F2 hsl(76, 5%, 95%)
		functional: {
			success: 'oklch(0.577 0.18 144.916)', // #069327 hsl(134, 92%, 30%)
			warning: 'oklch(0.615 0.147 54.981)', // #c66810 hsl(29, 85%, 42%)
			error: 'oklch(0.559 0.203 26.879)', // #d12929 hsl(0, 67%, 49%)
			info: 'oklch(0.455 0.194 263.236)' // #1649c0 hsl(222, 79%, 42%)
		},
		extend: [
			{
				color: 'oklch(0.345 0.194 290.65)', // #410093 hsl(267, 100%, 29%)
				alias: 'Yahoo!'
			},
			{
				color: 'oklch(0.651 0.212 142.608)', // oklch(0.651 0.212 142.608) hsl(120, 75%, 39%)
				alias: 'WeChat'
			},
			{
				color: 'oklch(0.689 0.196 21.407)', // #fd5c63 hsl(357, 98%, 68%)
				alias: 'Airbnb'
			}
		]
	}
};

export default Aqua;



================================================
FILE: docs/site/src/data/themes/azuper.ts
================================================
import type { ThemeProps } from 'stdf/theme';

const Azuper: ThemeProps = {
	name: 'Azuper',
	color: {
		primary: {
			50: 'oklch(0.987 0.008 225.079)', // #F5FCFF hsl(198, 100%, 98%)
			100: 'oklch(0.967 0.019 230.689)', // #E8F7FF hsl(201, 100%, 96%)
			200: 'oklch(0.827 0.048 234.484)', // #A9CCE1 hsl(203, 48%, 77%)
			300: 'oklch(0.692 0.069 240.216)', // #74A2C3 hsl(205, 40%, 61%)
			400: 'oklch(0.565 0.085 244.974)', // #487BA5 hsl(207, 39%, 47%)
			500: 'oklch(0.45 0.094 249.497)', // #265887 hsl(209, 56%, 34%)
			default: 'oklch(0.347 0.095 253.302)', // #0D3A69 hsl(211, 78%, 23%)
			700: 'oklch(0.317 0.097 256.274)', // #093162 hsl(213, 83%, 21%)
			800: 'oklch(0.291 0.098 258.443)', // #06295B hsl(215, 88%, 19%)
			900: 'oklch(0.266 0.098 259.566)', // #032254 hsl(217, 93%, 17%)
			950: 'oklch(0.241 0.099 260.073)' // #001B4D hsl(219, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.984 0.009 44.894)', // #FFF8F5 hsl(18, 100%, 98%)
			100: 'oklch(0.963 0.02 45.262)', // #FFEFE8 hsl(18, 100%, 96%)
			200: 'oklch(0.889 0.047 41.262)', // #F7D1C3 hsl(16, 77%, 87%)
			300: 'oklch(0.817 0.075 38.298)', // #EFB3A0 hsl(14, 71%, 78%)
			400: 'oklch(0.747 0.107 34.759)', // #E8947F hsl(12, 70%, 70%)
			500: 'oklch(0.68 0.138 32.855)', // #E0755F hsl(10, 68%, 63%)
			default: 'oklch(0.621 0.167 31.47)', // #D85742 hsl(8, 66%, 55%)
			700: 'oklch(0.522 0.165 29.582)', // #B5372A hsl(6, 62%, 44%)
			800: 'oklch(0.433 0.152 29.344)', // #921F16 hsl(4, 74%, 33%)
			900: 'oklch(0.348 0.132 28.566)', // #6F0C09 hsl(2, 85%, 24%)
			950: 'oklch(0.264 0.108 29.234)' // #4D0000 hsl(0, 100%, 15%)
		},
		primaryBlack: 'oklch(0.15 0.035 247.014)', // #010C19 hsl(211, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(211, 5%, 95%)
		darkBlack: 'oklch(0.148 0.043 37.362)', // #190401 hsl(8, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(8, 5%, 95%)
		functional: {
			success: 'oklch(0.663 0.189 146.376)', // #21b043 hsl(134, 68%, 41%)
			warning: 'oklch(0.652 0.163 41.893)', // #df6734 hsl(18, 73%, 54%)
			error: 'oklch(0.616 0.196 13.669)', // #e14161 hsl(348, 73%, 57%)
			info: 'oklch(0.523 0.229 273.504)' // #484eea hsl(238, 79%, 60%)
		},
		extend: [
			{
				color: 'oklch(0.492 0.217 261.351)', // oklch(0.492 0.217 261.351) hsl(217, 100%, 43%)
				alias: 'Tencent'
			},
			{
				color: 'oklch(0.654 0.154 241.655)', // #0099e5 hsl(200, 100%, 45%)
				alias: '500px'
			},
			{
				color: 'oklch(0.571 0.235 261.561)', // #1769ff hsl(219, 100%, 55%)
				alias: 'Behance'
			}
		]
	}
};

export default Azuper;



================================================
FILE: docs/site/src/data/themes/azurePink.ts
================================================
import type { ThemeProps } from 'stdf/theme';

const AzurePink: ThemeProps = {
	name: 'AzurePink',
	color: {
		primary: {
			50: 'oklch(0.977 0.011 274.897)', // #F5F7FF hsl(228, 100%, 98%)
			100: 'oklch(0.948 0.025 273.503)', // #E8EDFF hsl(227, 100%, 96%)
			200: 'oklch(0.799 0.073 275.979)', // #B0BAED hsl(230, 63%, 81%)
			300: 'oklch(0.66 0.12 275.608)', // #7E8BDB hsl(232, 56%, 68%)
			400: 'oklch(0.531 0.164 274.903)', // #535EC9 hsl(234, 52%, 56%)
			500: 'oklch(0.421 0.199 271.236)', // #2D36B7 hsl(236, 61%, 45%)
			default: 'oklch(0.341 0.216 266.286)', // #0D12A5 hsl(238, 85%, 35%)
			700: 'oklch(0.302 0.198 265.961)', // #08088F hsl(240, 89%, 30%)
			800: 'oklch(0.269 0.175 267.031)', // #090579 hsl(242, 92%, 25%)
			900: 'oklch(0.233 0.152 268.05)', // #080263 hsl(244, 96%, 20%)
			950: 'oklch(0.196 0.128 270.599)' // #08004D hsl(246, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.979 0.011 356.992)', // #FFF5F8 hsl(342, 100%, 98%)
			100: 'oklch(0.952 0.027 354.511)', // #FFE8F0 hsl(339, 100%, 96%)
			200: 'oklch(0.863 0.076 354.34)', // #FBBED5 hsl(337, 88%, 87%)
			300: 'oklch(0.783 0.127 353.824)', // #F795BE hsl(335, 86%, 78%)
			400: 'oklch(0.713 0.175 354.443)', // #F36DA9 hsl(333, 85%, 69%)
			500: 'oklch(0.658 0.216 355.121)', // #EF4698 hsl(331, 84%, 61%)
			default: 'oklch(0.621 0.239 357.218)', // #EB2188 hsl(329, 84%, 53%)
			700: 'oklch(0.54 0.212 354.913)', // #C31575 hsl(327, 81%, 42%)
			800: 'oklch(0.458 0.183 353.544)', // #9C0B5F hsl(325, 87%, 33%)
			900: 'oklch(0.37 0.15 351.13)', // #740449 hsl(323, 93%, 24%)
			950: 'oklch(0.278 0.117 348.207)' // #4D0032 hsl(321, 100%, 15%)
		},
		primaryBlack: 'oklch(0.106 0.061 269.597)', // #010119 hsl(238, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(238, 5%, 95%)
		darkBlack: 'oklch(0.144 0.055 350.158)', // #19010D hsl(329, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(329, 5%, 95%)
		functional: {
			success: 'oklch(0.629 0.199 141.373)', // #2ba417 hsl(112, 75%, 37%)
			warning: 'oklch(0.674 0.166 52.005)', // #e37318 hsl(27, 81%, 49%)
			error: 'oklch(0.599 0.177 27.079)', // #d54941 hsl(3, 64%, 55%)
			info: 'oklch(0.492 0.217 261.351)' // #0052d9 hsl(217, 100%, 43%)
		},
		extend: [
			{
				color: 'oklch(0.364 0.191 266.82)', // #1428a0 hsl(231, 78%, 35%)
				alias: 'Samsung'
			},
			{
				color: 'oklch(0.66 0.225 36.296)', // #fd4900 hsl(17, 100%, 50%)
				alias: 'Xiaomi'
			},
			{
				color: 'oklch(0.461 0.116 153.579)', // #046a38 hsl(151, 93%, 22%)
				alias: 'OPPO'
			}
		]
	}
};

export default AzurePink;



================================================
FILE: docs/site/src/data/themes/camelliaRed.ts
================================================
import type { ThemeProps } from 'stdf/theme';

const CamelliaRed: ThemeProps = {
	name: 'CamelliaRed',
	color: {
		primary: {
			50: 'oklch(0.98 0.01 25.073)', // #FFF6F5 hsl(6, 100%, 98%)
			100: 'oklch(0.953 0.023 24.126)', // #FFEAE8 hsl(5, 100%, 96%)
			200: 'oklch(0.876 0.061 22.144)', // #FCC7C4 hsl(3, 90%, 88%)
			300: 'oklch(0.799 0.101 20.296)', // #F8A3A2 hsl(1, 86%, 80%)
			400: 'oklch(0.732 0.143 20.141)', // #F58082 hsl(359, 85%, 73%)
			500: 'oklch(0.675 0.18 20.489)', // #F15F66 hsl(357, 84%, 66%)
			default: 'oklch(0.632 0.21 21.584)', // #EE3F4D hsl(355, 84%, 59%)
			700: 'oklch(0.54 0.193 20.999)', // #C6273A hsl(353, 67%, 47%)
			800: 'oklch(0.449 0.168 20.933)', // #9D1529 hsl(351, 76%, 35%)
			900: 'oklch(0.36 0.138 20.161)', // #75081C hsl(349, 87%, 25%)
			950: 'oklch(0.266 0.107 17.45)' // #4D0011 hsl(347, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.99 0.008 319.447)', // #FEFAFF hsl(288, 100%, 99%)
			100: 'oklch(0.953 0.037 320.346)', // #FBE8FF hsl(290, 100%, 96%)
			200: 'oklch(0.915 0.065 318.761)', // #F6D6FF hsl(287, 100%, 92%)
			300: 'oklch(0.877 0.092 317.423)', // #F0C4FF hsl(285, 100%, 88%)
			400: 'oklch(0.841 0.118 315.933)', // #E9B3FF hsl(283, 100%, 85%)
			500: 'oklch(0.803 0.145 314.514)', // #E1A1FF hsl(281, 100%, 82%)
			default: 'oklch(0.765 0.171 312.957)', // #D88FFF hsl(279, 100%, 78%)
			700: 'oklch(0.602 0.188 310.729)', // #A458D2 hsl(277, 58%, 58%)
			800: 'oklch(0.461 0.184 307.198)', // #742EA6 hsl(275, 57%, 42%)
			900: 'oklch(0.339 0.159 303.074)', // #4A1179 hsl(273, 75%, 27%)
			950: 'oklch(0.231 0.124 299.616)' // #28004D hsl(271, 100%, 15%)
		},
		primaryBlack: 'oklch(0.139 0.05 18.003)', // #190103 hsl(355, 95%, 5%)
		primaryWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(355, 5%, 95%)
		darkBlack: 'oklch(0.134 0.06 312.473)', // #100119 hsl(279, 95%, 5%)
		darkWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(279, 5%, 95%)
		functional: {
			success: 'oklch(0.726 0.218 138.487)', // #52c41a hsl(100, 77%, 44%)
			warning: 'oklch(0.802 0.165 76.001)', // #faad14 hsl(40, 96%, 53%)
			error: 'oklch(0.673 0.214 24.465)', // #ff4d4f hsl(359, 100%, 65%)
			info: 'oklch(0.599 0.219 259.04)' // #1677ff hsl(215, 100%, 54%)
		},
		extend: [
			{
				color: 'oklch(0.472 0.108 263.58)', // #3b5998 hsl(221, 44%, 41%)
				alias: 'Facebook'
			},
			{
				color: 'oklch(0.602 0.236 28.928)', // #ed1c16 hsl(2, 86%, 51%)
				alias: 'CocaCola'
			},
			{
				color: 'oklch(0.51 0.145 250.251)', // #0068b5 hsl(206, 100%, 36%)
				alias: 'Intel'
			}
		]
	}
};

export default CamelliaRed;



================================================
FILE: docs/site/src/data/themes/chameleon.ts
================================================
import type { ThemeProps } from 'stdf/theme';

const Chameleon: ThemeProps = {
	name: 'Chameleon',
	color: {
		primary: {
			50: 'oklch(0.991 0.014 155.599)', // #F5FFF8 hsl(138, 100%, 98%)
			100: 'oklch(0.979 0.032 155.407)', // #E8FFEF hsl(138, 100%, 96%)
			200: 'oklch(0.89 0.085 155.743)', // #ADECC3 hsl(141, 62%, 80%)
			300: 'oklch(0.812 0.128 154.98)', // #78DA9D hsl(143, 57%, 66%)
			400: 'oklch(0.742 0.153 154.251)', // #4AC77E hsl(145, 53%, 54%)
			500: 'oklch(0.682 0.167 152.73)', // #23B564 hsl(147, 68%, 42%)
			default: 'oklch(0.623 0.168 150.91)', // #02A24E hsl(149, 98%, 32%)
			700: 'oklch(0.564 0.146 152.693)', // #018D49 hsl(151, 99%, 28%)
			800: 'oklch(0.5 0.124 154.785)', // #017742 hsl(153, 98%, 24%)
			900: 'oklch(0.437 0.104 156.756)', // #006239 hsl(155, 100%, 19%)
			950: 'oklch(0.371 0.085 159.162)' // #004D2F hsl(157, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.98 0.014 336.137)', // #FFF5FC hsl(318, 100%, 98%)
			100: 'oklch(0.955 0.034 333.19)', // #FFE8FA hsl(313, 100%, 96%)
			200: 'oklch(0.896 0.07 332.956)', // #FACCF1 hsl(312, 82%, 89%)
			300: 'oklch(0.842 0.108 332.745)', // #F6B1EA hsl(310, 79%, 83%)
			400: 'oklch(0.793 0.145 331.761)', // #F197E5 hsl(308, 76%, 77%)
			500: 'oklch(0.75 0.181 330.986)', // #ED7EE2 hsl(306, 76%, 71%)
			default: 'oklch(0.711 0.213 330.284)', // #E866DF hsl(304, 74%, 66%)
			700: 'oklch(0.6 0.215 329.149)', // #C140BD hsl(302, 51%, 50%)
			800: 'oklch(0.496 0.202 328.098)', // #9A229A hsl(300, 64%, 37%)
			900: 'oklch(0.391 0.17 326.834)', // #700D73 hsl(298, 80%, 25%)
			950: 'oklch(0.284 0.133 324.454)' // #47004D hsl(295, 100%, 15%)
		},
		primaryBlack: 'oklch(0.189 0.042 157.928)', // #01190C hsl(149, 95%, 5%)
		primaryWhite: 'oklch(0.963 0.002 145.562)', // #F2F3F2 hsl(149, 5%, 95%)
		darkBlack: 'oklch(0.151 0.063 331.348)', // #190117 hsl(304, 95%, 5%)
		darkWhite: 'oklch(0.962 0.002 325.59)', // #F3F2F3 hsl(304, 5%, 95%)
		functional: {
			success: 'oklch(0.731 0.191 137.226)', // #67c23a hsl(100, 54%, 49%)
			warning: 'oklch(0.761 0.139 73.316)', // #e6a23c hsl(36, 77%, 57%)
			error: 'oklch(0.699 0.169 22.456)', // #f56c6c hsl(0, 87%, 69%)
			info: 'oklch(0.663 0.01 264.502)' // #909399 hsl(220, 4%, 58%)
		},
		extend: [
			{
				color: 'oklch(0.746 0.16 232.661)', // #00bcff hsl(194, 100%, 44%)
				alias: 'Tailwind'
			},
			{
				color: 'oklch(0.515 0.206 28.695)', // #c20c0c hsl(0, 88%, 40%)
				alias: 'NetEaseCloudMusic'
			},
			{
				color: 'oklch(0.566 0.238 268.917)', // #415fff hsl(231, 100%, 63%)
				alias: 'vivo'
			}
		]
	}
};

export default Chameleon;



================================================
FILE: docs/site/src/data/themes/citrus.ts
================================================
import type { ThemeProps } from 'stdf/theme';

const Citrus: ThemeProps = {
	name: 'Citrus',
	color: {
		primary: {
			50: 'oklch(0.985 0.008 236.556)', // #F5FBFF hsl(204, 100%, 98%)
			100: 'oklch(0.963 0.019 240.727)', // #E8F5FF hsl(206, 100%, 96%)
			200: 'oklch(0.818 0.048 241.473)', // #A9C8E0 hsl(206, 47%, 77%)
			300: 'oklch(0.677 0.07 246.931)', // #749CC1 hsl(209, 38%, 61%)
			400: 'oklch(0.548 0.088 251.698)', // #4974A3 hsl(211, 38%, 46%)
			500: 'oklch(0.431 0.097 254.641)', // #275184 hsl(213, 54%, 34%)
			default: 'oklch(0.324 0.099 258.036)', // #0E3265 hsl(215, 76%, 23%)
			700: 'oklch(0.298 0.102 260.178)', // #0A2A5F hsl(217, 81%, 21%)
			800: 'oklch(0.274 0.103 261.304)', // #062359 hsl(219, 87%, 19%)
			900: 'oklch(0.251 0.105 262.192)', // #031C53 hsl(221, 93%, 17%)
			950: 'oklch(0.229 0.106 261.947)' // #00164D hsl(223, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.997 0.013 106.635)', // #FFFFF5 hsl(60, 100%, 98%)
			100: 'oklch(0.994 0.03 106.933)', // #FFFFE8 hsl(60, 100%, 96%)
			200: 'oklch(0.967 0.08 105.52)', // #FBF8B9 hsl(57, 89%, 86%)
			300: 'oklch(0.937 0.122 105)', // #F6EF8B hsl(56, 86%, 76%)
			400: 'oklch(0.903 0.152 102.892)', // #F2E35E hsl(54, 85%, 66%)
			500: 'oklch(0.867 0.168 100.267)', // #EDD533 hsl(52, 84%, 57%)
			default: 'oklch(0.826 0.168 94.589)', // #E9C30A hsl(50, 92%, 48%)
			700: 'oklch(0.707 0.144 91.085)', // #C29C06 hsl(48, 94%, 39%)
			800: 'oklch(0.588 0.12 87.218)', // #9B7703 hsl(46, 96%, 31%)
			900: 'oklch(0.47 0.096 83.886)', // #745501 hsl(44, 98%, 23%)
			950: 'oklch(0.35 0.072 82.069)' // #4D3600 hsl(42, 100%, 15%)
		},
		primaryBlack: 'oklch(0.147 0.037 249.929)', // #010B19 hsl(215, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(215, 5%, 95%)
		darkBlack: 'oklch(0.195 0.038 99.68)', // #191501 hsl(50, 95%, 5%)
		darkWhite: 'oklch(0.964 0.001 106.424)', // #F3F3F2 hsl(50, 5%, 95%)
		functional: {
			success: 'oklch(0.637 0.184 146.403)', // #1ba73e hsl(135, 72%, 38%)
			warning: 'oklch(0.495 0.128 47.783)', // #9a460e hsl(24, 83%, 33%)
			error: 'oklch(0.504 0.203 28.76)', // #bd0a0a hsl(0, 90%, 39%)
			info: 'oklch(0.466 0.24 284.096)' // #5628d7 hsl(256, 69%, 50%)
		},
		extend: [
			{
				color: 'oklch(0.703 0.149 235.113)', // oklch(0.703 0.149 235.059) hsl(197, 98%, 47%)
				alias: 'Twitter'
			},
			{
				color: 'oklch(0.702 0.194 38.137)', // oklch(0.702 0.194 38.137) hsl(15, 100%, 61%)
				alias: 'Svelte'
			},
			{
				color: 'oklch(0.716 0.171 53.446)', // #f38020 hsl(27, 90%, 54%)
				alias: 'Cloudflare'
			}
		]
	}
};

export default Citrus;



================================================
FILE: docs/site/src/data/themes/greenJade.ts
================================================
import type { ThemeProps } from 'stdf/theme';

const GreenJade: ThemeProps = {
	name: 'GreenJade',
	color: {
		primary: {
			50: 'oklch(0.992 0.011 176.326)', // #F5FFFC hsl(162, 100%, 98%)
			100: 'oklch(0.982 0.025 181.302)', // #E8FFFA hsl(167, 100%, 96%)
			200: 'oklch(0.871 0.05 182.107)', // #B1E0D7 hsl(169, 43%, 79%)
			300: 'oklch(0.765 0.067 183.674)', // #81C1B7 hsl(171, 34%, 63%)
			400: 'oklch(0.662 0.075 185.315)', // #59A299 hsl(173, 29%, 49%)
			500: 'oklch(0.561 0.075 188.146)', // #38837D hsl(175, 40%, 37%)
			default: 'oklch(0.46 0.067 190.938)', // #1F6461 hsl(177, 53%, 26%)
			700: 'oklch(0.44 0.068 193.584)', // #165E5D hsl(179, 62%, 23%)
			800: 'oklch(0.416 0.066 196.348)', // #0E5758 hsl(181, 73%, 20%)
			900: 'oklch(0.389 0.064 199.408)', // #064F52 hsl(182, 86%, 17%)
			950: 'oklch(0.36 0.062 206.153)' // #00464D hsl(186, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.993 0.011 95.159)', // #FFFDF5 hsl(48, 100%, 98%)
			100: 'oklch(0.984 0.024 94.062)', // #FFFAE8 hsl(47, 100%, 96%)
			200: 'oklch(0.963 0.055 93.624)', // #FFF3CA hsl(46, 100%, 90%)
			300: 'oklch(0.938 0.081 90.541)', // #FFE9AC hsl(44, 100%, 84%)
			400: 'oklch(0.909 0.106 87.283)', // #FFDD8D hsl(42, 100%, 78%)
			500: 'oklch(0.877 0.126 83.083)', // #FFCF6F hsl(40, 100%, 72%)
			default: 'oklch(0.844 0.144 77.934)', // #FFBF51 hsl(38, 100%, 66%)
			700: 'oklch(0.707 0.132 72.908)', // #D29232 hsl(36, 64%, 51%)
			800: 'oklch(0.574 0.117 66.999)', // #A6691A hsl(34, 73%, 38%)
			900: 'oklch(0.444 0.097 61.688)', // #79450A hsl(32, 85%, 26%)
			950: 'oklch(0.315 0.075 58.16)' // #4D2600 hsl(30, 100%, 15%)
		},
		primaryBlack: 'oklch(0.193 0.032 191.218)', // #011918 hsl(177, 95%, 5%)
		primaryWhite: 'oklch(0.963 0.001 197.138)', // #F2F3F3 hsl(177, 5%, 95%)
		darkBlack: 'oklch(0.18 0.034 82.944)', // #191001 hsl(38, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(38, 5%, 95%)
		functional: {
			success: 'oklch(0.618 0.208 142.486)', // #09a207 hsl(119, 92%, 33%)
			warning: 'oklch(0.677 0.149 65.479)', // #d4810c hsl(35, 89%, 44%)
			error: 'oklch(0.554 0.224 28.911)', // #d70909 hsl(0, 92%, 44%)
			info: 'oklch(0.419 0.238 264.463)' // #062ecb hsl(228, 94%, 41%)
		},
		extend: [
			{
				color: 'oklch(0.492 0.217 261.351)', // oklch(0.492 0.217 261.351) hsl(217, 100%, 43%)
				alias: 'Tencent'
			},
			{
				color: 'oklch(0.606 0.23 11.741)', // #ea1d5d hsl(341, 83%, 52%)
				alias: 'Aparat'
			},
			{
				color: 'oklch(0.588 0.134 239.667)', // #0085c3 hsl(199, 100%, 38%)
				alias: 'Dell'
			}
		]
	}
};

export default GreenJade;



================================================
FILE: docs/site/src/data/themes/index.ts
================================================
import { STDFTheme } from 'stdf/theme';
import Chameleon from './chameleon.js';
import AzurePink from './azurePink.js';
import SmartLive from './smartLive.js';
import CamelliaRed from './camelliaRed.js';
import Nintendo from './nintendo.js';
import Skybloom from './skybloom.js';
import Aqua from './aqua.js';
import KleinH from './kleinH.js';
import Azuper from './azuper.js';
import Citrus from './citrus.js';
import Lavender from './lavender.js';
import TealMedley from './tealMedley.js';
import GreenJade from './greenJade.js';

export default [
	{ name_CN: 'STDF', name: STDFTheme.name, theme: STDFTheme },
	{ name_CN: '任天堂', name: Nintendo.name, theme: Nintendo },
	{ name_CN: '蔚蓝粉', name: AzurePink.name, theme: AzurePink },
	{ name_CN: '变色龙', name: Chameleon.name, theme: Chameleon },
	{ name_CN: '慧活力', name: SmartLive.name, theme: SmartLive },
	{ name_CN: '蓝采绿', name: Aqua.name, theme: Aqua },
	{ name_CN: '山茶红', name: CamelliaRed.name, theme: CamelliaRed },
	{ name_CN: '蓝粉梦', name: Skybloom.name, theme: Skybloom },
	{ name_CN: '克莱仕', name: KleinH.name, theme: KleinH },
	{ name_CN: '石青柿', name: Azuper.name, theme: Azuper },
	{ name_CN: '青佛手', name: Citrus.name, theme: Citrus },
	{ name_CN: '以初紫', name: Lavender.name, theme: Lavender },
	{ name_CN: '青什锦', name: TealMedley.name, theme: TealMedley },
	{ name_CN: '绿玉子', name: GreenJade.name, theme: GreenJade }
];



================================================
FILE: docs/site/src/data/themes/kleinH.ts
================================================
import type { ThemeProps } from 'stdf/theme';

const KleinH: ThemeProps = {
	name: 'KleinH',
	color: {
		primary: {
			50: 'oklch(0.983 0.009 247.912)', // #F5FAFF hsl(210, 100%, 98%)
			100: 'oklch(0.957 0.021 254.913)', // #E8F2FF hsl(214, 100%, 96%)
			200: 'oklch(0.817 0.061 257.788)', // #ABC5EB hsl(216, 62%, 80%)
			300: 'oklch(0.681 0.099 261.163)', // #7699D6 hsl(218, 54%, 65%)
			400: 'oklch(0.559 0.134 262.606)', // #4871C2 hsl(220, 50%, 52%)
			500: 'oklch(0.446 0.164 263.584)', // #214BAD hsl(222, 68%, 40%)
			default: 'oklch(0.355 0.183 263.561)', // #022A99 hsl(224, 97%, 30%)
			700: 'oklch(0.316 0.17 263.812)', // #012086 hsl(226, 99%, 27%)
			800: 'oklch(0.28 0.155 264.078)', // #011873 hsl(228, 98%, 23%)
			900: 'oklch(0.242 0.139 263.958)', // #001060 hsl(230, 100%, 19%)
			950: 'oklch(0.207 0.12 264.016)' // #000A4D hsl(232, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.991 0.01 87.47)', // #FFFCF5 hsl(42, 100%, 98%)
			100: 'oklch(0.978 0.022 83.264)', // #FFF7E8 hsl(39, 100%, 96%)
			200: 'oklch(0.935 0.058 80.464)', // #FEE6BE hsl(38, 97%, 87%)
			300: 'oklch(0.886 0.094 74.988)', // #FED193 hsl(35, 98%, 79%)
			400: 'oklch(0.837 0.125 70.641)', // #FDBB69 hsl(33, 97%, 70%)
			500: 'oklch(0.786 0.153 63.13)', // #FDA140 hsl(31, 98%, 62%)
			default: 'oklch(0.734 0.178 54.177)', // #FC8416 hsl(29, 98%, 54%)
			700: 'oklch(0.625 0.159 50.796)', // #D0650E hsl(27, 87%, 44%)
			800: 'oklch(0.515 0.137 47.874)', // #A44907 hsl(25, 92%, 34%)
			900: 'oklch(0.405 0.113 45.466)', // #783003 hsl(23, 95%, 24%)
			950: 'oklch(0.295 0.084 45.171)' // #4D1B00 hsl(21, 100%, 15%)
		},
		primaryBlack: 'oklch(0.133 0.043 259.636)', // #010719 hsl(224, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(224, 5%, 95%)
		darkBlack: 'oklch(0.17 0.034 67.389)', // #190C01 hsl(29, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(29, 5%, 95%)
		functional: {
			success: 'oklch(0.439 0.132 145.643)', // #07641d hsl(134, 87%, 21%)
			warning: 'oklch(0.566 0.171 39.514)', // #c54711 hsl(18, 84%, 42%)
			error: 'oklch(0.497 0.177 16.155)', // #b0213e hsl(348, 68%, 41%)
			info: 'oklch(0.573 0.096 219.542)' // #1d859f hsl(192, 69%, 37%)
		},
		extend: [
			{
				color: 'oklch(0.686 0.139 231.254)', // #00a8e0 hsl(195, 100%, 44%)
				alias: 'AT&T'
			},
			{
				color: 'oklch(0.651 0.212 142.608)', // oklch(0.651 0.212 142.608) hsl(120, 75%, 39%)
				alias: 'WeChat'
			},
			{
				color: 'oklch(0.652 0.199 0.712)', // #ea4c89 hsl(337, 79%, 61%)
				alias: 'Dribbble'
			}
		]
	}
};

export default KleinH;



================================================
FILE: docs/site/src/data/themes/lavender.ts
================================================
import type { ThemeProps } from 'stdf/theme';

const Lavender: ThemeProps = {
	name: 'Lavender',
	color: {
		primary: {
			50: 'oklch(0.978 0.015 315.966)', // #FCF5FF hsl(282, 100%, 98%)
			100: 'oklch(0.95 0.035 315.73)', // #F8E8FF hsl(282, 100%, 96%)
			200: 'oklch(0.842 0.065 314.453)', // #DBBFE9 hsl(280, 49%, 83%)
			300: 'oklch(0.739 0.091 312.314)', // #BE9AD4 hsl(277, 40%, 72%)
			400: 'oklch(0.641 0.109 310.145)', // #A179BE hsl(275, 35%, 61%)
			500: 'oklch(0.551 0.124 307.99)', // #865CA9 hsl(273, 31%, 51%)
			default: 'oklch(0.467 0.13 305.627)', // #6C4393 hsl(271, 37%, 42%)
			700: 'oklch(0.392 0.138 302.664)', // #552C81 hsl(269, 49%, 34%)
			800: 'oklch(0.326 0.14 298.682)', // #401970 hsl(267, 64%, 27%)
			900: 'oklch(0.269 0.132 293.856)', // #2D0B5E hsl(265, 79%, 21%)
			950: 'oklch(0.216 0.123 289.042)' // #1D004D hsl(263, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.971 0.017 349.48)', // #FFF1F7 hsl(334, 100%, 97%)
			100: 'oklch(0.953 0.029 347.076)', // #FFE8F3 hsl(331, 100%, 96%)
			200: 'oklch(0.926 0.042 344.642)', // #FCDCED hsl(328, 84%, 93%)
			300: 'oklch(0.901 0.053 344.002)', // #F9D1E7 hsl(327, 77%, 90%)
			400: 'oklch(0.874 0.065 342.674)', // #F5C5E1 hsl(325, 71%, 87%)
			500: 'oklch(0.85 0.078 340.995)', // #F2BADD hsl(323, 68%, 84%)
			default: 'oklch(0.826 0.092 339.861)', // #EFAFD9 hsl(321, 67%, 81%)
			700: 'oklch(0.654 0.135 340.177)', // #C66DAA hsl(319, 44%, 60%)
			800: 'oklch(0.512 0.156 340.793)', // #9E3A81 hsl(317, 46%, 42%)
			900: 'oklch(0.391 0.15 340.551)', // #75155D hsl(315, 70%, 27%)
			950: 'oklch(0.284 0.123 340.171)' // #4D003C hsl(313, 100%, 15%)
		},
		primaryBlack: 'oklch(0.129 0.059 306.37)', // #0D0119 hsl(271, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(271, 5%, 95%)
		darkBlack: 'oklch(0.146 0.057 343.966)', // #190110 hsl(321, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(321, 5%, 95%)
		functional: {
			success: 'oklch(0.784 0.194 147.722)', // #4ad96b hsl(134, 65%, 57%)
			warning: 'oklch(0.693 0.147 42.888)', // #e67a4c hsl(18, 76%, 60%)
			error: 'oklch(0.639 0.192 24.341)', // #e94e4e hsl(0, 78%, 61%)
			info: 'oklch(0.613 0.168 270.082)' // #5e7ae8 hsl(228, 75%, 64%)
		},
		extend: [
			{
				color: 'oklch(0.492 0.217 261.351)', // oklch(0.492 0.217 261.351) hsl(217, 100%, 43%)
				alias: 'Tencent'
			},
			{
				color: 'oklch(0.651 0.212 142.608)', // oklch(0.651 0.212 142.608) hsl(120, 75%, 39%)
				alias: 'WeChat'
			},
			{
				color: 'oklch(0.343 0.077 256.446)', // #1c3960 hsl(214, 55%, 24%)
				alias: 'Ford'
			}
		]
	}
};

export default Lavender;



================================================
FILE: docs/site/src/data/themes/nintendo.ts
================================================
import type { ThemeProps } from 'stdf/theme';

const Nintendo: ThemeProps = {
	name: 'Nintendo',
	color: {
		primary: {
			50: 'oklch(0.98 0.01 25.073)', // #FFF6F5 hsl(6, 100%, 98%)
			100: 'oklch(0.953 0.023 24.126)', // #FFEAE8 hsl(5, 100%, 96%)
			200: 'oklch(0.845 0.076 21.796)', // #FAB9B6 hsl(3, 87%, 85%)
			300: 'oklch(0.745 0.133 21.872)', // #F58886 hsl(1, 85%, 74%)
			400: 'oklch(0.662 0.188 22.749)', // #F0575A hsl(359, 84%, 64%)
			500: 'oklch(0.609 0.224 25.256)', // #EB2B34 hsl(357, 83%, 55%)
			default: 'oklch(0.581 0.238 27.862)', // #E60012 hsl(355, 100%, 45%)
			700: 'oklch(0.508 0.207 26.549)', // #C00016 hsl(353, 100%, 38%)
			800: 'oklch(0.43 0.174 24.608)', // #990017 hsl(351, 100%, 30%)
			900: 'oklch(0.351 0.141 21.971)', // #730015 hsl(349, 100%, 23%)
			950: 'oklch(0.266 0.107 17.45)' // #4D0011 hsl(347, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.992 0.011 189.833)', // #F5FFFE hsl(174, 100%, 98%)
			100: 'oklch(0.983 0.024 193.6)', // #E8FFFE hsl(177, 100%, 96%)
			200: 'oklch(0.938 0.067 196.074)', // #B6F9F9 hsl(180, 85%, 85%)
			300: 'oklch(0.893 0.099 198.69)', // #85F0F4 hsl(182, 84%, 74%)
			400: 'oklch(0.847 0.12 201.806)', // #57E4EE hsl(184, 82%, 64%)
			500: 'oklch(0.803 0.131 206.757)', // #2AD6E9 hsl(186, 81%, 54%)
			default: 'oklch(0.752 0.133 215.123)', // #00C3E3 hsl(189, 100%, 45%)
			700: 'oklch(0.646 0.116 218.359)', // #009EBD hsl(190, 100%, 37%)
			800: 'oklch(0.535 0.1 223.819)', // #007998 hsl(192, 100%, 30%)
			900: 'oklch(0.426 0.083 227.589)', // #005772 hsl(194, 100%, 22%)
			950: 'oklch(0.319 0.064 230.58)' // #00384D hsl(196, 100%, 15%)
		},
		primaryBlack: 'oklch(0.139 0.05 18.003)', // #190103 hsl(355, 95%, 5%)
		primaryWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(355, 5%, 95%)
		darkBlack: 'oklch(0.184 0.03 206.812)', // #011619 hsl(188, 95%, 5%)
		darkWhite: 'oklch(0.963 0.001 197.138)', // #F2F3F3 hsl(188, 5%, 95%)
		functional: {
			success: 'oklch(0.669 0.214 144.385)', // #00b42a hsl(134, 100%, 35%)
			warning: 'oklch(0.865 0.176 95.103)', // #f7d00c hsl(50, 94%, 51%)
			error: 'oklch(0.642 0.218 25.88)', // #f53f3f hsl(0, 90%, 60%)
			info: 'oklch(0.549 0.249 263.048)' // #165dff hsl(222, 100%, 54%)
		},
		extend: [
			{
				color: 'oklch(0.492 0.217 261.351)', // #0052d9 hsl(217, 100%, 43%)
				alias: 'Tencent'
			},
			{
				color: 'oklch(0.651 0.212 142.608)', // #1aad19 hsl(120, 75%, 39%)
				alias: 'WeChat'
			},
			{
				color: 'oklch(0.692 0.181 46.213)', // #f37021 hsl(23, 90%, 54%)
				alias: 'Hermès'
			}
		]
	}
};

export default Nintendo;



================================================
FILE: docs/site/src/data/themes/skybloom.ts
================================================
import type { ThemeProps } from 'stdf/theme';

const Skybloom: ThemeProps = {
	name: 'Skybloom',
	color: {
		primary: {
			50: 'oklch(0.987 0.008 225.079)', // #F5FCFF hsl(198, 100%, 98%)
			100: 'oklch(0.969 0.019 225.712)', // #E8F8FF hsl(198, 100%, 96%)
			200: 'oklch(0.863 0.05 229.685)', // #B1D9ED hsl(200, 63%, 81%)
			300: 'oklch(0.759 0.075 234.966)', // #81B9DA hsl(202, 55%, 68%)
			400: 'oklch(0.66 0.098 240.067)', // #569AC8 hsl(204, 51%, 56%)
			500: 'oklch(0.566 0.115 244.99)', // #317CB5 hsl(206, 57%, 45%)
			default: 'oklch(0.479 0.13 251.007)', // #125FA3 hsl(208, 80%, 36%)
			700: 'oklch(0.42 0.122 253.316)', // #0C4D8D hsl(210, 84%, 30%)
			800: 'oklch(0.359 0.116 256.313)', // #073B78 hsl(212, 89%, 25%)
			900: 'oklch(0.303 0.105 257.617)', // #032C62 hsl(214, 94%, 20%)
			950: 'oklch(0.251 0.093 258.021)' // #001F4D hsl(216, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.975 0.012 23.703)', // #FFF4F3 hsl(5, 100%, 98%)
			100: 'oklch(0.949 0.025 17.604)', // #FFE8E8 hsl(0, 100%, 96%)
			200: 'oklch(0.92 0.038 17.861)', // #FDDBDB hsl(0, 90%, 93%)
			300: 'oklch(0.89 0.05 15.051)', // #FACED0 hsl(357, 82%, 89%)
			400: 'oklch(0.861 0.063 12.376)', // #F8C1C6 hsl(355, 80%, 87%)
			500: 'oklch(0.832 0.076 10.667)', // #F5B4BC hsl(353, 77%, 83%)
			default: 'oklch(0.807 0.089 9.599)', // #F3A8B3 hsl(351, 76%, 81%)
			700: 'oklch(0.635 0.124 9.491)', // #C9687A hsl(349, 47%, 60%)
			800: 'oklch(0.493 0.139 10.638)', // #A0374E hsl(347, 49%, 42%)
			900: 'oklch(0.374 0.131 12.448)', // #76142D hsl(345, 71%, 27%)
			950: 'oklch(0.268 0.107 13.338)' // #4D0016 hsl(343, 100%, 15%)
		},
		primaryBlack: 'oklch(0.156 0.033 240.386)', // #010E19 hsl(208, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(208, 5%, 95%)
		darkBlack: 'oklch(0.14 0.05 14.109)', // #190104 hsl(351, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(351, 5%, 95%)
		functional: {
			success: 'oklch(0.7 0.181 152.201)', // #0fbd63 hsl(149, 85%, 40%)
			warning: 'oklch(0.534 0.132 51.034)', // #a75211 hsl(26, 82%, 36%)
			error: 'oklch(0.58 0.211 10.496)', // #d9265c hsl(342, 70%, 50%)
			info: 'oklch(0.458 0.218 283.692)' // #5231c9 hsl(253, 61%, 49%)
		},
		extend: [
			{
				color: 'oklch(0.703 0.149 235.113)', // oklch(0.703 0.149 235.059) hsl(197, 98%, 47%)
				alias: 'Twitter'
			},
			{
				color: 'oklch(0.702 0.194 38.137)', // oklch(0.702 0.194 38.137) hsl(15, 100%, 61%)
				alias: 'Svelte'
			},
			{
				color: 'oklch(0.518 0.199 259.881)', // #0e5fd8 hsl(216, 88%, 45%)
				alias: 'Philips'
			}
		]
	}
};

export default Skybloom;



================================================
FILE: docs/site/src/data/themes/smartLive.ts
================================================
import type { ThemeProps } from 'stdf/theme';

const SmartLive: ThemeProps = {
	name: 'SmartLive',
	color: {
		primary: {
			50: 'oklch(0.978 0.015 315.966)', // #FCF5FF hsl(282, 100%, 98%)
			100: 'oklch(0.95 0.035 315.73)', // #F8E8FF hsl(282, 100%, 96%)
			200: 'oklch(0.794 0.075 313.533)', // #CDAEDE hsl(279, 42%, 78%)
			300: 'oklch(0.652 0.103 312.25)', // #A57DBD hsl(278, 33%, 62%)
			400: 'oklch(0.522 0.119 309.358)', // #7E549D hsl(275, 30%, 47%)
			500: 'oklch(0.406 0.122 307.073)', // #5B337C hsl(273, 42%, 34%)
			default: 'oklch(0.304 0.112 304.532)', // #3C1A5B hsl(271, 56%, 23%)
			700: 'oklch(0.28 0.115 301.336)', // #341357 hsl(269, 64%, 21%)
			800: 'oklch(0.258 0.119 297.251)', // #2C0C54 hsl(267, 75%, 19%)
			900: 'oklch(0.238 0.12 293.937)', // #250650 hsl(265, 86%, 17%)
			950: 'oklch(0.216 0.123 289.042)' // #1D004D hsl(263, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.98 0.01 25.073)', // #FFF6F5 hsl(6, 100%, 98%)
			100: 'oklch(0.953 0.023 24.126)', // #FFEAE8 hsl(5, 100%, 96%)
			200: 'oklch(0.902 0.051 19.634)', // #FFD2D1 hsl(1, 100%, 91%)
			300: 'oklch(0.853 0.08 18.86)', // #FFBABA hsl(0, 100%, 87%)
			400: 'oklch(0.806 0.111 17.023)', // #FFA2A6 hsl(357, 100%, 82%)
			500: 'oklch(0.765 0.14 16.578)', // #FF8B93 hsl(356, 100%, 77%)
			default: 'oklch(0.728 0.169 15.672)', // #FF7483 hsl(354, 100%, 73%)
			700: 'oklch(0.597 0.173 16.54)', // #D2485A hsl(352, 61%, 55%)
			800: 'oklch(0.482 0.163 17.177)', // #A6263B hsl(350, 63%, 40%)
			900: 'oklch(0.373 0.138 17.973)', // #790E23 hsl(348, 79%, 27%)
			950: 'oklch(0.267 0.107 16.66)' // #4D0012 hsl(346, 100%, 15%)
		},
		primaryBlack: 'oklch(0.129 0.059 306.37)', // #0D0119 hsl(271, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(271, 5%, 95%)
		darkBlack: 'oklch(0.139 0.05 18.003)', // #190103 hsl(354, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(354, 5%, 95%)
		functional: {
			success: 'oklch(0.419 0.092 155.284)', // #155b36 hsl(148, 63%, 22%)
			warning: 'oklch(0.666 0.147 65.222)', // #d07e0b hsl(35, 90%, 43%)
			error: 'oklch(0.564 0.223 28.46)', // #da1414 hsl(0, 83%, 47%)
			info: 'oklch(0.728 0.107 239.498)' // #63b0e3 hsl(204, 70%, 64%)
		},
		extend: [
			{
				color: 'oklch(0.713 0.194 130.802)', // #76b900 hsl(82, 100%, 36%)
				alias: 'NVIDIA'
			},
			{
				color: 'oklch(0.726 0.171 4.454)', // #fb7299 hsl(343, 95%, 72%)
				alias: 'bilibili'
			},
			{
				color: 'oklch(0.599 0.219 259.04)', // #1677ff hsl(215, 100%, 54%)
				alias: 'AliPay'
			}
		]
	}
};

export default SmartLive;



================================================
FILE: docs/site/src/data/themes/tealMedley.ts
================================================
import type { ThemeProps } from 'stdf/theme';

const TealMedley: ThemeProps = {
	name: 'TealMedley',
	color: {
		primary: {
			50: 'oklch(0.991 0.01 204.917)', // #F5FEFF hsl(186, 100%, 98%)
			100: 'oklch(0.977 0.021 207.588)', // #E8FCFF hsl(188, 100%, 96%)
			200: 'oklch(0.877 0.046 213.81)', // #B5DFE9 hsl(192, 54%, 81%)
			300: 'oklch(0.78 0.063 217.138)', // #89C2D2 hsl(193, 45%, 68%)
			400: 'oklch(0.686 0.076 222.122)', // #62A5BC hsl(195, 40%, 56%)
			500: 'oklch(0.595 0.084 226.019)', // #4089A5 hsl(197, 44%, 45%)
			default: 'oklch(0.509 0.088 231.916)', // #256E8F hsl(199, 59%, 35%)
			700: 'oklch(0.448 0.086 236.944)', // #195B7E hsl(201, 67%, 30%)
			800: 'oklch(0.389 0.085 242.356)', // #0E496E hsl(203, 77%, 24%)
			900: 'oklch(0.334 0.081 245.985)', // #06395D hsl(205, 88%, 19%)
			950: 'oklch(0.28 0.078 249.311)' // #002A4D hsl(207, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.971 0.015 33.071)', // #FFF2EF hsl(11, 100%, 97%)
			100: 'oklch(0.957 0.021 31.78)', // #FFECE8 hsl(10, 100%, 96%)
			200: 'oklch(0.932 0.028 28.52)', // #FBE2DE hsl(8, 78%, 93%)
			300: 'oklch(0.905 0.036 24.203)', // #F7D7D4 hsl(5, 69%, 90%)
			400: 'oklch(0.879 0.042 23.456)', // #F2CDCA hsl(5, 61%, 87%)
			500: 'oklch(0.852 0.051 21.242)', // #EEC2C0 hsl(3, 58%, 84%)
			default: 'oklch(0.825 0.059 18.425)', // #EAB7B7 hsl(0, 55%, 82%)
			700: 'oklch(0.642 0.102 17.954)', // #C37275 hsl(358, 40%, 61%)
			800: 'oklch(0.49 0.126 19.197)', // #9B3D43 hsl(356, 44%, 42%)
			900: 'oklch(0.369 0.126 21.232)', // #741720 hsl(354, 67%, 27%)
			950: 'oklch(0.265 0.107 22.403)' // #4D000A hsl(352, 100%, 15%)
		},
		primaryBlack: 'oklch(0.167 0.03 228.62)', // #011119 hsl(199, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(199, 5%, 95%)
		darkBlack: 'oklch(0.138 0.051 27.08)', // #190101 hsl(0, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(0, 5%, 95%)
		functional: {
			success: 'oklch(0.608 0.142 148.314)', // #38994f hsl(134, 46%, 41%)
			warning: 'oklch(0.776 0.119 100.626)', // #c7b857 hsl(52, 50%, 56%)
			error: 'oklch(0.66 0.146 21.85)', // #dd6969 hsl(0, 63%, 64%)
			info: 'oklch(0.559 0.131 271.419)' // #596dc0 hsl(228, 45%, 55%)
		},
		extend: [
			{
				color: 'oklch(0.492 0.217 261.351)', // oklch(0.492 0.217 261.351) hsl(217, 100%, 43%)
				alias: 'Tencent'
			},
			{
				color: 'oklch(0.424 0.097 251.575)', // #205081 hsl(210, 60%, 32%)
				alias: 'Bitbucket'
			},
			{
				color: 'oklch(0.364 0.191 266.82)', // #1428a0 hsl(231, 78%, 35%)
				alias: 'Samsung'
			}
		]
	}
};

export default TealMedley;



================================================
FILE: docs/site/src/lib/index.ts
================================================
// place files you want to import through the `$lib` alias in this folder.



================================================
FILE: docs/site/src/lib/clis/Clis.svelte
================================================
<script lang="ts">
	import { onMount, onDestroy } from 'svelte';
	import codeGroupSvgData from '../../utils/code-group-svg-data';
	const isZh = localStorage.getItem('lang') === 'zh_CN';

	// 将 codeGroupSvgData 随机打乱
	const randomCodeGroupSvgData = codeGroupSvgData.sort(() => Math.random() - 0.5);

	let showCli = $state(0);
	let intervalTime: ReturnType<typeof setInterval>;
	let isClicked = $state(false);
	let isHover = $state(false);
	let textCli = $state('_');
	let times: ReturnType<typeof setInterval>;
	// 写一个函数，模拟打字效果，传入一段文字，返回一个打字效果的函数
	const typeWriter = (text: string, speed: number = 150) => {
		let number = 0;
		times = setInterval(() => {
			number++;
			if (number >= text.length) {
				number = 0;
				textCli = text;
				clearInterval(times);
			} else {
				textCli = text.slice(0, number) + '_';
			}
		}, speed);
	};
	// 动画
	const animationFun = () => {
		typeWriter(randomCodeGroupSvgData[showCli].cli);
		// 每 3 秒切换一次
		intervalTime = setInterval(() => {
			if (showCli === codeGroupSvgData.length - 1) {
				showCli = 0;
			} else {
				showCli++;
			}
			textCli = '_';
			setTimeout(() => {
				typeWriter(randomCodeGroupSvgData[showCli].cli);
			}, 300);
		}, 6000);
	};
	onMount(() => {
		animationFun();
		window.addEventListener('visibilitychange', () => {
			if (document.visibilityState === 'visible') {
				animationFun();
			} else {
				clearInterval(intervalTime);
				clearInterval(times);
			}
		});
	});
	onDestroy(() => {
		clearInterval(intervalTime);
		clearInterval(times);
	});
</script>

<div class="inline-flex justify-center">
	<div class="bg-primary/5 dark:bg-dark/10 rounded-l-full text-xs">
		<div class="mr-2 flex h-7 items-center gap-1 pl-3">{@html randomCodeGroupSvgData[showCli].svg}</div>
	</div>
	<button
		type="button"
		onmouseenter={() => (isHover = true)}
		onmouseleave={() => (isHover = false)}
		class="bg-primary/5 dark:bg-dark/10 relative inline-flex cursor-copy items-center justify-center rounded-r-full py-1 pr-3"
		onclick={async () => {
			await navigator.clipboard.writeText(randomCodeGroupSvgData[showCli].cli);
			isClicked = true;
			setTimeout(() => {
				isClicked = false;
			}, 2000);
		}}
	>
		<code class="text-primary dark:text-dark text-sm opacity-80">{textCli}</code>
		<div
			class="bg-primary dark:bg-dark rounded-xs absolute -top-3 left-1/2 size-3 -translate-x-1/2 rotate-45 transition-all {isHover
				? '-translate-y-1/2 opacity-100'
				: '-translate-y-4 opacity-0'}"
		></div>
		<div
			class="bg-primary dark:bg-dark absolute -top-8 left-1/2 -translate-x-1/2 rounded-sm px-2 py-1 text-xs text-white transition-all dark:text-black {isHover
				? 'translate-y-0 opacity-100'
				: '-translate-y-2 opacity-0'}"
		>
			{isZh ? (isClicked ? '已复制' : '复制') : isClicked ? 'Copied' : 'Copy'}
		</div>
	</button>
</div>



================================================
FILE: docs/site/src/lib/cmdk/CmdK.svelte
================================================
<script lang="ts">
	import { fade, scale } from 'svelte/transition';
	import { menuList, type MenuList, type MenuListChild } from '../../data/menuList';
	import { page } from '$app/stores';
	import { goto } from '$app/navigation';
	import { isCmdKStore } from '../../store';

	//数组二级组成新数组
	const ArrChildFun = (arr: MenuList[]) => {
		let newArr = [];
		for (let e = 0; e < arr.length; e++) {
			newArr.push(...arr[e].childs);
		}
		return newArr;
	};

	const menuChildList: MenuListChild[] = ArrChildFun(menuList); //展开的菜单列表，全部
	const isZh = localStorage.getItem('lang') === 'zh_CN';
	const params = new URLSearchParams('?');

	let cmdKValue = $state(''); //cmd+k 搜索框的值
	let currentIndex = $state(0); //当前选中的索引
	let currentTab: number = $state(0); //当前选中的 tab
	let cmdFocus = $state(false); //cmd+k 搜索框是否获取焦点
	let cmdKInput: HTMLInputElement | null = $state(null); //cmd+k 搜索框的 dom
	let latelyList: MenuListChild[] = $state(localStorage.getItem('latelyList') ? JSON.parse(localStorage.getItem('latelyList') || '') : []); //最近使用的列表
	let isDemoShake = $state(false); //是否显示 demo 抖动动画
	let isGuideShake = $state(false); //是否显示 guide 抖动动画
	let cmdKList = $derived(
		cmdKValue === '' ? latelyList : menuChildList.filter((item: any) => item.alias.indexOf(cmdKValue.toLowerCase()) > -1)
	); //cmd+k 搜索框的列表
	let currentMenu = $derived(cmdKList[currentIndex]); //当前选中的菜单

	//cmd+k 搜索框的事件
	const cmdKFun = (e: KeyboardEvent) => {
		// 判断是 Windows 还是 Mac，cmd+k 在 Windows 下是 ctrl+k，监听 e.ctrlKey，Mac 监听 metaKey
		const isMac = /macintosh|mac os x/i.test(navigator.userAgent);
		const isWindows = /windows|win32/i.test(navigator.userAgent);

		//按下 cmd+k 触发事件
		if (e.key === 'k' && ((isMac && e.metaKey) || (isWindows && e.ctrlKey))) {
			const latelyListStr = localStorage.getItem('latelyList');
			latelyList = latelyListStr ? JSON.parse(latelyListStr) : [];
			if ($isCmdKStore) {
				isCmdKStore.set(false);
				cmdFocus = false;
			} else {
				isCmdKStore.set(true);
				cmdFocus = true;
				cmdKValue = '';
				currentIndex = 0;
				currentTab = 0;
				setTimeout(() => {
					cmdKInput?.focus();
				}, 0);
			}
			e.preventDefault();
		}
		//按下 esc 触发事件
		if ($isCmdKStore && e.key === 'Escape') {
			// 阻止默认事件
			e.preventDefault();
			//如果搜索框没有获取焦点，按下 esc 获取焦点并选定搜索框的值
			if (!cmdFocus) {
				cmdFocus = true;
				setTimeout(() => {
					cmdKInput?.focus();
					cmdKInput?.select();
				}, 0);
			} else {
				isCmdKStore.set(false);
				cmdFocus = false;
			}
		}

		//显示 cmd+k 搜索框时，按下上下键触发事件
		if ($isCmdKStore && (e.key === 'ArrowUp' || e.key === 'ArrowDown')) {
			//阻止默认事件，防止下层滚动
			e.preventDefault();
			cmdFocus = false;
			cmdKInput?.blur();
			if (e.key === 'ArrowUp') {
				if (currentIndex === 0 && currentTab === 0) {
					isDemoShake = true;
					setTimeout(() => {
						isDemoShake = false;
					}, 820);
					return;
				}
				if (currentTab === 0) {
					currentIndex = currentIndex === 0 ? cmdKList.length - 1 : currentIndex - 1;
					currentTab = 2;
				} else {
					currentTab--;
				}
			}
			if (e.key === 'ArrowDown') {
				if (currentIndex === cmdKList.length - 1 && currentTab === 2) {
					isGuideShake = true;
					setTimeout(() => {
						isGuideShake = false;
					}, 820);
					return;
				}
				if (currentTab === 2) {
					currentIndex = currentIndex === cmdKList.length - 1 ? 0 : currentIndex + 1;
					currentTab = 0;
				} else {
					currentTab++;
				}
			}
		}
		//显示 cmd+k 搜索框时，按下回车键触发事件
		if ($isCmdKStore && e.key === 'Enter') {
			const nav = currentMenu.nav;
			const tab = currentTab;
			//将当前选中的菜单添加到最近使用的列表中，并存储到 localStorage 中，最多存储 3 条
			if (latelyList.length > 0 && latelyList[0]?.nav) {
				let index = latelyList.findIndex((item) => item.nav === nav);
				if (index > -1) {
					// latelyList 中包含 currentMenu 时，将 currentMenu 移动到最前面
					const newLatelyList = latelyList.filter((item) => item.nav !== nav);
					newLatelyList.unshift(currentMenu);
					latelyList = newLatelyList;
				} else {
					// 如果 latelyList 中不包含 currentMenu，则将 currentMenu 添加到最前面
					latelyList.unshift(currentMenu);
				}
			} else {
				latelyList.push(currentMenu);
			}
			// 如果 latelyList 长度大于 3，则删除最后一个元素
			if (latelyList.length > 3) {
				latelyList.pop();
			}
			if (latelyList.length > 0 && latelyList[0]?.nav) {
				localStorage.setItem('latelyList', JSON.stringify(latelyList));
			}
			isCmdKStore.set(false);
			cmdFocus = false;
			cmdKValue = '';
			params.set('nav', nav);
			params.set('tab', tab.toString());
			goto(`/components?nav=${nav}&tab=${tab}`);
			if ($page.url.pathname.includes('/components')) {
				setTimeout(() => {
					window.location.reload();
				}, 10);
			}
		}
	};
	//点击搜索框的事件
	const clickCmdKFun = (item: MenuListChild, index: number) => {
		const nav = item.nav;
		const tab = index;
		//将当前选中的菜单添加到最近使用的列表中，并存储到 localStorage 中，最多存储 3 条
		if (latelyList.length > 0 && latelyList[0]?.nav) {
			let index = latelyList.findIndex((item) => item.nav === nav);
			if (index > -1) {
				// latelyList 中包含 item 时，将 item 移动到最前面
				const newLatelyList = latelyList.filter((item) => item.nav !== nav);
				newLatelyList.unshift(item);
				latelyList = newLatelyList;
			} else {
				// 如果 latelyList 中不包含 item，则将 item 添加到最前面
				latelyList.unshift(item);
			}
		} else {
			latelyList.push(item);
		}
		// 如果 latelyList 长度大于 3，则删除最后一个元素
		if (latelyList.length > 3) {
			latelyList.pop();
		}
		if (latelyList.length > 0 && latelyList[0]?.nav) {
			localStorage.setItem('latelyList', JSON.stringify(latelyList));
		}
		isCmdKStore.set(false);
		cmdFocus = false;
		cmdKValue = '';
		params.set('nav', nav);
		params.set('tab', tab.toString());
		goto(`/components?nav=${nav}&tab=${tab}`);
		if ($page.url.pathname.includes('/components')) {
			setTimeout(() => {
				window.location.reload();
			}, 10);
		}
	};
	//关闭 cmd+k 搜索框
	const closeCmdKFun = () => {
		isCmdKStore.set(false);
		cmdFocus = false;
	};
	$effect(() => {
		if ($isCmdKStore) {
			// const latelyListStr = localStorage.getItem('latelyList');
			// latelyList = latelyListStr ? JSON.parse(latelyListStr) : [];
			isCmdKStore.set(true);
			cmdFocus = true;
			currentIndex = 0;
			currentTab = 0;
			setTimeout(() => {
				cmdKInput?.focus();
			}, 0);
		}
	});
</script>

<svelte:window onkeydown={cmdKFun} />
<!-- svelte-ignore a11y_click_events_have_key_events -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
{#if $isCmdKStore}
	<div
		transition:fade
		class="fixed left-0 top-0 flex h-screen w-screen flex-col bg-black/20 pt-20 text-left backdrop-blur-sm"
		style="z-index: 10000"
		onclick={closeCmdKFun}
	>
		<div
			in:scale={{ duration: 300, delay: 100 }}
			out:scale={{ duration: 300 }}
			class="mx-auto rounded-xl bg-white shadow-lg dark:bg-black"
			onclick={(e: Event) => e.stopPropagation()}
		>
			<div class="flex items-center border-b border-black/10 px-4 py-3 text-sm text-gray-500 dark:border-white/10">
				<div class="">
					<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" style="fill: currentColor;">
						<path fill="none" d="M0 0h24v24H0z" />
						<path
							d="M11 2c4.968 0 9 4.032 9 9s-4.032 9-9 9-9-4.032-9-9 4.032-9 9-9zm0 16c3.867 0 7-3.133 7-7 0-3.868-3.133-7-7-7-3.868 0-7 3.132-7 7 0 3.867 3.132 7 7 7zm8.485.071l2.829 2.828-1.415 1.415-2.828-2.829 1.414-1.414z"
						/>
					</svg>
				</div>
				<div class="grow px-3 text-gray-800 dark:text-gray-200">
					<input
						bind:this={cmdKInput}
						bind:value={cmdKValue}
						class="focus:ring-b caret-primary dark:caret-dark focus:outline-hidden w-full placeholder:text-black/20 dark:bg-black dark:placeholder:text-white/30"
						type="text"
						placeholder={isZh ? '请输入组件关键字' : 'Please enter the component keyword'}
					/>
				</div>
				<div class="rounded-sm border border-black/10 px-2 py-1 text-xs font-bold dark:border-white/10">ESC</div>
			</div>
			<div class="overflow-y-auto px-6 pb-6" style="max-height: {(document.documentElement.clientHeight * 3) / 4}px">
				{#if cmdKValue === ''}
					<div class="mt-2 text-xs text-black/50 dark:text-white/30">
						{#if latelyList.length === 0}
							{isZh ? `最近无搜索，请输入关键字搜索。` : `No recent searches, please enter a keyword to search.`}
						{:else}
							{isZh ? `最近搜索 ${latelyList.length} 条结果` : `Recent search ${latelyList.length} results`}
						{/if}
					</div>
				{/if}
				{#if cmdKValue !== ''}
					{#if cmdKList.length === 0}
						<div class="mt-2 text-xs text-black/50 dark:text-white/30">
							{isZh ? '没有搜索到结果' : 'No results found'}
						</div>
					{:else}
						<div class="mt-2 text-xs text-black/50 dark:text-white/30">
							{isZh
								? `搜索到包含 "${cmdKValue}" 的 ${cmdKList.length} 条结果`
								: `Found ${cmdKList.length} results containing "${cmdKValue}"`}
						</div>
					{/if}
				{/if}
				{#each cmdKList as item, index}
					<div class="flex items-center">
						<div
							class="w-lg mr-2 transition-all {index === currentIndex
								? 'text-primary dark:text-dark text-xl font-bold'
								: 'text-lg text-black dark:text-white'}"
						>
							{isZh ? item?.title : item?.title_en}
						</div>
						<div class="w-full dark:border-white/10">
							<button
								class="my-1 flex w-full cursor-pointer justify-between rounded-sm border py-1 pl-2 {index === currentIndex &&
								currentTab === 0
									? 'border-primary dark:border-dark text-primary dark:text-dark'
									: 'text-balck border-transparent dark:text-white'}"
								class:animate-shake={isDemoShake && index === 0}
								onclick={() => clickCmdKFun(item, 0)}
							>
								<div>{isZh ? '示例' : 'Demo'}</div>
								<div>
									<svg
										class={index === currentIndex && currentTab === 0 ? 'fill-primary dark:fill-dark' : 'fill-gray-500'}
										xmlns="http://www.w3.org/2000/svg"
										viewBox="0 0 24 24"
										width="24"
										height="24"
									>
										<path fill="none" d="M0 0h24v24H0z" />
										<path d="M12.172 12L9.343 9.172l1.414-1.415L15 12l-4.243 4.243-1.414-1.415z" />
									</svg>
								</div>
							</button>
							<button
								class="my-1 flex w-full cursor-pointer justify-between rounded-sm border py-1 pl-2 {index === currentIndex &&
								currentTab === 1
									? 'border-primary dark:border-dark text-primary dark:text-dark'
									: 'text-balck border-transparent dark:text-white'}"
								onclick={() => clickCmdKFun(item, 1)}
							>
								<div>API</div>
								<div>
									<svg
										class={index === currentIndex && currentTab === 1 ? 'fill-primary dark:fill-dark' : 'fill-gray-500'}
										xmlns="http://www.w3.org/2000/svg"
										viewBox="0 0 24 24"
										width="24"
										height="24"
									>
										<path fill="none" d="M0 0h24v24H0z" />
										<path d="M12.172 12L9.343 9.172l1.414-1.415L15 12l-4.243 4.243-1.414-1.415z" />
									</svg>
								</div>
							</button>
							<button
								class="my-1 flex w-full cursor-pointer justify-between rounded-sm border py-1 pl-2 {index === currentIndex &&
								currentTab === 2
									? 'border-primary dark:border-dark text-primary dark:text-dark'
									: 'text-balck border-transparent dark:text-white'}"
								class:animate-shake={isGuideShake && index === cmdKList.length - 1}
								onclick={() => clickCmdKFun(item, 2)}
							>
								<div>{isZh ? '指南' : 'Guide'}</div>
								<div>
									<svg
										class={index === currentIndex && currentTab === 2 ? 'fill-primary dark:fill-dark' : 'fill-gray-500'}
										xmlns="http://www.w3.org/2000/svg"
										viewBox="0 0 24 24"
										width="24"
										height="24"
									>
										<path fill="none" d="M0 0h24v24H0z" />
										<path d="M12.172 12L9.343 9.172l1.414-1.415L15 12l-4.243 4.243-1.414-1.415z" />
									</svg>
								</div>
							</button>
						</div>
					</div>
				{/each}
			</div>
			<div class="flex gap-4 border-t border-black/10 px-4 py-2 text-xs opacity-60 dark:border-white/10">
				<div class="flex gap-1">
					<div class="rounded-xs flex size-4 flex-col items-center justify-center bg-black/10 p-0.5 dark:bg-white/30">
						<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="fill-black dark:fill-white">
							<path
								d="M19.0003 13.9999L19.0004 5.00003L17.0004 5L17.0003 11.9999L6.82845 12L10.7782 8.05027L9.36396 6.63606L3 13L9.36396 19.364L10.7782 17.9498L6.8284 14L19.0003 13.9999Z"
							/>
						</svg>
					</div>
					{isZh ? '选择' : 'Select'}
				</div>
				<div class="flex gap-1">
					<div class="rounded-xs flex size-4 flex-col items-center justify-center bg-black/10 p-0.5 dark:bg-white/30">
						<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="fill-black dark:fill-white">
							<path
								d="M12.9999 16.1716L18.3638 10.8076L19.778 12.2218L11.9999 20L4.22168 12.2218L5.63589 10.8076L10.9999 16.1716V4H12.9999V16.1716Z"
							/>
						</svg>
					</div>
					{isZh ? '向下' : 'Down'}
				</div>
				<div class="flex gap-1">
					<div class="rounded-xs flex size-4 flex-col items-center justify-center bg-black/10 p-0.5 dark:bg-white/30">
						<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="fill-black dark:fill-white">
							<path
								d="M12.9999 7.82843V20H10.9999V7.82843L5.63589 13.1924L4.22168 11.7782L11.9999 4L19.778 11.7782L18.3638 13.1924L12.9999 7.82843Z"
							/>
						</svg>
					</div>
					{isZh ? '向上' : 'Up'}
				</div>
				<div class="flex gap-1">
					<div class="rounded-xs bg-black/10 px-1 text-xs dark:bg-white/30">Esc</div>
					{isZh ? '关闭' : 'Close'}
				</div>
			</div>
		</div>
	</div>
{/if}



================================================
FILE: docs/site/src/lib/colorCard/ColorCard.svelte
================================================
<script lang="ts">
	let { colorList = [] } = $props();
</script>

{#each colorList as color, index}
	<div
		class="flex w-full flex-1 justify-between self-center px-4 transition hover:scale-105 hover:rounded-sm md:py-0 {index > 5
			? 'text-white'
			: 'text-black'}"
		style="background-color: {color.color};"
	>
		<div class="flex flex-col justify-center text-sm">{color.key}</div>
		<div class="mt-2 flex flex-col justify-center py-1 text-right">
			<div>{color.color || ''}</div>
		</div>
	</div>
{/each}



================================================
FILE: docs/site/src/lib/fund/Fund.svelte
================================================
<script lang="ts">
	import { fly, fade } from 'svelte/transition';
	import { isShowFundStore } from '../../store';

	const isZh = localStorage.getItem('lang') === 'zh_CN';

	let showWeChatPay = $state(false);
	let showAlipayPay = $state(false);

	// 判断是否是桌面设备
	const isDeskDeviceFunc = () => {
		return window.innerWidth >= 768;
	};
	const isDeskDevice = isDeskDeviceFunc();
</script>

<!-- svelte-ignore a11y_click_events_have_key_events -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
	transition:fade
	class="fixed left-0 top-0 flex h-screen w-screen flex-col justify-center bg-black/20 backdrop-blur"
	style="z-index: 1000"
	onclick={() => {
		isShowFundStore.set(false);
	}}
>
	<div
		in:fly={{ y: -400 }}
		class="mx-auto w-full rounded-xl bg-white p-4 shadow-lg md:w-[800px] md:p-8 dark:bg-gray-950"
		onclick={(e: Event) => e.stopPropagation()}
	>
		<div class="flex justify-between">
			<div class="text-xl font-bold">{isZh ? '支持' : 'Support'}</div>
			<div class="h-8">
				<a href="https://github.com/any-tdf/stdf" target="_blank">
					<img src="https://img.shields.io/github/stars/any-tdf/stdf?logo=github&label=stars&color=000" alt="GitHub" />
				</a>
			</div>
		</div>
		{#if isDeskDevice || (!showWeChatPay && !showAlipayPay)}
			<div class="mt-2 text-xs text-gray-500 md:mt-8">
				<p>
					{isZh
						? 'STDF 是一个免费、开源、简单易用且精心打造的组件库。我们在组件设计开发、工具配套、文档建设等方面倾注了大量心血。如果 STDF 为您带来了便利，希望您能给个 star 或打赏以示支持，感谢您的厚爱！'
						: 'STDF is a free, open-source, easy-to-use, and carefully crafted component library. We have devoted tremendous effort to component design, development tools, and documentation. If STDF has helped you, please consider showing your support with a star or donation. Thank you for your love!'}
				</p>
				<p class="text-md mt-2 font-bold">
					{isZh ? '无论如何，STDF 都将怀着热爱继续前行！' : 'No matter what, STDF will keep moving forward with love!'}
				</p>
			</div>
		{/if}
		<div class="grid {showWeChatPay || showAlipayPay ? 'grid-cols-1' : 'grid-cols-2'}  mt-4 gap-2 text-center md:mt-10 md:grid-cols-4">
			<!-- coffee -->
			{#if isDeskDevice || (!showWeChatPay && !showAlipayPay)}
				<div
					class="group flex w-full flex-col justify-center rounded-lg border border-black/10 py-1 md:relative md:w-40 md:py-12 dark:border-white/10"
				>
					<div class="mx-auto h-8 w-6">
						<img class="h-full w-full object-cover" src="/assets/fund/coffee.svg" alt="coffee" />
					</div>
					<a class="mx-2 block md:hidden" href="https://www.buymeacoffee.com/dufu1991" target="_blank">
						<div class="text-center font-bold after:content-['_↗']">Buy Me a Coffee</div>
						<div class="mt-1 text-xs text-gray-500">
							{isZh ? '推荐非中国地区使用' : 'Recommended for Non-China Regions'}
						</div>
					</a>
					<a
						class="absolute inset-1 hidden h-[95%] w-[95%] bg-white px-1 py-12 opacity-0 transition-all duration-500 group-hover:opacity-95 md:block dark:bg-gray-950"
						href="https://www.buymeacoffee.com/dufu1991"
						target="_blank"
					>
						<div class="text-center font-bold after:content-['_↗']">Buy Me a Coffee</div>
						<div class="mt-1 text-xs text-gray-500">
							{isZh ? '推荐非中国地区使用' : 'Recommended for Non-China Regions'}
						</div>
					</a>
				</div>
			{/if}
			<!-- paypal -->
			{#if isDeskDevice || (!showWeChatPay && !showAlipayPay)}
				<div
					class="group flex w-full flex-col justify-center rounded-lg border border-black/10 py-1 md:relative md:w-40 md:py-12 dark:border-white/10"
				>
					<div class="mx-auto h-8 w-8">
						<img class="h-full w-full object-cover" src="/assets/fund/paypal.svg" alt="paypal" />
					</div>
					<a class="mx-2 block md:hidden" href="https://paypal.me/dufu1991" target="_blank">
						<div class="text-center font-bold after:content-['_↗']">PayPal</div>
						<div class="mt-1 text-xs text-gray-500">
							{isZh ? '推荐非中国地区使用' : 'Recommended for Non-China Regions'}
						</div>
					</a>
					<a
						class="absolute inset-1 hidden h-[95%] w-[95%] bg-white px-1 py-12 opacity-0 transition-all duration-500 group-hover:opacity-95 md:block dark:bg-gray-950"
						href="https://paypal.me/dufu1991"
						target="_blank"
					>
						<div class="text-center font-bold after:content-['_↗']">PayPal</div>
						<div class="mt-1 text-xs text-gray-500">
							{isZh ? '推荐非中国地区使用' : 'Recommended for Non-China Regions'}
						</div>
					</a>
				</div>
			{/if}
			<!-- wechat -->
			{#if isDeskDevice || !showAlipayPay}
				<div
					class="group flex w-full flex-col justify-center rounded-lg border border-black/10 py-1 md:relative md:w-40 md:py-12 dark:border-white/10"
				>
					<div class="mx-auto h-8 w-10" class:hidden={showWeChatPay}>
						<img class="h-full w-full object-cover" src="/assets/fund/wechat_pay.svg" alt="wechat" />
					</div>
					<div
						class="mx-2 block md:hidden"
						onclick={() => {
							showWeChatPay = !showWeChatPay;
						}}
					>
						{#if showWeChatPay}
							<div class="mt-1">
								<img class="mx-auto w-3/5 object-cover" src="/assets/fund/wp_code.png" alt="wechat" />
							</div>
							<div class="mt-1 text-xs text-gray-500">
								{isZh ? '微信扫一扫' : 'WeChat Scan'}
							</div>
						{:else}
							<div class="text-center font-bold after:content-['_↗']">
								{isZh ? '微信赞赏' : 'WeChat Reward'}
							</div>
							<div class="mt-1 text-xs text-gray-500">
								{isZh ? '推荐中国地区使用' : 'Recommended for China Regions'}
							</div>
						{/if}
					</div>
					<button
						onclick={() => {
							showWeChatPay = !showWeChatPay;
						}}
						class="absolute inset-1 hidden h-[95%] w-[95%] cursor-pointer bg-white px-1 opacity-0 transition-all duration-500 group-hover:opacity-95 md:block dark:bg-gray-950"
						class:opacity-95={showWeChatPay}
					>
						{#if showWeChatPay}
							<div class="mt-0.5">
								<img class="mx-auto w-[70%] object-cover" src="/assets/fund/wp_code.png" alt="wechat" />
							</div>
							<div class="mt-0.5 text-xs text-gray-500">
								{isZh ? '微信扫一扫' : 'WeChat Scan'}
							</div>
						{:else}
							<div class="mt-12 text-center font-bold after:content-['_↗']">
								{isZh ? '微信赞赏' : 'WeChat Reward'}
							</div>
							<div class="mt-1 text-xs text-gray-500">
								{isZh ? '推荐中国地区使用' : 'Recommended for China Regions'}
							</div>
						{/if}
					</button>
				</div>
			{/if}
			<!-- alipay -->
			{#if isDeskDevice || !showWeChatPay}
				<div
					class="group mx-auto flex w-full flex-col justify-center rounded-lg border border-black/10 py-1 md:relative md:w-40 md:py-12 dark:border-white/10"
				>
					<div class="mx-auto h-8 w-8" class:hidden={showAlipayPay}>
						<img class="h-full w-full object-cover" src="/assets/fund/alipay.svg" alt="alipay" />
					</div>
					<div
						class="mx-2 block md:hidden"
						onclick={() => {
							showAlipayPay = !showAlipayPay;
						}}
					>
						{#if showAlipayPay}
							<div class="m-1">
								<img class="mx-auto w-3/5 object-cover" src="/assets/fund/ap_code.png" alt="alipay" />
							</div>
							<div class="mt-1 text-xs text-gray-500">
								{isZh ? '支付宝扫一扫' : 'Alipay Scan'}
							</div>
						{:else}
							<div class="text-center font-bold after:content-['_↗']">
								{isZh ? '支付宝收款' : 'Alipay Payment'}
							</div>
							<div class="mt-1 text-xs text-gray-500">
								{isZh ? '推荐中国地区使用' : 'Recommended for China Regions'}
							</div>
						{/if}
					</div>
					<button
						onclick={() => {
							showAlipayPay = !showAlipayPay;
						}}
						class="absolute inset-1 hidden h-[95%] w-[95%] cursor-pointer bg-white px-1 opacity-0 transition-all duration-500 group-hover:opacity-95 md:block dark:bg-gray-950"
						class:opacity-95={showAlipayPay}
					>
						{#if showAlipayPay}
							<div class="mt-0.5">
								<img class="mx-auto w-[70%] object-cover" src="/assets/fund/ap_code.png" alt="wechat" />
							</div>
							<div class="mt-0.5 text-xs text-gray-500">
								{isZh ? '支付宝扫一扫' : 'Alipay Scan'}
							</div>
						{:else}
							<div class="mt-12 text-center font-bold after:content-['_↗']">
								{isZh ? '支付宝收款' : 'Alipay Payment'}
							</div>
							<div class="mt-1 text-xs text-gray-500">
								{isZh ? '推荐中国地区使用' : 'Recommended for China Regions'}
							</div>
						{/if}
					</button>
				</div>
			{/if}
		</div>
		<div class="mt-4 text-xs text-gray-500 md:mt-8">
			{isZh
				? '欢迎在捐赠留言中附上您的 GitHub 或其他社交账号链接，STDF 将在项目仓库和官网中展示感谢！'
				: 'Feel free to include your GitHub or other social media links in the donation message. STDF will gratefully acknowledge your support on our repository and website!'}
		</div>
	</div>
</div>



================================================
FILE: docs/site/src/lib/header/Header.svelte
================================================
<script lang="ts">
	import { slide, fly } from 'svelte/transition';
	import ModeSwitch from '../modeSwitch/ModeSwitch.svelte';
	import ThemeSwitch from '../themeSwitch/ThemeSwitch.svelte';
	import { isShowNavStore, isShowFundStore, showThemeSwitchStore } from '../../store';
	import { page } from '$app/stores';
	import stdfPackage from '../../../../../packages/stdf/package.json';

	let { showLeftNav = false, showBottonLine = false, onclickCmdK } = $props();

	let currentRoute = $state('/guide');
	$effect(() => {
		currentRoute = $page.url.pathname;
	});
	let showNav = $state(false); //是否显示导航
	const toggleNavFun = () => {
		isShowNavStore.set(!$isShowNavStore);
	};
	//判断是 Mac 系统
	const isMac = navigator.userAgent.toUpperCase().indexOf('MAC') >= 0;
	const cmdkey = isMac ? '⌘' : 'Ctrl';
	const isZh = localStorage.getItem('lang') === 'zh_CN';

	// const dispatch = createEventDispatcher(); //创建事件派发器
	const clickCmdKFun = () => {
		onclickCmdK?.();
	};
	// 切换支持
	const toggleFundFunc = () => {
		isShowFundStore.set(true);
	};
	// 显示主题切换
	const showThemeFunc = () => {
		showThemeSwitchStore.set(!$showThemeSwitchStore);
	};
	let ThemeSwitchDom: HTMLButtonElement | null = $state(null);
	// 监听 window 点击事件，如果点击的不是 ThemeSwitchDom，则隐藏主题切换
	window.addEventListener('click', (e: MouseEvent) => {
		if (ThemeSwitchDom && !ThemeSwitchDom.contains(e.target as Node)) {
			showThemeSwitchStore.set(false);
		}
	});

	let showVersion = $state(false);
	let versionBtnRef: HTMLButtonElement | null = $state(null);

	const switchLangFunc = () => {
		const isHaveParams = window.location.href.includes('?');
		// 如果有参数，则增加 &lang=xxx，否则增加 ?lang=xxx
		const newUrl = isHaveParams
			? window.location.href + '&lang=' + (isZh ? 'en_US' : 'zh_CN')
			: window.location.href + '?lang=' + (isZh ? 'en_US' : 'zh_CN');
		window.location.href = newUrl;
	};
</script>

<svelte:document
	onclick={(e) => {
		if (versionBtnRef && !versionBtnRef.contains(e.target as Node)) {
			showVersion = false;
		}
	}}
/>

<div class="sticky top-0 z-[100] flex h-14 items-center justify-between border-black/5 backdrop-blur-sm dark:border-white/10">
	{#if showLeftNav}
		<button class="cursor-pointer p-4 md:hidden" onclick={toggleNavFun}>
			{#if !$isShowNavStore}
				<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
					<path d="M21.0001 4.50004L7.50007 4.5L7.50006 6L21.0001 6.00004V4.50004Z" fill="currentColor" />
					<path d="M5.25007 4.5L3.00098 4.5L3.00098 6L5.25007 6V4.5Z" fill="currentColor" />
					<path d="M7.50007 11.2501L21.0001 11.2501V12.7501L7.50006 12.7501L7.50007 11.2501Z" fill="currentColor" />
					<path d="M3.00098 11.2501H5.25007V12.7501H3.00098L3.00098 11.2501Z" fill="currentColor" />
					<path d="M7.50007 18L21.0001 18V19.5L7.50006 19.5L7.50007 18Z" fill="currentColor" />
					<path d="M3.00098 18H5.25007V19.5H3.00098L3.00098 18Z" fill="currentColor" />
				</svg>
			{:else}
				<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
					<path
						fill="currentColor"
						d="M10.4143 4.58594L10.4142 11.0003L16.0003 11.0004L16.0003 13.0004L10.4142 13.0003L10.4141 19.4144L3 12.0002L10.4143 4.58594ZM18.0002 19.0002V5.00018H20.0002V19.0002H18.0002Z"
					/>
				</svg>
			{/if}
		</button>
	{/if}

	<div class="flex items-end">
		<a href="/" class="flex items-center justify-between py-2 md:pl-6" aria-label={isZh ? '首页' : 'Home'}>
			<div class="fill-primary flex h-8 w-16 flex-col items-center justify-center">
				<svg viewBox="0 0 90 80">
					<path
						class="fill-primary dark:fill-dark"
						d="M0 0H20H40H50C64.8056 0 77.7325 8.04398 84.6487 20H50H40V22.6757V30H50C55.5229 30 60 34.4771 60 40C60 45.5229 55.5229 50 50 50H40V57.3243V78.7398V80H20V66.4583V20H15.3513H0V0ZM50 80C72.0914 80 90 62.0914 90 40C90 36.547 89.5625 33.1962 88.7398 30H67.3244C69.0261 32.9417 70 36.3571 70 40C70 51.0457 61.0457 60 50 60V80Z"
					/>
					<path class="fill-dark dark:fill-primary" d="M20 30V0L0 50H20V80L40 30H20Z" />
				</svg>
			</div>
		</a>
		<!-- 下拉选项，选择版本 -->
		{#if $page.url.pathname === '' || $page.url.pathname === '/'}
			<div class="relative bottom-1">
				<button
					bind:this={versionBtnRef}
					class="flex cursor-pointer py-0.5 pl-2 pr-4 text-xs text-gray-500"
					onclick={() => (showVersion = !showVersion)}
				>
					{stdfPackage.version}
					<span class="absolute -bottom-px left-8 w-5 text-gray-500">
						<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
							<path d="M12 15.0006L7.75732 10.758L9.17154 9.34375L12 12.1722L14.8284 9.34375L16.2426 10.758L12 15.0006Z"></path>
						</svg>
					</span>
				</button>
				{#if showVersion}
					<div
						transition:fly={{ duration: 300, y: -20, opacity: 0 }}
						class="absolute left-0 top-10 w-28 rounded-xl bg-white p-4 text-xs shadow-md dark:bg-black dark:shadow-white/10"
					>
						<div class="text-primary dark:text-dark relative flex py-0.5">
							<span class="mr-1">
								<svg xmlns="http://www.w3.org/2000/svg" class="w-4" viewBox="0 0 24 24">
									<path
										fill="currentColor"
										d="M3 20q-.825 0-1.412-.587T1 18V6q0-.825.588-1.412T3 4h18q.825 0 1.413.588T23 6v12q0 .825-.587 1.413T21 20zm1.75-8.5l2.375 3.25q.075.125.2.188T7.6 15h.3q.25 0 .425-.175T8.5 14.4V9.625q0-.275-.175-.45T7.875 9t-.45.175t-.175.45V12.5L4.925 9.25q-.1-.125-.225-.187T4.425 9h-.3q-.275 0-.45.175t-.175.45v4.75q0 .275.175.45t.45.175t.45-.175t.175-.45zM10 15h2.875q.275 0 .45-.175t.175-.45t-.175-.45t-.45-.175H11v-1.1h1.875q.275 0 .45-.175t.175-.45t-.175-.45t-.45-.175H11v-1.15h1.875q.275 0 .45-.175t.175-.45t-.175-.45t-.45-.175H10q-.2 0-.35.15t-.15.35v5q0 .2.15.35T10 15m5.5 0h4q.425 0 .713-.288T20.5 14V9.625q0-.275-.175-.45T19.875 9t-.45.175t-.175.45V13.5h-1.1v-2.875q0-.275-.175-.45t-.45-.175t-.45.175t-.175.45V13.5h-1.15V9.625q0-.275-.175-.45T15.125 9t-.45.175t-.175.45V14q0 .425.288.713T15.5 15"
									/>
								</svg>
							</span>
							{stdfPackage.version}
							<span class="absolute bottom-1 left-12 w-3">
								<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
									<path d="M9.9997 15.1709L19.1921 5.97852L20.6063 7.39273L9.9997 17.9993L3.63574 11.6354L5.04996 10.2212L9.9997 15.1709Z"
									></path>
								</svg>
							</span>
						</div>
						<div class="my-2 h-px bg-black/5 dark:bg-white/20"></div>
						<a href="/guide/changelog" class="hover:underline">
							<span class="inline-block size-3 translate-y-0.5">
								<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
									<path
										d="M12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12H4C4 16.4183 7.58172 20 12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C9.25022 4 6.82447 5.38734 5.38451 7.50024L8 7.5V9.5H2V3.5H4L3.99989 5.99918C5.82434 3.57075 8.72873 2 12 2ZM13 7L12.9998 11.585L16.2426 14.8284L14.8284 16.2426L10.9998 12.413L11 7H13Z"
									>
									</path>
								</svg>
							</span>
							{isZh ? '更新日志' : 'Changelog'}
						</a>
						<div class="my-2 h-px bg-black/5 dark:bg-white/20"></div>
						<a href="https://0.stdf.design" target="_blank" class="hover:underline">Version 0.x </a>
					</div>
				{/if}
			</div>
		{/if}
	</div>
	<div>
		<div class="cursor-pointer p-4 md:hidden">
			<button onclick={() => (showNav = !showNav)}>
				{#if !showNav}
					<svg width="24" height="24" fill="none" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
						<path
							d="M12 6v.01M12 12v.01M12 18v.01M12 7a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm0 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm0 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"
							stroke="currentColor"
							stroke-width="1.5"
							stroke-linecap="round"
							stroke-linejoin="round"
						/>
					</svg>
				{:else}
					<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
						<path
							fill="currentColor"
							d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM12 10.5858L14.8284 7.75736L16.2426 9.17157L13.4142 12L16.2426 14.8284L14.8284 16.2426L12 13.4142L9.17157 16.2426L7.75736 14.8284L10.5858 12L7.75736 9.17157L9.17157 7.75736L12 10.5858Z"
						/>
					</svg>
				{/if}
			</button>
			{#if showNav}
				<!-- 移动端 -->
				<div
					transition:slide={{ duration: 300, axis: 'y' }}
					class="absolute right-2 top-14 flex flex-col space-y-3 rounded-sm border border-black/10 bg-white p-1 pt-4 text-center text-sm font-bold shadow-lg backdrop-blur-sm dark:border-white/20 dark:bg-gray-950 dark:shadow-white/20"
				>
					<!-- AI 问答 -->
					<a
						href="https://deepwiki.com/any-tdf/stdf"
						class="px-4 py-1 text-center"
						target="_blank"
						title={isZh ? '到 DeepWiki 提问' : 'Ask questions on DeepWiki'}
						aria-label={isZh ? '到 DeepWiki 提问' : 'Ask questions on DeepWiki'}
					>
						<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="inline-block" fill="currentColor">
							<path
								d="M20.7134 8.12811L20.4668 8.69379C20.2864 9.10792 19.7136 9.10792 19.5331 8.69379L19.2866 8.12811C18.8471 7.11947 18.0555 6.31641 17.0677 5.87708L16.308 5.53922C15.8973 5.35653 15.8973 4.75881 16.308 4.57612L17.0252 4.25714C18.0384 3.80651 18.8442 2.97373 19.2761 1.93083L19.5293 1.31953C19.7058 0.893489 20.2942 0.893489 20.4706 1.31953L20.7238 1.93083C21.1558 2.97373 21.9616 3.80651 22.9748 4.25714L23.6919 4.57612C24.1027 4.75881 24.1027 5.35653 23.6919 5.53922L22.9323 5.87708C21.9445 6.31641 21.1529 7.11947 20.7134 8.12811ZM10 3H14V5H10C6.68629 5 4 7.68629 4 11C4 14.61 6.46208 16.9656 12 19.4798V17H14C17.3137 17 20 14.3137 20 11H22C22 15.4183 18.4183 19 14 19V22.5C9 20.5 2 17.5 2 11C2 6.58172 5.58172 3 10 3Z"
							>
							</path>
						</svg>
					</a>
					<a
						href={currentRoute.includes('/guide') ? 'javascript:void(0)' : '/guide'}
						class="px-4 py-1 text-center {currentRoute.includes('/guide') ? ' text-primary dark:text-dark' : ''}"
					>
						{isZh ? '指南' : 'Guide'}
					</a>
					<a
						href={currentRoute.includes('/components') ? 'javascript:void(0)' : '/components?nav=button&tab=0'}
						class="px-4 py-1 text-center {currentRoute.includes('/components') ? ' text-primary dark:text-dark' : ''}"
					>
						{isZh ? '组件' : 'Components'}
					</a>
					<button class="relative px-4 py-1 text-center" onclick={showThemeFunc} bind:this={ThemeSwitchDom}>
						{isZh ? '主题' : 'Theme'}
						{#if $showThemeSwitchStore}
							<div
								transition:slide={{ duration: 300, axis: 'x' }}
								class="absolute top-0 h-80 overflow-y-auto rounded-lg bg-white p-3 shadow-lg dark:bg-black/95 dark:shadow-white/40"
								style="right:{isZh ? '66px' : '128px'}"
							>
								<ModeSwitch useViewTransition={false} />
								<ThemeSwitch vertical />
							</div>
						{/if}
					</button>
					<button class="px-4 py-1 text-center" onclick={toggleFundFunc}>
						{isZh ? '支持' : 'Support'}
					</button>

					<!-- 语言切换 -->
					<button
						onclick={switchLangFunc}
						aria-label={isZh ? '跳转英文站点' : 'Jump to Chinese Site'}
						class="cursor-pointer px-4 py-1 text-center"
					>
						<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" class="inline-block">
							<path fill="none" d="M0 0h24v24H0z" />
							<path
								fill="currentColor"
								d="M5 15v2a2 2 0 0 0 1.85 1.995L7 19h3v2H7a4 4 0 0 1-4-4v-2h2zm13-5l4.4 11h-2.155l-1.201-3h-4.09l-1.199 3h-2.154L16 10h2zm-1 2.885L15.753 16h2.492L17 12.885zM8 2v2h4v7H8v3H6v-3H2V4h4V2h2zm9 1a4 4 0 0 1 4 4v2h-2V7a2 2 0 0 0-2-2h-3V3h3zM6 6H4v3h2V6zm4 0H8v3h2V6z"
							/>
						</svg>
					</button>
					<!-- GitHub -->
					<a
						href="https://github.com/any-tdf/stdf"
						class="px-4 py-1 text-center"
						target="_blank"
						aria-label={isZh ? '跳转至 GitHub' : 'Jump to GitHub'}
					>
						<svg width="20" height="20" viewBox="0 0 24 24" class="inline-block" xmlns="http://www.w3.org/2000/svg">
							<path
								fill-rule="evenodd"
								clip-rule="evenodd"
								d="M12 2.23999C6.475 2.23999 2 6.71499 2 12.24C2 16.665 4.8625 20.4025 8.8375 21.7275C9.3375 21.815 9.525 21.515 9.525 21.2525C9.525 21.015 9.5125 20.2275 9.5125 19.39C7 19.8525 6.35 18.7775 6.15 18.215C6.0375 17.9275 5.55 17.04 5.125 16.8025C4.775 16.615 4.275 16.1525 5.1125 16.14C5.9 16.1275 6.4625 16.865 6.65 17.165C7.55 18.6775 8.9875 18.2525 9.5625 17.99C9.65 17.34 9.9125 16.9025 10.2 16.6525C7.975 16.4025 5.65 15.54 5.65 11.715C5.65 10.6275 6.0375 9.72749 6.675 9.02749C6.575 8.77749 6.225 7.75249 6.775 6.37749C6.775 6.37749 7.6125 6.11499 9.525 7.40249C10.325 7.17749 11.175 7.06499 12.025 7.06499C12.875 7.06499 13.725 7.17749 14.525 7.40249C16.4375 6.10249 17.275 6.37749 17.275 6.37749C17.825 7.75249 17.475 8.77749 17.375 9.02749C18.0125 9.72749 18.4 10.615 18.4 11.715C18.4 15.5525 16.0625 16.4025 13.8375 16.6525C14.2 16.965 14.5125 17.565 14.5125 18.5025C14.5125 19.84 14.5 20.915 14.5 21.2525C14.5 21.515 14.6875 21.8275 15.1875 21.7275C17.1727 21.0573 18.8977 19.7815 20.1198 18.0795C21.3419 16.3776 21.9995 14.3352 22 12.24C22 6.71499 17.525 2.23999 12 2.23999Z"
								fill="currentColor"
							/>
						</svg>
					</a>
				</div>
			{/if}
		</div>
		<!--PC 端-->
		<div class="hidden items-center space-x-2 px-6 font-bold md:flex">
			<!-- AI 问答 -->
			<a
				href="https://deepwiki.com/any-tdf/stdf"
				class="inline-block px-2 py-1"
				target="_blank"
				title={isZh ? '到 DeepWiki 提问' : 'Ask questions on DeepWiki'}
				aria-label={isZh ? '到 DeepWiki 提问' : 'Ask questions on DeepWiki'}
			>
				<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"
					><path
						d="M20.7134 8.12811L20.4668 8.69379C20.2864 9.10792 19.7136 9.10792 19.5331 8.69379L19.2866 8.12811C18.8471 7.11947 18.0555 6.31641 17.0677 5.87708L16.308 5.53922C15.8973 5.35653 15.8973 4.75881 16.308 4.57612L17.0252 4.25714C18.0384 3.80651 18.8442 2.97373 19.2761 1.93083L19.5293 1.31953C19.7058 0.893489 20.2942 0.893489 20.4706 1.31953L20.7238 1.93083C21.1558 2.97373 21.9616 3.80651 22.9748 4.25714L23.6919 4.57612C24.1027 4.75881 24.1027 5.35653 23.6919 5.53922L22.9323 5.87708C21.9445 6.31641 21.1529 7.11947 20.7134 8.12811ZM10 3H14V5H10C6.68629 5 4 7.68629 4 11C4 14.61 6.46208 16.9656 12 19.4798V17H14C17.3137 17 20 14.3137 20 11H22C22 15.4183 18.4183 19 14 19V22.5C9 20.5 2 17.5 2 11C2 6.58172 5.58172 3 10 3Z"
					></path></svg
				>
			</a>
			<button
				class="flex cursor-pointer rounded-sm border border-black/10 p-0.5 text-xs font-normal text-black/40 transition-all hover:border-black/20 dark:border-white/10 dark:text-white/40 dark:hover:border-white/20"
				onclick={clickCmdKFun}
			>
				<div class="mr-1 flex flex-col justify-center">
					<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" style="fill: currentColor;">
						<path fill="none" d="M0 0h24v24H0z" />
						<path
							d="M11 2c4.968 0 9 4.032 9 9s-4.032 9-9 9-9-4.032-9-9 4.032-9 9-9zm0 16c3.867 0 7-3.133 7-7 0-3.868-3.133-7-7-7-3.868 0-7 3.132-7 7 0 3.867 3.132 7 7 7zm8.485.071l2.829 2.828-1.415 1.415-2.828-2.829 1.414-1.414z"
						/>
					</svg>
				</div>
				<div class="mr-2 flex flex-col justify-center">
					{isZh ? '搜索...' : 'Search...'}
				</div>
				<div class="rounded-sm bg-black/5 px-1 dark:bg-white/5">{cmdkey} K</div>
			</button>
			<a
				href={currentRoute.includes('/guide') ? 'javascript:void(0)' : '/guide'}
				class="px-2 py-1{currentRoute.includes('/guide') ? ' text-primary dark:text-dark' : ''}"
			>
				{isZh ? '指南' : 'Guide'}
			</a>
			<a
				href={currentRoute.includes('/components') ? 'javascript:void(0)' : '/components?nav=button&tab=0'}
				class="inline-block px-2 py-1 text-center{currentRoute.includes('/components')
					? ' text-primary dark:text-dark pointer-events-none'
					: ''}"
			>
				{isZh ? '组件' : 'Components'}
			</a>
			<!-- svelte-ignore a11y_mouse_events_have_key_events -->
			<button
				class="relative px-2 py-1 text-center"
				onmouseover={() => showThemeSwitchStore.set(true)}
				onmouseout={() => showThemeSwitchStore.set(false)}
				bind:this={ThemeSwitchDom}
			>
				{isZh ? '主题' : 'Theme'}
				{#if $showThemeSwitchStore}
					<div transition:slide={{ duration: 300, axis: 'y' }} class="absolute left-1/2 top-8 -translate-x-1/2 pt-2">
						<div class="rounded-md bg-white px-3 pb-1 pt-2 shadow-lg dark:bg-black/95 dark:shadow-white/10">
							<ModeSwitch useViewTransition={false} />
							<ThemeSwitch vertical />
						</div>
					</div>
				{/if}
			</button>
			<button class="cursor-pointer px-2 py-1 text-center" onclick={toggleFundFunc}>
				{isZh ? '支持' : 'Support'}
			</button>
			<!-- 语言切换 -->
			<button
				onclick={switchLangFunc}
				class="cursor-pointer px-2 py-1 text-center"
				aria-label={isZh ? '跳转英文站点' : 'Jump to Chinese Site'}
			>
				<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" class="inline-block">
					<path fill="none" d="M0 0h24v24H0z" />
					<path
						fill="currentColor"
						d="M5 15v2a2 2 0 0 0 1.85 1.995L7 19h3v2H7a4 4 0 0 1-4-4v-2h2zm13-5l4.4 11h-2.155l-1.201-3h-4.09l-1.199 3h-2.154L16 10h2zm-1 2.885L15.753 16h2.492L17 12.885zM8 2v2h4v7H8v3H6v-3H2V4h4V2h2zm9 1a4 4 0 0 1 4 4v2h-2V7a2 2 0 0 0-2-2h-3V3h3zM6 6H4v3h2V6zm4 0H8v3h2V6z"
					/>
				</svg>
			</button>
			<!-- GitHub -->
			<a
				href="https://github.com/any-tdf/stdf"
				class="inline-block px-2 py-1"
				target="_blank"
				aria-label={isZh ? '跳转至 GitHub' : 'Jump to GitHub'}
			>
				<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" class="inline-block">
					<path
						fill-rule="evenodd"
						clip-rule="evenodd"
						d="M12 2.23999C6.475 2.23999 2 6.71499 2 12.24C2 16.665 4.8625 20.4025 8.8375 21.7275C9.3375 21.815 9.525 21.515 9.525 21.2525C9.525 21.015 9.5125 20.2275 9.5125 19.39C7 19.8525 6.35 18.7775 6.15 18.215C6.0375 17.9275 5.55 17.04 5.125 16.8025C4.775 16.615 4.275 16.1525 5.1125 16.14C5.9 16.1275 6.4625 16.865 6.65 17.165C7.55 18.6775 8.9875 18.2525 9.5625 17.99C9.65 17.34 9.9125 16.9025 10.2 16.6525C7.975 16.4025 5.65 15.54 5.65 11.715C5.65 10.6275 6.0375 9.72749 6.675 9.02749C6.575 8.77749 6.225 7.75249 6.775 6.37749C6.775 6.37749 7.6125 6.11499 9.525 7.40249C10.325 7.17749 11.175 7.06499 12.025 7.06499C12.875 7.06499 13.725 7.17749 14.525 7.40249C16.4375 6.10249 17.275 6.37749 17.275 6.37749C17.825 7.75249 17.475 8.77749 17.375 9.02749C18.0125 9.72749 18.4 10.615 18.4 11.715C18.4 15.5525 16.0625 16.4025 13.8375 16.6525C14.2 16.965 14.5125 17.565 14.5125 18.5025C14.5125 19.84 14.5 20.915 14.5 21.2525C14.5 21.515 14.6875 21.8275 15.1875 21.7275C17.1727 21.0573 18.8977 19.7815 20.1198 18.0795C21.3419 16.3776 21.9995 14.3352 22 12.24C22 6.71499 17.525 2.23999 12 2.23999Z"
						fill="currentColor"
					/>
				</svg>
			</a>
		</div>
	</div>
</div>



================================================
FILE: docs/site/src/lib/menu/Menu.svelte
================================================
<script lang="ts">
	let { currentNav = $bindable(''), showNum = true, menuList = [], onclickMenu } = $props();
	import type { MenuListChild } from '../../data/menuList.js';

	const setClick = (menu: MenuListChild) => {
		currentNav = menu.nav;
		onclickMenu(menu);
	};
	const isZh = localStorage.getItem('lang') === 'zh_CN';
</script>

<div class="flex flex-col px-2 py-4">
	<span class="pb-3 text-xs text-gray-500">
		{isZh ? '文档更新：' : 'Document last updated:'}
		<br />
		{isZh ? import.meta.env.VITE_BUILD_TIME_ZH : import.meta.env.VITE_BUILD_TIME_EN}
	</span>
	{#each menuList as menu}
		<div class="text-xs">
			{isZh ? menu.class : menu.class_en}{showNum ? `（${menu.childs.length}）` : ''}
		</div>
		<div class="my-2 ml-1 flex flex-col gap-3 border-l-2 border-black/10 pr-0 dark:border-white/20">
			{#each menu.childs as child}
				<button
					onclick={(e: MouseEvent) => {
						e.preventDefault();
						// e.self();
						setClick(child);
					}}
					class="box-content -translate-x-0.5 cursor-pointer border-l-2 py-0.5 pl-2 text-left text-sm transition-all hover:font-bold {child.nav ===
					currentNav
						? 'border-primary text-primary dark:border-dark dark:text-dark font-bold'
						: 'border-transparent'}"
				>
					{isZh ? child.title : child.title_en}
				</button>
			{/each}
		</div>
	{/each}
</div>



================================================
FILE: docs/site/src/lib/modeSwitch/darkMode.ts
================================================
/**
 * 给 HTML 元素增加或删除 dark 类名，实现 Mode 切换
 * Add or remove the dark class name to the HTML element to implement Mode switching
 * @param {boolean} [isDark] 是否为 dark 模式
 * @returns {void}
 * @example
 */
export default (isDark = true, ev: MouseEvent, useViewTransition = true) => {
	document.documentElement.style.setProperty('--x', ev.clientX + 'px');
	document.documentElement.style.setProperty('--y', ev.clientY + 'px');

	if (isDark) {
		if ('startViewTransition' in document && useViewTransition) {
			(document as Document & { startViewTransition: (callback: () => void) => void }).startViewTransition(() => {
				document.documentElement.classList.add('dark');
			});
		} else {
			document.documentElement.classList.add('dark');
		}
	} else {
		if ('startViewTransition' in document && useViewTransition) {
			(document as Document & { startViewTransition: (callback: () => void) => void }).startViewTransition(() => {
				document.documentElement.classList.remove('dark');
			});
		} else {
			document.documentElement.classList.remove('dark');
		}
	}
};



================================================
FILE: docs/site/src/lib/modeSwitch/ModeSwitch.svelte
================================================
<script lang="ts">
	let { useViewTransition = true } = $props();
	import darkMode from './darkMode';
	import { themeStore, sysThemeStore, currentThemeStore } from '../../store';
	let isClick = $state(false);
	//手动切换主题
	const toggleFun = (e: MouseEvent) => {
		// 阻止冒泡
		e.stopPropagation();
		isClick = true;
		setTimeout(() => {
			isClick = false;
		}, 150);
		if ($themeStore === 'light') {
			// 切换到 dark
			themeStore.set('dark');
			currentThemeStore.set('dark');
			localStorage.setItem('theme', 'dark');
			darkMode(true, e, useViewTransition);
		} else if ($themeStore === 'dark') {
			// 切换到 auto
			themeStore.set('auto');
			localStorage.setItem('theme', 'auto');
			if ($sysThemeStore === 'dark') {
				// 系统是暗模式
				darkMode(true, e, useViewTransition);
				currentThemeStore.set('dark');
			} else {
				darkMode(false, e, useViewTransition);
				currentThemeStore.set('light');
			}
		} else {
			// 切换到 light
			themeStore.set('light');
			currentThemeStore.set('light');
			localStorage.setItem('theme', 'light');
			darkMode(false, e, useViewTransition);
		}
	};
	//auto 时，监听系统主题
	const mql: MediaQueryList = window.matchMedia('(prefers-color-scheme: dark)');
	mql.addEventListener('change', (e: MediaQueryListEvent) => {
		if ($themeStore === 'auto') {
			if (e.matches) {
				// 系统是暗模式
				darkMode(true, e as unknown as MouseEvent);
				sysThemeStore.set('dark');
				currentThemeStore.set('dark');
			} else {
				darkMode(false, e as unknown as MouseEvent);
				sysThemeStore.set('light');
				currentThemeStore.set('light');
			}
		}
	});
	const isZh = localStorage.getItem('lang') === 'zh_CN';
</script>

<button
	class="mx-auto flex cursor-pointer justify-between rounded-sm bg-black/5 p-0.5 text-center dark:bg-white/10"
	aria-label={isZh
		? `${$themeStore === 'light' ? '亮模式' : $themeStore === 'dark' ? '暗模式' : '跟随系统'}`
		: `${$themeStore === 'light' ? 'Light' : $themeStore === 'dark' ? 'Dark' : 'System'}`}
	onclick={toggleFun}
>
	<div
		class:scale-75={isClick}
		class="min-h-full px-1 transition-all duration-150 rounded-sm{$themeStore === 'light' ? ' shadow-xs bg-white/80' : ''}"
		style="color:{$sysThemeStore === 'dark'
			? $themeStore === 'light'
				? '#ff3f2e'
				: '#646464'
			: $themeStore === 'light'
				? '#ff3f2e'
				: $themeStore === 'dark'
					? '#646464'
					: '#cecece'}"
	>
		<svg width="20" height="20" viewBox="0 0 20 24" fill="none" style="display: inline;" xmlns="http://www.w3.org/2000/svg">
			<path
				fill="currentColor"
				d="M9.99996 3.15217C10.5252 3.15217 10.951 2.72636 10.951 2.20109C10.951 1.67582 10.5252 1.25 9.99996 1.25C9.47469 1.25 9.04887 1.67582 9.04887 2.20109C9.04887 2.72636 9.47469 3.15217 9.99996 3.15217Z"
			/>
			<path
				fill="currentColor"
				d="M9.99992 4.29348C6.84829 4.29348 4.2934 6.84838 4.2934 10C4.2934 13.1516 6.84829 15.7065 9.99992 15.7065C13.1515 15.7065 15.7064 13.1516 15.7064 10C15.7064 6.84838 13.1515 4.29348 9.99992 4.29348Z"
			/>
			<path
				fill="currentColor"
				d="M16.4673 4.4837C16.4673 5.00896 16.0415 5.43478 15.5162 5.43478C14.991 5.43478 14.5652 5.00896 14.5652 4.4837C14.5652 3.95843 14.991 3.53261 15.5162 3.53261C16.0415 3.53261 16.4673 3.95843 16.4673 4.4837Z"
			/>
			<path
				fill="currentColor"
				d="M17.7989 10.9511C18.3241 10.9511 18.75 10.5253 18.75 10C18.75 9.47474 18.3241 9.04891 17.7989 9.04891C17.2736 9.04891 16.8478 9.47474 16.8478 10C16.8478 10.5253 17.2736 10.9511 17.7989 10.9511Z"
			/>
			<path
				fill="currentColor"
				d="M16.4673 15.5163C16.4673 16.0416 16.0415 16.4674 15.5162 16.4674C14.991 16.4674 14.5652 16.0416 14.5652 15.5163C14.5652 14.991 14.991 14.5652 15.5162 14.5652C16.0415 14.5652 16.4673 14.991 16.4673 15.5163Z"
			/>
			<path
				fill="currentColor"
				d="M9.99996 18.75C10.5252 18.75 10.951 18.3242 10.951 17.7989C10.951 17.2736 10.5252 16.8478 9.99996 16.8478C9.47469 16.8478 9.04887 17.2736 9.04887 17.7989C9.04887 18.3242 9.47469 18.75 9.99996 18.75Z"
			/>
			<path
				fill="currentColor"
				d="M5.43469 15.5163C5.43469 16.0416 5.00887 16.4674 4.4836 16.4674C3.95833 16.4674 3.53252 16.0416 3.53252 15.5163C3.53252 14.991 3.95833 14.5652 4.4836 14.5652C5.00887 14.5652 5.43469 14.991 5.43469 15.5163Z"
			/>
			<path
				fill="currentColor"
				d="M2.20096 10.9511C2.72623 10.9511 3.15205 10.5253 3.15205 10C3.15205 9.47474 2.72623 9.04891 2.20096 9.04891C1.67569 9.04891 1.24988 9.47474 1.24988 10C1.24988 10.5253 1.67569 10.9511 2.20096 10.9511Z"
			/>
			<path
				fill="currentColor"
				d="M5.43469 4.4837C5.43469 5.00896 5.00887 5.43478 4.4836 5.43478C3.95833 5.43478 3.53252 5.00896 3.53252 4.4837C3.53252 3.95843 3.95833 3.53261 4.4836 3.53261C5.00887 3.53261 5.43469 3.95843 5.43469 4.4837Z"
			/>
		</svg>
	</div>
	<div
		class:scale-75={isClick}
		class="min-h-full px-1 transition-all duration-150 rounded-sm{$themeStore === 'dark' ? ' shadow-xs bg-black/50' : ''}"
		style="color:{$sysThemeStore === 'light'
			? $themeStore === 'auto'
				? '#cecece'
				: $themeStore === 'dark'
					? '#fff'
					: '#cecece'
			: $themeStore === 'light'
				? '#cecece'
				: $themeStore === 'auto'
					? '#646464'
					: '#fff'}"
	>
		<svg width="20" height="20" style="display: inline;position:relative;top:-1px" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
			<path
				fill="currentColor"
				d="M9.99993 3.12494C6.20294 3.12494 3.12488 6.203 3.12488 10C3.12488 13.797 6.20294 16.8751 9.99993 16.8751C13.7969 16.8751 16.875 13.797 16.875 10C16.875 9.52352 16.8264 9.0577 16.7337 8.6075C16.6752 8.32295 16.4282 8.11628 16.1378 8.10872C15.8474 8.10117 15.5901 8.29473 15.5168 8.57585C15.1411 10.0167 13.8302 11.0795 12.2727 11.0795C10.4212 11.0795 8.92039 9.57869 8.92039 7.72726C8.92039 6.16969 9.98319 4.85879 11.4241 4.48312C11.7052 4.40983 11.8988 4.15249 11.8912 3.86207C11.8836 3.57165 11.677 3.32473 11.3924 3.26616C10.9422 3.1735 10.4764 3.12494 9.99993 3.12494Z"
			/>
		</svg>
	</div>
	<div
		class="min-h-full px-1 transition-all duration-150 rounded-sm{$themeStore === 'auto' && $sysThemeStore === 'light'
			? ' bg-white/80'
			: ''}{$themeStore === 'auto' && $sysThemeStore === 'dark' ? ' bg-black/50' : ''}{$themeStore === 'auto' && $sysThemeStore === 'light'
			? ' shadow-xs'
			: ''}"
		style="color:{$themeStore === 'light'
			? '#cecece'
			: $themeStore === 'dark'
				? '#646464'
				: $themeStore === 'auto' && $sysThemeStore === 'light'
					? '#ff3f2e'
					: '#fff'};background-size: 30%;"
	>
		<svg xmlns="http://www.w3.org/2000/svg" style="display: inline;" viewBox="0 0 24 28" width="20" height="20">
			<path
				fill="currentColor"
				d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm0-2V6a6 6 0 1 1 0 12z"
			/>
		</svg>
	</div>
</button>




================================================
FILE: docs/site/src/lib/tab/Tab.svelte
================================================
<script lang="ts">
	import { fade } from 'svelte/transition';
	import { currentThemeStore, isWideScreenStore } from '../../store';
	// @ts-expect-error - beautify-qrcode 缺少类型定义
	import { encodeData, rendererLine } from 'beautify-qrcode';
	import { page } from '$app/stores';

	let { currentTab = 0, onclickTab } = $props();

	const tabList = [
		{ zh: '示例', en: 'Demo' },
		{ zh: 'API', en: 'API' },
		{ zh: '指南', en: 'Guide' },
		{ zh: 'FAQ', en: 'FAQ' },
		{ zh: '版本', en: 'Version' }
	];
	const changeIndexFun = (i: number) => {
		currentTab = i;
		onclickTab?.(i);
	};
	const isZh = localStorage.getItem('lang') === 'zh_CN';
	let showQr = $state(false);
	let QRValue = $state('');
	let A_a1Svg = $state('');

	const mouseenterFun = () => {
		const params = new URLSearchParams('?' + $page.url.searchParams);
		QRValue =
			(import.meta.env.DEV ? location.protocol + '//' + location.hostname + ':8888/' : 'HTTPS://DEMO.STDF.DESIGN/') +
			params.get('nav') +
			(isZh ? '/zh_CN' : '/en_US');
		showQr = true;
		/**
		 * A_a1
		 * @param {Object} qrcode
		 * @param {Object} options
		 * @param {String} [options.type]  连线方向 0=>左右 1=>上下 2=>纵横 3=>回环 4=>左上—右下 5=>右上—左下 6=>交叉"
		 * @param {String} [options.size] 连线粗细
		 * @param {String} [options.opacity] 连线不透明度
		 * @param {String} [options.posType] 定位点样式  0=>矩形 1=>圆形 2=>行星 3=>圆角矩形
		 * @param {String} [options.otherColor] 连线颜色
		 * @param {String} [options.posColor] 定位点颜色
		 */
		const qrcode = encodeData({
			text: QRValue,
			isSpace: false
		});
		const color = $currentThemeStore === 'dark' ? 'var(--color-dark)' : 'var(--color-primary)';
		A_a1Svg = rendererLine(qrcode, {
			posType: 2,
			otherColor: color,
			posColor: color
		});
	};

	let showStackblitz = $state(false);
	let stackblitzValue = $state('');
	const showStackblitzFunc = () => {
		const nav = $page.url.searchParams.get('nav');
		stackblitzValue = `https://stackblitz.com/github/any-tdf/demo-stdf?file=src%2Froutes%2F${
			nav
		}%2F${isZh ? 'zh_CN' : 'en_US'}%2F%2Bpage.svelte&startScript=${nav}${isZh ? '' : '_en'}`;
		showStackblitz = true;
	};

	let showCode = $state(false);
	let codeValue = $state('');
	const showCodeFunc = () => {
		const nav = $page.url.searchParams.get('nav');
		// 将 nav 首字母大写
		const navFirst = nav ? nav.slice(0, 1).toUpperCase() + nav.slice(1) : '';
		codeValue = `https://github.com/any-tdf/stdf/blob/main/packages/stdf/src/lib/components/${nav}/${navFirst}.svelte`;
		showCode = true;
	};
	let showFull = $state(false);
	// 全屏
	const changeFullFunc = () => {
		if ($isWideScreenStore) {
			isWideScreenStore.set(false);
			localStorage.setItem('isFull', 'notFull');
		} else {
			isWideScreenStore.set(true);
			localStorage.setItem('isFull', 'full');
		}
	};
</script>

<div class="w-82 md:w-102 relative top-14">
	<div class="relative rounded-sm bg-gray-100 p-1 dark:bg-gray-700">
		<!--滑块-->
		<div
			class="absolute top-1 h-10 w-16 rounded-sm bg-white shadow-md transition-all duration-300 md:w-20 dark:bg-black dark:shadow-white/10"
			class:left-1={currentTab === 0}
			class:left-17={currentTab === 1}
			class:md:left-21={currentTab === 1}
			class:left-33={currentTab === 2}
			class:md:left-41={currentTab === 2}
			class:left-49={currentTab === 3}
			class:md:left-61={currentTab === 3}
			class:left-65={currentTab === 4}
			class:md:left-81={currentTab === 4}
		></div>
		<!--二维码-->
		<a href={QRValue} target="_blank">
			<button
				onmouseleave={() => (showQr = false)}
				onmouseenter={mouseenterFun}
				class="left-106 absolute top-0 hidden h-12 w-12 rounded-sm bg-gray-100 p-3 md:block dark:bg-gray-700"
			>
				<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style="fill: currentColor">
					<path fill="none" d="M0 0h24v24H0z" />
					<path
						d="M16 17v-1h-3v-3h3v2h2v2h-1v2h-2v2h-2v-3h2v-1h1zm5 4h-4v-2h2v-2h2v4zM3 3h8v8H3V3zm2 2v4h4V5H5zm8-2h8v8h-8V3zm2 2v4h4V5h-4zM3 13h8v8H3v-8zm2 2v4h4v-4H5zm13-2h3v2h-3v-2zM6 6h2v2H6V6zm0 10h2v2H6v-2zM16 6h2v2h-2V6z"
					/>
				</svg>
				{#if showQr}
					<div
						class="absolute left-0 top-14 z-50 hidden w-60 rounded-sm bg-black p-6 shadow-lg dark:block"
						transition:fade={{ duration: 200 }}
					>
						<!-- eslint-disable-next-line svelte/no-at-html-tags -->
						<span>{@html A_a1Svg}</span>
					</div>
				{/if}
				{#if showQr}
					<div
						class="absolute left-0 top-14 z-50 block w-60 rounded-sm bg-white p-6 shadow-lg dark:hidden"
						transition:fade={{ duration: 200 }}
					>
						<!-- eslint-disable-next-line svelte/no-at-html-tags -->
						<span>{@html A_a1Svg}</span>
					</div>
				{/if}
			</button>
		</a>

		<!--组件源码-->
		<a href={codeValue} target="_blank">
			<button
				onmouseleave={() => (showCode = false)}
				onmouseenter={showCodeFunc}
				class="absolute left-[30.5rem] top-0 hidden h-12 w-12 rounded-sm bg-gray-100 p-3 md:block dark:bg-gray-700"
			>
				<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style="fill: currentColor">
					<path
						d="M3 3H21C21.5523 3 22 3.44772 22 4V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3ZM4 5V19H20V5H4ZM20 12L16.4645 15.5355L15.0503 14.1213L17.1716 12L15.0503 9.87868L16.4645 8.46447L20 12ZM6.82843 12L8.94975 14.1213L7.53553 15.5355L4 12L7.53553 8.46447L8.94975 9.87868L6.82843 12ZM11.2443 17H9.11597L12.7557 7H14.884L11.2443 17Z"
					/>
				</svg>
				{#if showCode}
					<div
						class="{isZh
							? 'w-28'
							: 'w-52'} absolute left-0 top-14 z-50 h-12 rounded-sm bg-gray-700 py-3 text-center leading-[1.5rem] text-white shadow-lg"
						transition:fade={{ duration: 200 }}
					>
						{isZh ? '组件源码' : 'Component source code'}
					</div>
				{/if}
			</button>
		</a>
		<!--StackBlitz-->
		<a href={stackblitzValue} target="_blank">
			<button
				onmouseleave={() => (showStackblitz = false)}
				onmouseenter={showStackblitzFunc}
				class="absolute left-[34.5rem] top-0 hidden h-12 w-12 rounded-sm bg-gray-100 p-3 md:block dark:bg-gray-700"
			>
				<svg viewBox="0 0 28 28" height="24">
					<path fill="#3275e7" d="M12.747 16.273h-7.46L18.925 1.5l-3.671 10.227h7.46L9.075 26.5l3.671-10.227z" />
				</svg>
				{#if showStackblitz}
					<div
						class="absolute left-0 top-14 z-50 h-12 w-44 rounded-sm bg-gray-700 py-3 text-center leading-[1.5rem] text-white shadow-lg"
						transition:fade={{ duration: 200 }}
					>
						{isZh ? '在 StackBlitz 中打开' : 'Open in StackBlitz'}
					</div>
				{/if}
			</button>
		</a>
		<!-- 宽屏 -->
		<button
			onclick={changeFullFunc}
			onmouseleave={() => (showFull = false)}
			onmouseenter={() => (showFull = true)}
			onfocus={() => (showFull = true)}
			onblur={() => (showFull = false)}
			class="absolute left-[38.5rem] top-0 hidden h-12 w-12 cursor-pointer rounded-sm bg-gray-100 p-3 md:block dark:bg-gray-700"
		>
			{#if $isWideScreenStore}
				<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
					<path
						d="M20 3C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3H20ZM11 5H5V19H11V15H13V19H19V5H13V9H11V5ZM15 9L18 12L15 15V13H9V15L6 12L9 9V11H15V9Z"
						fill="currentColor"
					></path>
				</svg>
			{:else}
				<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
					<path
						d="M20 3C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3H20ZM11 5H5V10.999H7V9L10 12L7 15V13H5V19H11V17H13V19H19V13H17V15L14 12L17 9V10.999H19V5H13V7H11V5ZM13 13V15H11V13H13ZM13 9V11H11V9H13Z"
						fill="currentColor"
					></path>
				</svg>
			{/if}
			{#if showFull}
				<div
					class="{isZh
						? 'w-20'
						: 'w-32'} absolute left-0 top-14 z-50 h-12 rounded-sm bg-gray-700 py-3 text-center leading-[1.5rem] text-white shadow-lg"
					transition:fade={{ duration: 200 }}
				>
					{isZh ? '宽屏' : 'Full screen'}
				</div>
			{/if}
		</button>
		<div class="relative flex">
			{#each tabList as item, index}
				<button onclick={() => changeIndexFun(index)} class="w-16 cursor-pointer rounded-sm py-2 text-center md:w-20">
					{isZh ? item.zh : item.en}
				</button>
			{/each}
		</div>
	</div>
</div>



================================================
FILE: docs/site/src/lib/themeSwitch/ThemeSwitch.svelte
================================================
<script lang="ts">
	import { switchTheme, type ThemeProps } from 'stdf/theme';
	import themes from '../../data/themes/index.js';
	import { currentColorStore } from '../../store.js';

	type ThemeItem = { name: string; name_CN: string; theme: ThemeProps };

	// 横排还是竖排
	export let vertical = false;

	const isZh = localStorage.getItem('lang') === 'zh_CN';

	const selectColorFunc = (e: MouseEvent, item: ThemeItem) => {
		// 阻止冒泡
		e.stopPropagation();
		currentColorStore.set(item.name);
		localStorage.setItem('theme_color', item.name);
		const theme = item.theme;
		switchTheme(theme);
		// 修改 HTML 的 meta name="theme-color" 属性，适配 Safari 的 tab 背景色，需要设置 light 和 dark 两种颜色
		const safariLight = theme.color.primaryWhite;
		const safariDark = theme.color.darkBlack;
		// 查找 meta 标签，name="theme-color" 且 media="(prefers-color-scheme: light)"
		const lightMeta = document.querySelector('meta[name="theme-color"][media="(prefers-color-scheme: light)"]');
		// 查找 meta 标签，name="theme-color" 且 media="(prefers-color-scheme: dark)"
		const darkMeta = document.querySelector('meta[name="theme-color"][media="(prefers-color-scheme: dark)"]');
		// 如果找到了，就修改它的 content 属性
		if (lightMeta) {
			lightMeta.setAttribute('content', safariLight);
		}
		if (darkMeta) {
			darkMeta.setAttribute('content', safariDark);
		}
	};
</script>

<div class="flex {vertical ? 'flex-col gap-1' : 'flex-row gap-2'} my-2 flex-wrap">
	{#each themes as item}
		<button
			class="flex items-center justify-between gap-0.5 border px-0.5 py-1 {$currentColorStore === item.name
				? 'border-primary dark:border-dark'
				: 'border-gray-100 dark:border-gray-700'} cursor-pointer rounded-sm"
			on:click={(e) => selectColorFunc(e, item)}
		>
			<div class="size-3 {$currentColorStore === item.name ? 'fill-primary dark:fill-dark' : 'fill-gray-300 dark:fill-gray-700'}">
				<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
					<path
						d="M12 2C17.5222 2 22 5.97778 22 10.8889C22 13.9556 19.5111 16.4444 16.4444 16.4444H14.4778C13.5556 16.4444 12.8111 17.1889 12.8111 18.1111C12.8111 18.5333 12.9778 18.9222 13.2333 19.2111C13.5 19.5111 13.6667 19.9 13.6667 20.3333C13.6667 21.2556 12.9 22 12 22C6.47778 22 2 17.5222 2 12C2 6.47778 6.47778 2 12 2ZM7.5 12C8.32843 12 9 11.3284 9 10.5C9 9.67157 8.32843 9 7.5 9C6.67157 9 6 9.67157 6 10.5C6 11.3284 6.67157 12 7.5 12ZM16.5 12C17.3284 12 18 11.3284 18 10.5C18 9.67157 17.3284 9 16.5 9C15.6716 9 15 9.67157 15 10.5C15 11.3284 15.6716 12 16.5 12ZM12 9C12.8284 9 13.5 8.32843 13.5 7.5C13.5 6.67157 12.8284 6 12 6C11.1716 6 10.5 6.67157 10.5 7.5C10.5 8.32843 11.1716 9 12 9Z"
					>
					</path>
				</svg>
			</div>
			<div class="flex-1 whitespace-nowrap text-left text-xs font-normal">{isZh ? item.name_CN : item.name}</div>
			<div class="flex justify-between gap-1">
				<!-- theme  -->
				<div class="rounded-xs flex overflow-hidden">
					<div class="bg-primary w-3" style="background-color: {item.theme.color.primary.default};"></div>
					<div class="bg-dark w-3" style="background-color: {item.theme.color.dark.default};"></div>
				</div>
				<div class="flex flex-col justify-between gap-px">
					<!-- Functional -->
					<div class="flex gap-px">
						<div class="size-1.5 rounded" style="background-color: {item.theme.color.functional.success};"></div>
						<div class="size-1.5 rounded" style="background-color: {item.theme.color.functional.warning};"></div>
						<div class="size-1.5 rounded" style="background-color: {item.theme.color.functional.error};"></div>
						<div class="size-1.5 rounded" style="background-color: {item.theme.color.functional.info};"></div>
					</div>
					<!-- Extended -->
					<div class="flex justify-between gap-px">
						{#each item.theme.color.extend as child}
							<div class="size-1.5 rounded" style="background-color: {child.color};"></div>
						{/each}
					</div>
				</div>
			</div>
		</button>
	{/each}
	{#if vertical}
		<a
			href="/guide/generator"
			target="_blank"
			class="text-primary hover:border-primary dark:text-dark dark:hover:border-dark group mt-2 flex items-center justify-center gap-1 rounded-sm border border-gray-100 py-1 text-xs transition-all duration-300 dark:border-gray-700"
		>
			<svg class="size-4 transition-all duration-300 group-hover:scale-95" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
				<path
					class="fill-primary dark:fill-dark"
					d="M15.1986 9.94435C14.7649 9.53358 14.4859 8.98601 14.4085 8.39371L14.0056 5.31126L11.275 6.79711C10.7503 7.08262 10.1433 7.17876 9.55608 7.06936L6.49998 6.50003L7.06931 9.55612C7.17871 10.1434 7.08257 10.7503 6.79707 11.275L5.31121 14.0056L8.39367 14.4085C8.98596 14.4859 9.53353 14.7649 9.94431 15.1986L12.0821 17.4555L13.4178 14.6485C13.6745 14.1091 14.109 13.6745 14.6484 13.4179L17.4555 12.0821L15.1986 9.94435ZM15.2238 15.5078L13.0111 20.1579C12.8687 20.4572 12.5107 20.5843 12.2115 20.4419C12.1448 20.4102 12.0845 20.3664 12.0337 20.3127L8.49229 16.574C8.39749 16.4739 8.27113 16.4095 8.13445 16.3917L3.02816 15.7242C2.69958 15.6812 2.46804 15.3801 2.51099 15.0515C2.52056 14.9782 2.54359 14.9074 2.5789 14.8425L5.04031 10.3191C5.1062 10.198 5.12839 10.0579 5.10314 9.92241L4.16 4.85979C4.09931 4.53402 4.3142 4.22074 4.63997 4.16005C4.7126 4.14652 4.78711 4.14652 4.85974 4.16005L9.92237 5.10319C10.0579 5.12843 10.198 5.10625 10.319 5.04036L14.8424 2.57895C15.1335 2.42056 15.4979 2.52812 15.6562 2.81919C15.6916 2.88409 15.7146 2.95495 15.7241 3.02821L16.3916 8.13449C16.4095 8.27118 16.4739 8.39754 16.5739 8.49233L20.3127 12.0337C20.5533 12.2616 20.5636 12.6414 20.3357 12.8819C20.2849 12.9356 20.2246 12.9794 20.1579 13.0111L15.5078 15.2238C15.3833 15.2831 15.283 15.3833 15.2238 15.5078ZM16.0206 17.4349L17.4348 16.0207L21.6775 20.2633L20.2633 21.6775L16.0206 17.4349Z"
				>
				</path>
			</svg>
			{isZh ? '创建新主题' : 'Create new theme'}
		</a>
	{/if}
</div>



================================================
FILE: docs/site/src/routes/+error.svelte
================================================
<script lang="ts">
	const isZh = localStorage.getItem('lang') === 'zh_CN';
</script>

<div class="flex h-screen flex-col items-center justify-center">
	<div class="flex flex-col items-center">
		<div class="flex items-center gap-1">
			<div class="text-primary dark:text-dark mb-4 text-9xl font-bold">4</div>
			<div>
				<svg viewBox="0 0 100 100" class="svg-spin size-20">
					<path
						fill-rule="evenodd"
						clip-rule="evenodd"
						d="M50 0V100C22.3858 100 0 77.6142 0 50C0 22.3858 22.3858 0 50 0Z"
						class="fill-dark"
					/>
					<path
						fill-rule="evenodd"
						clip-rule="evenodd"
						d="M50 100V0C77.6142 0 100 22.3858 100 50C100 77.6142 77.6142 100 50 100Z"
						class="fill-primary"
					/>
					<circle cx="50" cy="25" r="25" class="fill-primary" />
					<circle cx="50" cy="75" r="25" class="fill-dark" />
					<circle cx="50.25" cy="25.25" r="6.25" class="fill-dark" />
					<circle cx="50.25" cy="75.25" r="6.25" class="fill-primary" />
				</svg>
			</div>
			<div class="text-primary dark:text-dark mb-4 text-9xl font-bold">4</div>
		</div>
		<p class="mb-8 text-black/60 dark:text-white/60">{isZh ? '抱歉，页面未找到' : 'Sorry, page not found'}</p>
		<a href="/" class="bg-primary dark:bg-dark rounded px-6 py-2 text-white hover:opacity-90 dark:text-black">
			{isZh ? '返回首页' : 'Back to home'}
		</a>
	</div>
</div>

<style>
	@keyframes svg-spin {
		0% {
			transform: rotate(360deg);
		}
		100% {
			transform: rotate(0deg);
		}
	}

	.svg-spin {
		animation: svg-spin 8s linear infinite;
	}
</style>



================================================
FILE: docs/site/src/routes/+layout.svelte
================================================
<script lang="ts">
	import themes from '../data/themes/index.js';
	import { switchTheme } from 'stdf/theme';
	import Header from '$lib/header/Header.svelte';
	import CmdK from '$lib/cmdk/CmdK.svelte';
	import Fund from '$lib/fund/Fund.svelte';
	import { page } from '$app/stores';
	import { isCmdKStore, isShowFundStore } from '../store.js';
	import '../app.css';
	import { delParamsUrl } from '../utils/index.js';

	let { children } = $props();

	let showLeftNav = $state(false); //是否显示左侧导航
	let isHome = $page.url.pathname === '/' || $page.url.pathname === '';

	//路由改变时，更新左侧导航
	$effect(() => {
		showLeftNav = $page.url.pathname.startsWith('/guide') || $page.url.pathname === '/components';
	});
	// 点击顶部菜单事件
	const headerCmdKFun = () => {
		isCmdKStore.set(true);
	};

	const currentTheme = localStorage.getItem('theme_color') || 'STDF';
	// 设置默认主题色
	themes.forEach((item) => {
		if (item.name === currentTheme) {
			const theme = item.theme;
			switchTheme(theme);
			// 修改 HTML 的 meta name="theme-color" 属性，适配 Safari 的 tab 背景色，需要设置 light 和 dark 两种颜色
			const safariLight = theme.color.primaryWhite;
			const safariDark = theme.color.darkBlack;
			// 查找 meta 标签，name="theme-color" 且 media="(prefers-color-scheme: light)"
			const lightMeta = document.querySelector('meta[name="theme-color"][media="(prefers-color-scheme: light)"]');
			// 查找 meta 标签，name="theme-color" 且 media="(prefers-color-scheme: dark)"
			const darkMeta = document.querySelector('meta[name="theme-color"][media="(prefers-color-scheme: dark)"]');
			// 如果找到了，就修改它的 content 属性
			if (lightMeta) {
				lightMeta.setAttribute('content', safariLight);
			}
			if (darkMeta) {
				darkMeta.setAttribute('content', safariDark);
			}
		}
	});

	let urlLang = window.location.href.split('?')[1];
	if (!urlLang || (urlLang && !urlLang.includes('lang'))) {
		if (!localStorage.getItem('lang')) {
			//获取浏览器语言前两位
			const lang = navigator.language.substring(0, 2);
			if (lang === 'en') {
				localStorage.setItem('lang', 'en_US');
			} else {
				localStorage.setItem('lang', 'zh_CN');
			}
		}
	} else {
		let urlParams = new URLSearchParams(urlLang);
		localStorage.setItem('lang', urlParams.get('lang') || '');
		setTimeout(() => {
			// window.location.href = window.location.href.replace(/(\?|#)[^'"]*/, '');//去除参数
			const url = new URL(window.location.href);
			url.searchParams.delete('lang');
			window.history.pushState({}, '', url.toString()); //刷新页面
		}, 10);
	}
	if (localStorage.getItem('theme') === 'dark') {
		document.documentElement.classList.add('dark');
	} else if (localStorage.getItem('theme') === 'light') {
		document.documentElement.classList.remove('dark');
	} else {
		if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
			document.documentElement.classList.add('dark');
		} else {
			document.documentElement.classList.remove('dark');
		}
	}
	const isZh = localStorage.getItem('lang') === 'zh_CN';

	// 根据 params 判断当前 URL 是否含有 fund 参数，如果有则显示赞赏弹窗
	const urlFund = window.location.href.split('?')[1];
	const urlParams = new URLSearchParams(urlFund);
	const isFund = urlParams.has('fund');
	if (isFund) {
		isShowFundStore.set(true);
		// 去除 URL 中的 fund 参数
		setTimeout(() => {
			window.history.replaceState({}, '', delParamsUrl(window.location.href, 'fund'));
		}, 10);
	}
</script>

<svelte:head>
	<title>STDF - {isZh ? '移动 web 组件库' : 'Mobile web component library'}</title>
</svelte:head>

<main class="bg-primaryWhite dark:bg-darkBlack relative min-h-screen text-justify text-black antialiased dark:text-white">
	<Header {showLeftNav} showBottonLine={!isHome} onclickCmdK={headerCmdKFun} />
	<!-- <Router {routes} /> -->
	<!-- <div class="mx-auto max-w-[1536px]"> -->
	{@render children()}
	<!-- </div> -->

	<CmdK />
	<!-- 赞赏 -->
	{#if $isShowFundStore}
		<Fund />
	{/if}
</main>



================================================
FILE: docs/site/src/routes/+layout.ts
================================================
// 修改 ssr 为 false，使其不再使用服务端渲染，而是使用客户端渲染
// Change ssr to false to use client-side rendering instead of server-side rendering
export const ssr = false;

// 开启预渲染
// Enable prerendering
export const prerender = true;



================================================
FILE: docs/site/src/routes/+page.svelte
================================================
<script lang="ts">
	import { onMount } from 'svelte';
	import { fly } from 'svelte/transition';
	import { Confetti } from 'svelte-confetti';
	import { currentThemeStore, currentColorStore } from '../store';
	// @ts-ignore
	import { encodeData, rendererLine } from 'beautify-qrcode';
	import { Tab, Loading, Switch, Avatar, Pagination, Input, Rate, Icon, NoticeBar, Slider, Swiper, Button } from 'stdf';
	import type { SwiperImgProps, SwiperProps } from 'stdf/types';
	import { menuList, type MenuList } from '../data/menuList';
	import themes from '../data/themes/index.js';
	import { switchTheme } from 'stdf/theme';
	import Clis from '../lib/clis/Clis.svelte';
	const isZh = localStorage.getItem('lang') === 'zh_CN';

	// 随机生成 1_0 到 1_53 这种字符串
	const randomNum = Math.floor(Math.random() * 53) + 1;
	const randomNumStr = `1_${randomNum}`;
	const swiperData: SwiperImgProps[] = [
		{ type: 'img', url: '/assets/images/home/wall_1.jpg' },
		{ type: 'img', url: '/assets/images/home/wall_2.jpg' },
		{ type: 'img', url: '/assets/images/home/wall_3.jpg' },
		{ type: 'img', url: '/assets/images/home/wall_4.jpg' }
	];
	const swiperOptions: SwiperProps[] = [
		{
			data: swiperData,
			containerWidth: 390,
			px: '6',
			py: '6',
			indicateInjClass: 'bg-none',
			indicateColor: 'bg-black/5 dark:bg-white/10',
			indicateActiveColor: 'bg-primary dark:bg-dark',
			radius: 'xl',
			indicateStyle: 'longLine'
		},
		{
			data: swiperData,
			containerWidth: 390,
			px: '16',
			py: '6',
			indicateInjClass: 'bg-none',
			indicateColor: 'bg-primary dark:bg-dark',
			indicateActiveColor: 'bg-primary dark:bg-dark',
			radius: 'xl',
			aspectRatio: [3, 1],
			innerInjClass: 'shadow-md shadow-black/20 dark:shadow-white/20',
			translateX: 100
		},
		{
			data: swiperData,
			containerWidth: 390,
			px: '4',
			py: '8',
			indicateInjClass: 'bg-none',
			indicateColor: 'bg-primary dark:bg-dark',
			indicateActiveColor: 'bg-primary dark:bg-dark',
			radius: 'xl',
			rotateY: 90,
			innerInjClass: 'shadow-md shadow-black/20 dark:shadow-white/20'
		},
		{
			data: swiperData,
			containerWidth: 390,
			px: '24',
			py: '8',
			indicateInjClass: 'bg-none',
			indicateColor: 'bg-primary dark:bg-dark',
			indicateActiveColor: 'bg-primary dark:bg-dark',
			innerInjClass: 'shadow-md shadow-black/20 dark:shadow-white/20',
			radius: 'xl',
			aspectRatio: [3, 1],
			translateX: 160,
			notActiveInjClass: 'grayscale'
		},
		{
			data: swiperData,
			indicateStyle: 'longLine',
			containerWidth: 390,
			px: '12',
			py: '8',
			indicateInjClass: 'bg-none',
			indicateColor: 'bg-black/5 dark:bg-white/10',
			indicateActiveColor: 'bg-primary dark:bg-dark',
			radius: 'xl',
			translateZ: 600,
			innerInjClass: 'shadow-md shadow-black/20 dark:shadow-white/20'
		}
	];
	const swiperOption = swiperOptions[Math.floor(Math.random() * swiperOptions.length)];
	//数组二级组成新数组
	const ArrChildFun = (arr: MenuList[]) => {
		const newArr = [];
		for (let e = 0; e < arr.length; e++) {
			newArr.push(...arr[e].childs);
		}
		return newArr;
	};
	const menuChildList = ArrChildFun(menuList);
	// 从 menuChildList 中随机取 3 个
	const randomMenuChildList = menuChildList.sort(() => Math.random() - 0.5).slice(0, 3);
	const textList = randomMenuChildList.map((item, index) => {
		return `${index + 1}. ${isZh ? item.tip : item.tip_en}`;
	});
	const labels = randomMenuChildList.map((item) => {
		return { text: isZh ? item.title_zh : item.title_en };
	});
	// Avatar radius 随机 'none'|'sm'|'xl'|'2xl'|'3xl'|'full'
	const avatarRadiusList = ['none', 'sm', 'xl', '2xl', '3xl', 'full'] as const;
	const avatarRadius = avatarRadiusList[Math.floor(Math.random() * avatarRadiusList.length)];
	const avatarImgs = ['/assets/images/home/wall_3.jpg', '/assets/images/home/avatar_1.jpg', null];
	const avatar = avatarImgs[Math.floor(Math.random() * avatarImgs.length)];
	// Switch radius 随机 'none'|'middle'|'full' ，inside 随机 'state'|'loading'|null
	const switchRadiusList = ['none', 'middle', 'full'];
	const switchRadius = switchRadiusList[Math.floor(Math.random() * switchRadiusList.length)] as 'none' | 'middle' | 'full';
	const switchInsideList = ['state', 'loading', null];
	const switchInside = switchInsideList[Math.floor(Math.random() * switchInsideList.length)] as 'state' | 'loading' | null;
	// Slider 随机 0-100
	const sliderValue = Math.floor(Math.random() * 100);
	// slider radius 随机 'none'|'full'|'sm'|'xl'
	const sliderRadiusList = ['none', 'full', 'sm', 'xl'];
	const sliderRadius = sliderRadiusList[Math.floor(Math.random() * sliderRadiusList.length)] as 'none' | 'full' | 'sm' | 'xl';
	const sliderShowTipList = ['always', 'never', 'touch'];
	const sliderShowTip = sliderShowTipList[Math.floor(Math.random() * sliderShowTipList.length)] as 'always' | 'never' | 'touch';
	// 列举 20 个与评分相关的 emoji 表情
	const emojiList1 = ['love', 'default'];
	const emojiList2 = ['👍', '👋', '👏', '🌺', '🏆', '🎯', '💯', '🎳', '🎖️'];
	// 随机出一个 emoji，emojiList1 的概率为 0.5，emojiList2 的概率为 0.5
	const emoji =
		Math.random() > 0.5
			? emojiList1[Math.floor(Math.random() * emojiList1.length)]
			: emojiList2[Math.floor(Math.random() * emojiList2.length)];
	// Tab radius 随机 'none'|'full'|'sm'|'xl'
	const tabRadiusList = ['none', 'full', 'sm', 'xl'];
	const tabRadius = tabRadiusList[Math.floor(Math.random() * tabRadiusList.length)] as 'none' | 'full' | 'sm' | 'xl';
	// lineType 随机 true 或 false
	const lineType = Math.random() > 0.5;
	// Pagination 随机总条数 50 - 200 和当前页，保证当前页在 1 - 总条数/10 之间
	const paginationTotal = Math.floor(Math.random() * 150) + 50;
	const paginationCurrent = Math.floor(Math.random() * (paginationTotal / 10)) + 1;
	// paginationType 随机 'block'|'bold'|'border'
	const paginationTypeList = ['block', 'bold', 'border'];
	const paginationType = paginationTypeList[Math.floor(Math.random() * paginationTypeList.length)] as 'block' | 'bold' | 'border';
	const paginationRadiusList = ['none', 'sm', 'md', 'lg', 'xl', 'full'];
	const paginationRadius = paginationRadiusList[Math.floor(Math.random() * paginationRadiusList.length)] as
		| 'none'
		| 'sm'
		| 'md'
		| 'lg'
		| 'xl'
		| 'full';
	const injPaginationRadiusList = {
		none: 'rounded-none',
		sm: 'rounded-sm',
		md: 'rounded-md',
		lg: 'rounded-lg',
		xl: 'rounded-xl',
		full: 'rounded-full'
	};
	const injPaginationRadius = injPaginationRadiusList[paginationRadius];
	// 随机主题
	const randomThemeFunc = () => {
		const item = themes[Math.floor(Math.random() * themes.length)];
		currentColorStore.set(item.name);
		localStorage.setItem('theme_color', item.name);
		const theme = item.theme;

		switchTheme(theme);
		// 修改 HTML 的 meta name="theme-color" 属性，适配 Safari 的 tab 背景色，需要设置 light 和 dark 两种颜色
		const safariLight = theme.color.primaryWhite;
		const safariDark = theme.color.darkBlack;
		// 查找 meta 标签，name="theme-color" 且 media="(prefers-color-scheme: light)"
		const lightMeta = document.querySelector('meta[name="theme-color"][media="(prefers-color-scheme: light)"]');
		// 查找 meta 标签，name="theme-color" 且 media="(prefers-color-scheme: dark)"
		const darkMeta = document.querySelector('meta[name="theme-color"][media="(prefers-color-scheme: dark)"]');
		// 如果找到了，就修改它的 content 属性
		if (lightMeta) {
			lightMeta.setAttribute('content', safariLight);
		}
		if (darkMeta) {
			darkMeta.setAttribute('content', safariDark);
		}
	};
	// randomMenuChildList 随机出一个
	const inputList = randomMenuChildList[Math.floor(Math.random() * randomMenuChildList.length)];
	const inputTitle = isZh ? inputList.title_zh : inputList.title_en;
	let inputValue = $state(isZh ? inputList.tip : inputList.tip_en);
	const inputRadiusList = ['none', 'full', 'sm', 'xl'];
	const inputRadius = inputRadiusList[Math.floor(Math.random() * inputRadiusList.length)] as 'none' | 'full' | 'sm' | 'xl';
	const inputStyleList = ['line', 'block'];
	const inputStyle = inputStyleList[Math.floor(Math.random() * inputStyleList.length)] as 'line' | 'block';
	let showInputConfetti = $derived(inputValue === inputTitle);
	// 当 inputValue === inputTitle 时，显示 confetti
	const inputFun = (v: string) => {
		inputValue = v;
	};

	const descList = [
		{
			title: 'Simple',
			titleZh: '简单',
			desc: '代码清晰，文档完善，易于使用。',
			descEn: 'Clear code, complete docs, easy to use.',
			icon: '/assets/images/home/s.jpeg',
			icon_d: '/assets/images/home/s-d.png',
			shwTip: false
		},
		{
			title: 'Tiny',
			titleZh: '轻量',
			desc: '体积小，无依赖，适合移动端。',
			descEn: 'Small size, no deps, for mobile.',
			icon: '/assets/images/home/t.jpeg',
			icon_d: '/assets/images/home/t-d.png',
			shwTip: true
		},
		{
			title: 'Design',
			titleZh: '设计',
			desc: '优化移动端设计交互，支持主题配置。',
			descEn: 'Better mobile design & themes.',
			icon: '/assets/images/home/d.jpeg',
			icon_d: '/assets/images/home/d-d.png',
			shwTip: false
		},
		{
			title: 'Fast',
			titleZh: '快速',
			desc: '配套脚手架，无虚拟 DOM，性能卓越。',
			descEn: 'With CLI, no vDOM, high performance.',
			icon: '/assets/images/home/f.jpeg',
			icon_d: '/assets/images/home/f.jpeg',
			shwTip: false
		}
	];
	const dominant = {
		title: '优势 & 目标',
		title_en: 'Advantages & Goals',
		data: [
			{
				icon: 'svelte',
				p: '丰富 Svelte 生态，为开发者提供高效、优质的组件库。',
				p_en: 'Enrich the Svelte ecosystem by providing efficient, high-quality component library.'
			},
			{
				icon: 'css3-line',
				p: '简化 CSS 开发流程，让开发者专注业务逻辑实现。',
				p_en: 'Streamline CSS development so developers can focus on business logic implementation.'
			},
			{
				icon: 'contrast-2-line',
				p: '内置暗黑模式与主题系统，轻松构建现代化界面。',
				p_en: 'Built-in dark mode and theming system for easily creating modern interfaces.'
			},
			{
				icon: 'paint-brush-line',
				p: '面向移动端的通用组件库，提供灵活的 UI 定制能力。',
				p_en: 'A versatile mobile component library with flexible UI customization capabilities.'
			},
			{
				icon: 'clockwise-line',
				p: '精心设计的交互体验，流畅的动画过渡，带来极致用户体验。',
				p_en: 'Carefully crafted interactions with smooth animations for ultimate user experience.'
			},
			{
				icon: 'article-line',
				p: '完整的中英文支持，文档、示例和注释清晰完整。',
				p_en: 'Full Chinese and English support with clear documentation, examples and comments.'
			},
			{
				icon: 'file-copy-2-line',
				p: '提供完善的脚手架和插件，助力开发者高效开发。',
				p_en: 'Provides comprehensive scaffolding and plugins for efficient development.'
			},
			{
				icon: 'planet-line',
				p: '强大的国际化支持，内置 60+ 语言包，快速实现多语言应用。',
				p_en: 'Powerful i18n with 60+ built-in language packs for quick multilingual implementation.'
			}
		]
	};
	const ugly = {
		title: '提前警告',
		title_en: 'Early Warning',
		data: [
			{
				icon: 'medal-line',
				p: 'STDF 不追求高大上的概念，只专注于为您提供简单实用的开发工具。',
				p_en: 'STDF focuses solely on providing practical development tools, without any fancy concepts.'
			},
			{
				icon: 'service-line',
				p: 'Svelte 生态仍在发展中，欢迎您加入我们一起建设更好的 Svelte 社区。',
				p_en: 'The Svelte ecosystem is still growing. We welcome you to join us in building a better Svelte community.'
			},
			{
				icon: 'bard-line',
				p: 'STDF 可能使用到 Vite、SvelteKit 等生态，建议先了解这些项目的核心概念。',
				p_en: 'STDF may use Vite, SvelteKit, etc. We recommend understanding their core concepts first.'
			},
			{
				icon: 'git-close-pull-request-line',
				p: 'STDF 支持 UnoCSS 等 Tailwind CSS 类库，使用前请先掌握相关基础知识。',
				p_en: 'STDF supports Tailwind CSS-like libraries such as UnoCSS. Please master the basics before using them.'
			}
		]
	};

	// 赞助人员
	const thinkGithub = [
		{ name: 'sbscan', amount: 100 },
		{ name: 'MuGuiLin', amount: 50 },
		{ name: 'yuedanlabs', amount: 10 }
	];

	const bottomInfo = [
		{
			title: '相关',
			title_en: 'Related',
			list: [
				{ title: 'Svelte', title_en: 'Svelte', link: 'https://svelte.dev', _blank: true },
				{ title: 'Tailwind', title_en: 'Tailwind', link: 'https://tailwindcss.com', _blank: true },
				{ title: 'Remix Icon', title_en: 'Remix Icon', link: 'https://remixicon.com', _blank: true }
				// { title: 'RTDF(计划中)', title_en: 'RTDF(intend)', link: '', _blank: false },
				// { title: 'VTDF(计划中)', title_en: 'VTDF(intend)', link: '', _blank: false },
			]
		},
		{
			title: '工具',
			title_en: 'Tools',
			list: [
				{ title: 'create-stdf', title_en: 'create-stdf', link: 'https://www.npmjs.com/package/create-stdf', _blank: true },
				{
					title: 'rollup-plugin-stdf-icon',
					title_en: 'rollup-plugin-stdf-icon',
					link: 'https://www.npmjs.com/package/rollup-plugin-stdf-icon',
					_blank: true
				},
				{
					title: 'rollup-plugin-md-ts',
					title_en: 'rollup-plugin-md-ts',
					link: 'https://www.npmjs.com/package/rollup-plugin-md-ts',
					_blank: true
				},
				{
					title: 'STDF for VS Code',
					title_en: 'STDF for VS Code',
					link: 'https://marketplace.visualstudio.com/items?itemName=STDF.stdf-vscode-extension',
					_blank: true
				}
			]
		},
		{
			title: '帮助',
			title_en: 'Help',
			list: [
				{ title: '关于', title_en: 'About', link: '/guide/about', _blank: false },
				{ title: '常见问题', title_en: 'FAQ', link: '/guide/faq', _blank: false },
				{ title: '更新日志', title_en: 'Changelog', link: '/guide/changelog', _blank: false },
				{ title: '开源许可', title_en: 'License', link: 'https://github.com/any-tdf/stdf/blob/main/LICENSE', _blank: true }
			]
		},
		{
			title: '社区',
			title_en: 'Community',
			list: [
				{
					title: 'QQ 群',
					title_en: 'QQ Group',
					link: 'https://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=U8ZlXJ3KVpTI9oZzs1jBnyWc3gVA0h6Y&authKey=ScWu0nU9g8BqNsC7o2eYkESwgVDVz9vzGNZEb17MrEAay9%2F7bTkXDiLJRIzo2vrg&noverify=0&group_code=581073686',
					_blank: true
				},
				{ title: 'Discord', title_en: 'Discord', link: 'https://discord.gg/DMkHu8GGre', _blank: true },
				{ title: 'QQ 频道', title_en: 'QQ Discord', link: 'https://pd.qq.com/s/fdd8incyr', _blank: true },
				{ title: 'Discussions', title_en: 'Discussions', link: 'https://github.com/any-tdf/stdf/discussions', _blank: true }
			]
		}
	];
	let showQr = $state(false);

	const io = new IntersectionObserver((entries: IntersectionObserverEntry[]) => {
		for (const item of entries) {
			// isIntersecting 是一个 Boolean 值，判断目标元素当前是否可见
			if (item.isIntersecting) {
				const target = item.target as HTMLElement;
				target.style.opacity = '1';
				target.style.transform = 'translateY(0)';
				setTimeout(() => {
					target.style.transitionDuration = '300ms';
				}, 1000);
			} else {
				// item.target.style.opacity = 0;
				// item.target.style.transform = 'translateY(200px)';
			}
		}
	});
	let A_a1Svg = $state();
	const mouseenterFun = () => {
		/**
		 * A_a1
		 * @param {Object} qrcode
		 * @param {Object} options
		 * @param {String} [options.type]  连线方向 0=>左右 1=>上下 2=>纵横 3=>回环 4=>左上—右下 5=>右上—左下 6=>交叉"
		 * @param {String} [options.size] 连线粗细
		 * @param {String} [options.opacity] 连线不透明度
		 * @param {String} [options.posType] 定位点样式  0=>矩形 1=>圆形 2=>行星 3=>圆角矩形
		 * @param {String} [options.otherColor] 连线颜色
		 * @param {String} [options.posColor] 定位点颜色
		 */
		const qrcode = encodeData({
			text: `HTTPS://DEMO.STDF.DESIGN?lang=${isZh ? 'zh_CN' : 'en_US'}`,
			isSpace: false
		});
		const color = $currentThemeStore === 'dark' ? 'var(--color-dark)' : 'var(--color-primary)';
		A_a1Svg = rendererLine(qrcode, { posType: 2, otherColor: color, posColor: color });
		showQr = true;
	};

	let showConfetti = $state(false);
	onMount(() => {
		const intersectionList = document.querySelectorAll('.intersection');
		for (const item of intersectionList) {
			// 开始时 opacity 为 0，不可见，transform 为 translateY(200px)
			const target = item as HTMLElement;
			target.style.opacity = '0';
			target.style.transform = 'translateY(200px)';
			target.style.transitionDuration = '1s';
			io.observe(item);
		}
	});
</script>

<!-- <div style="width: 100%; height: 100vh; background: #f0f0f0"> -->
<!-- </div> -->

<div class="mx-auto max-w-[1536px]">
	<div class="justify-center lg:flex">
		<div class="flex basis-2/5 flex-col justify-center py-16 text-center md:py-20">
			<div class="relative mb-20 mt-16 flex h-20 flex-col items-center justify-center md:h-28">
				<div class="animate-dynamicsBg absolute rounded-full opacity-50 blur-xl md:opacity-100 md:blur-3xl">
					<svg viewBox="0 0 100 100">
						<path
							fill-rule="evenodd"
							clip-rule="evenodd"
							d="M50 0V100C22.3858 100 0 77.6142 0 50C0 22.3858 22.3858 0 50 0Z"
							class="fill-dark"
						/>
						<path
							fill-rule="evenodd"
							clip-rule="evenodd"
							d="M50 100V0C77.6142 0 100 22.3858 100 50C100 77.6142 77.6142 100 50 100Z"
							class="fill-primary"
						/>
						<circle cx="50" cy="25" r="25" class="fill-primary" />
						<circle cx="50" cy="75" r="25" class="fill-dark" />
						<circle cx="50.25" cy="25.25" r="6.25" class="fill-dark" />
						<circle cx="50.25" cy="75.25" r="6.25" class="fill-primary" />
					</svg>
				</div>
				<div
					class="absolute h-full w-28 md:w-36"
					style="filter: drop-shadow(0 10px 8px rgb(0 0 0 / 0.05)) drop-shadow(0 4px 3px rgb(0 0 0 / 0.1));"
				>
					<svg viewBox="0 0 90 80" class="group">
						<path
							class="fill-primary dark:fill-dark"
							d="M0 0H20H40H50C64.8056 0 77.7325 8.04398 84.6487 20H50H40V22.6757V30H50C55.5229 30 60 34.4771 60 40C60 45.5229 55.5229 50 50 50H40V57.3243V78.7398V80H20V66.4583V20H15.3513H0V0ZM50 80C72.0914 80 90 62.0914 90 40C90 36.547 89.5625 33.1962 88.7398 30H67.3244C69.0261 32.9417 70 36.3571 70 40C70 51.0457 61.0457 60 50 60V80Z"
						/>
						<path
							style="stroke-dasharray: 400;stroke-dashoffset: 400;"
							class="fill-dark stroke-dark text-dark group-hover:animate-path dark:fill-primary dark:stroke-primary dark:text-primary stroke-1"
							d="M20 30V0L0 50H20V80L40 30H20Z"
						/>
					</svg>
				</div>
			</div>
			<div class="text-6xl md:text-8xl">STDF</div>
			<div class="md:text-md mb-10 mt-4 px-4 text-gray-700 md:mb-0 dark:text-gray-300">
				{#if isZh}
					基于
					<a
						href="https://svelte.dev"
						class="decoration-svelte hover:text-svelte underline underline-offset-2 transition-all"
						target="_blank"
						title={isZh ? '打开 Svelte 官方站点' : 'Open Svelte official website'}
					>
						Svelte
					</a>
					与
					<a
						href="https://tailwindcss.com/"
						class="decoration-tailwind hover:text-tailwind underline underline-offset-2 transition-all"
						target="_blank"
						title={isZh ? '打开 Tailwind CSS 官方站点' : 'Open Tailwind CSS official website'}
					>
						Tailwind
					</a>
					的移动 web 组件库
				{:else}
					Mobile web component
					<br class="md:hidden" />
					library based on
					<a
						href="https://svelte.dev"
						class="decoration-svelte hover:text-svelte underline underline-offset-2 transition-all"
						target="_blank"
					>
						Svelte
					</a>
					and
					<a
						href="https://tailwindcss.com/"
						class="decoration-tailwind hover:text-tailwind underline underline-offset-2 transition-all"
						target="_blank"
					>
						Tailwind
					</a>
				{/if}
			</div>
			<div class="mb-16 mt-8 flex justify-center gap-8 md:mt-16">
				<a
					href="/guide"
					onmouseenter={() => (showConfetti = true)}
					onmouseleave={() => (showConfetti = false)}
					class="bg-primary hover:bg-primary/80 dark:bg-dark hover:dark:bg-dark/80 group relative rounded-sm px-6 py-2 text-white transition-all dark:text-black"
				>
					<div class="group flex items-center gap-2">
						{isZh ? '开始使用' : 'Get Started'}
						<div class="size-3 translate-y-px">
							<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
								<rect
									x="6"
									y="14"
									width="10"
									height="2"
									fill="currentColor"
									class="scale-x-135 -translate-x-2 -translate-y-2 transition-all duration-500 group-hover:translate-x-0 group-hover:translate-y-0"
								/>
								<path
									d="M8.48535 7.07129L1.41406 14.1426L0 12.7275L5.65625 7.07031L0 1.41406L1.41406 0L8.48535 7.07129Z"
									fill="currentColor"
									class="translate-x-2 transition-all duration-500 group-hover:translate-x-0"
								/>
							</svg>
						</div>
						{#if showConfetti}
							<span class="absolute left-1/2 top-0">
								<Confetti rounded />
							</span>
						{/if}
					</div>
				</a>
				<a
					href={`https://demo.stdf.design?lang=${isZh ? 'zh_CN' : 'en_US'}`}
					target="_blank"
					onmouseleave={() => (showQr = false)}
					onmouseenter={mouseenterFun}
					class="border-primary dark:border-dark relative hidden rounded-sm border border-solid px-6 py-2 transition-all md:block"
				>
					{isZh ? '示例' : 'Demo'}
					{#if showQr}
						<div
							transition:fly={{ duration: 300, x: -10, opacity: 0 }}
							class="z-100 absolute left-full top-0 block w-44 -translate-y-1/3 translate-x-1 rounded-lg border border-black/5 p-2 shadow-lg dark:hidden"
						>
							<span>{@html A_a1Svg}</span>
						</div>
						<div
							transition:fly={{ duration: 300, x: -10, opacity: 0 }}
							class="z-100 absolute left-full top-0 hidden w-44 -translate-y-1/3 translate-x-1 rounded-lg border bg-black p-2 shadow-lg shadow-white/10 dark:block dark:border-white/10"
						>
							<span>{@html A_a1Svg}</span>
						</div>
					{/if}
				</a>
				<a
					href={'https://demo.stdf.design?lang=' + (isZh ? 'zh_CN' : 'en_US')}
					target="_blank"
					class="border-primary dark:border-dark block rounded-sm border border-solid px-6 py-2 transition-all md:hidden"
				>
					{isZh ? '示例' : 'Demo'}
				</a>
			</div>
			<Clis />
		</div>
		<div class="relative mt-10 hidden basis-3/5 xl:mt-0 xl:block">
			<div class="animate-elementUpDownMove1 -translate-x-18 absolute inset-1/2 size-20 -translate-y-12">
				{#if avatar}
					<Avatar size="md" radius={avatarRadius} image={avatar} injClass="shadow-lg dark:shadow-white/10" />
				{:else}
					<Avatar size="md" radius={avatarRadius} injClass="shadow-lg dark:shadow-white/10" />
				{/if}
			</div>
			<div class="animate-elementUpDownMove1 absolute inset-1/2 -translate-x-96 -translate-y-40">
				<Loading type={randomNumStr} theme />
			</div>
			<div class="animate-elementUpDownMove3 absolute inset-1/2 -translate-y-48 translate-x-52">
				<Switch radius={switchRadius} inside={switchInside} active />
			</div>
			<div class="animate-elementUpDownMove6 -translate-y-42 absolute inset-1/2 w-96 -translate-x-72">
				<Tab {labels} radius={tabRadius} {lineType} />
			</div>
			<div
				class="animate-elementUpDownMove5 w-84 absolute inset-1/2 h-24 translate-x-20 translate-y-6 rounded-lg bg-white px-2 shadow-lg dark:bg-black/80 dark:shadow-white/10"
			>
				<Input
					title={inputTitle}
					value={inputValue}
					{inputStyle}
					placeholder={isZh ? `请输入${inputTitle}` : `Input ${inputTitle}`}
					radius={inputRadius}
					lineTransition="left"
					clear
					onchange={inputFun}
				/>
				<span class="absolute left-0 top-1/2 {showInputConfetti ? 'block' : 'hidden'}">
					<Confetti infinite rounded x={[-0.5, 0.5]} y={[-0.5, 0.5]} />
				</span>
			</div>
			<div class="animate-elementUpDownMove6 absolute inset-1/2 w-96 translate-x-2 translate-y-48">
				<Pagination
					total={paginationTotal}
					type={paginationType}
					current={paginationCurrent}
					radius={paginationRadius}
					injClass="{injPaginationRadius} shadow-lg dark:shadow-white/10"
				/>
			</div>
			<div class="animate-elementUpDownMove4 absolute inset-1/2 w-64 -translate-x-80 -translate-y-8">
				{#if emoji === 'default'}
					<Rate />
				{:else}
					<Rate half opacity="0.2" value={3.5}>
						{#if emoji === 'love'}
							<Icon name="ri-heart-3-fill" injClass="text-[red]" />
						{:else}
							<div class="text-xl">{emoji}</div>
						{/if}
					</Rate>
				{/if}
			</div>
			<div
				class="animate-elementUpDownMove3 h-15 absolute inset-1/2 w-96 -translate-x-96 -translate-y-72 rounded-lg bg-white p-3 shadow-lg dark:bg-black/80 dark:shadow-white/10"
			>
				<NoticeBar vertical {textList}></NoticeBar>
			</div>
			<div class="animate-elementUpDownMove1 absolute inset-1/2 w-64 -translate-y-20 translate-x-32">
				<Slider value={sliderValue} showTip={sliderShowTip} radius={sliderRadius} />
			</div>
			<div class="animate-elementUpDownMove5 h-54 -translate-x-110 absolute inset-1/2 w-[390px] translate-y-16 overflow-hidden">
				<Swiper {...swiperOption} />
			</div>
			<div class="animate-elementUpDownMove1 -translate-y-74 group absolute inset-1/2 w-64 translate-x-32">
				<Button heightIn="2" onclick={randomThemeFunc}>
					<span class="transition-all duration-500 group-hover:translate-x-1">
						{themes.find((item) => item.name === $currentColorStore)?.[isZh ? 'name_CN' : 'name']}
					</span>
					<span
						class="ml-1 size-4 -translate-x-4 text-white opacity-0 transition-all delay-100 duration-500 group-hover:translate-x-0 group-hover:opacity-100 dark:text-black"
					>
						<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
							<path
								d="M1.99974 13.0001L1.9996 11.0002L18.1715 11.0002L14.2218 7.05044L15.636 5.63623L22 12.0002L15.636 18.3642L14.2218 16.9499L18.1716 13.0002L1.99974 13.0001Z"
							></path>
						</svg>
					</span>
				</Button>
			</div>
		</div>
	</div>
	<div class="mt-16 flex flex-wrap justify-around gap-12 px-8 xl:flex-nowrap">
		{#each descList as desc}
			<div
				class="intersection shadow-primary/10 dark:shadow-dark/20 group flex w-full flex-col space-y-5 overflow-hidden rounded-2xl shadow-xl transition-all duration-300 sm:w-2/3 md:w-80 lg:w-96"
			>
				<div class="relative w-full">
					<img
						class="aspect-5/3 block h-full w-full object-cover transition-all duration-500 group-hover:scale-125 dark:hidden"
						src={desc.icon}
						alt=""
					/>
					<img
						class="aspect-5/3 hidden h-full w-full object-cover transition-all duration-500 group-hover:scale-125 dark:block"
						src={desc.icon_d}
						alt=""
					/>
					<div
						class="text-shadow-lg bg-primary/10 dark:bg-dark/10 absolute bottom-1.5 left-0 right-0 mx-1.5 flex flex-col justify-center rounded-2xl border border-white/30 px-3 py-1.5 text-white backdrop-blur-sm"
					>
						<div class="mb-0.5 text-3xl font-bold transition-all duration-500 group-hover:translate-x-4">{desc.title}</div>
						<div class="text-xs font-bold transition-all duration-500">
							{isZh ? desc.desc : desc.descEn}
						</div>
					</div>
				</div>
			</div>
		{/each}
	</div>

	<div class="px-4 pb-10 md:px-12 md:pb-20" class:text-left={!isZh}>
		<div class="mt-40">
			<div class="intersection my-10 text-center text-2xl font-bold md:my-20 md:text-4xl">
				{isZh ? dominant.title : dominant.title_en}
			</div>
			<div class="grid grid-cols-1 gap-10 md:grid-cols-4">
				{#each dominant.data as item}
					<div
						class="intersection shadow-primary/10 dark:shadow-dark/10 border-primary/10 dark:border-dark/10 group rounded-xl border p-4 shadow-lg"
					>
						<div class="text-primary dark:text-dark size-6 transition-all duration-300 group-hover:scale-110">
							<svg class="fill-current" viewBox="0 0 24 24">
								<use xlink:href="/assets/fonts/home.symbol.svg#{item.icon}" />
							</svg>
						</div>
						<p class="mt-4 text-sm opacity-90">{isZh ? item.p : item.p_en}</p>
					</div>
				{/each}
			</div>
		</div>
		<div class="mt-32 md:mt-48">
			<div class="intersection my-10 text-center text-2xl font-bold md:my-20 md:text-4xl">
				{isZh ? ugly.title : ugly.title_en}
			</div>
			<div class="grid grid-cols-1 gap-10 md:grid-cols-4">
				{#each ugly.data as item}
					<div
						class="intersection shadow-primary/10 dark:shadow-dark/10 border-primary/10 dark:border-dark/10 group rounded-xl border p-4 shadow-lg"
					>
						<div class="text-primary dark:text-dark size-6 transition-all duration-300 group-hover:scale-110">
							<svg class="fill-current" viewBox="0 0 24 24">
								<use xlink:href="/assets/fonts/home.symbol.svg#{item.icon}" />
							</svg>
						</div>
						<p class="mt-4 text-sm opacity-90">{isZh ? item.p : item.p_en}</p>
					</div>
				{/each}
			</div>
		</div>
	</div>

	<!-- <div class="hidden md:flex justify-center mb-20">
    <article class={`prose dark:prose-invert max-w-none text-xs overflow-auto`} style="height:{500}px">
        <pre><code class="hljs">{@html highlightedCode}</code></pre>
    </article>
    <div class=" ml-2 border border-black/10 dark:border-gray-400 w-[392px] grow-0 shrink-0 overflow-auto" style="height:{500}px">
        <img src="/assets/images/home/zh/9.png" alt="" class='w-full' />
    </div>
</div> -->

	<div class="px-4 pb-10 text-center md:px-12 md:pb-20">
		<div class="intersection my-5 text-2xl font-bold transition-all ease-out md:my-10 md:text-4xl">
			🎖 {isZh ? '贡献者' : 'Contributors'}
		</div>
		<div class="intersection flex justify-center">
			<a href="https://github.com/any-tdf/stdf/graphs/contributors" target="_blank">
				<img src="https://contrib.nn.ci/api?repo=any-tdf/stdf&cols=7" title={isZh ? '贡献者' : 'Contributors'} alt="" />
			</a>
		</div>
	</div>

	<!-- 赞助者 -->
	<div class="px-4 pb-20 text-center md:px-12 md:pb-40">
		<div class="intersection my-5 text-2xl font-bold transition-all ease-out md:my-10 md:text-4xl">
			🙏 {isZh ? '赞助者' : 'Sponsors'}
		</div>
		<div class="">
			<div class="intersection mb-4">GitHub</div>
			<div class="flex flex-wrap justify-center gap-4">
				{#each thinkGithub as item}
					<a class="intersection" href={'https://github.com/' + item.name} target="_blank">
						<img
							class="h-16 w-16 overflow-hidden rounded-full"
							src={'https://avatars.githubusercontent.com/' + item.name}
							title={(isZh ? '感谢 ' : 'Thanks ') + item.name}
							alt=""
						/>
					</a>
				{/each}
			</div>
		</div>
	</div>
</div>
<div class="bg-gray-100 dark:bg-gray-950">
	<div class="mx-auto grid max-w-[1536px] grid-cols-2 gap-10 px-6 py-10 md:grid-cols-4 md:px-20">
		{#each bottomInfo as item}
			<div>
				<div class="mb-2 text-lg font-bold">{isZh ? item.title : item.title_en}</div>
				<div class="flex flex-col gap-2">
					{#each item.list as i}
						<a href={i.link} target={i._blank ? '_blank' : '_self'} title={i.link} class="text-sm hover:underline">
							{isZh ? i.title : i.title_en}
						</a>
					{/each}
				</div>
			</div>
		{/each}
	</div>
</div>

<div class="py-4 text-center text-xs">
	<div class="flex justify-center gap-1">
		<div>STDF DESIGN • MADE BY DUFU</div>
		<div>
			{#if isZh}
				• <a href="https://beian.miit.gov.cn" target="_blank">滇 ICP 备 17004037 号 -4</a>
			{/if}
		</div>
	</div>
</div>



================================================
FILE: docs/site/src/routes/components/+page.svelte
================================================
<script lang="ts">
	import { onMount } from 'svelte';
	import { fly } from 'svelte/transition';
	import { isShowNavStore, isCmdKStore, isWideScreenStore, currentColorStore, currentThemeStore } from '../../store';
	import { menuList, type MenuList } from '../../data/menuList';
	import { page } from '$app/stores';
	import hljs from 'highlight.js';
	import type { MenuListChild } from '../../data/menuList.js';
	import Menu from '$lib/menu/Menu.svelte';
	import Tab from '$lib/tab/Tab.svelte';
	import { goto } from '$app/navigation';

	import Component from './Component.svelte';
	import Guide from './Guide.svelte';
	import Api from './Api.svelte';
	import FAQ from './FAQ.svelte';
	import Version from './Version.svelte';

	let loading = $state(true);

	const isZh = localStorage.getItem('lang') === 'zh_CN';

	const params = $page.url.searchParams;

	//数组二级组成新数组
	const ArrChildFun = (arr: MenuList[]) => {
		let newArr = [];
		for (let e = 0; e < arr.length; e++) {
			newArr.push(...arr[e].childs);
		}
		return newArr;
	};
	let menuChildList = $derived(ArrChildFun(menuList));
	let currentNav = $state<MenuListChild | null>(null);
	let currentTab = $state(0);
	let titleDom: HTMLElement | null = $state(null);
	let demoHeight = $state(0);
	let highlightedCode = $state('');
	let titleWidth = $state(0);
	let visible = $state(true);
	let isShowIframe = $state(true);
	let navBarHeight = $state(0);
	let menuChange = $state(true);

	// 动态导入组件字符串
	const getComponentStrFunc = async (name: string) => {
		const rawObj = await import(`../../../../../packages/stdf/src/routes/${name}/${isZh ? 'zh_CN' : 'en_US'}/+page.svelte?raw`);
		// 将 componentStr 中所有的 from '$lib/index.js' 替换为 from 'stdf'
		// 将 componentStr 中所有的 from '$lib/types/index.js' 替换为 from 'stdf/types'
		return rawObj.default
			.replace(/from ['"]\$lib\/index\.js['"]/g, "from 'stdf'")
			.replace(/from ['"]\$lib\/types\/index\.js['"]/g, "from 'stdf/types'");
	};
	const getDemoHeightFun = () => {
		if (titleDom) {
			demoHeight = document.documentElement.clientHeight - 70 - titleDom.offsetHeight - 100;
			navBarHeight = document.documentElement.clientHeight - 56;
		}
	};
	const initFn = async () => {
		if (params.get('tab')) {
			currentTab = Number(params.get('tab'));
		}
		if (params.get('nav')) {
			currentNav = menuChildList.filter((item) => item.nav === params.get('nav'))[0];
		} else {
			currentNav = menuList[0].childs[1];
		}
		loading = true;

		const componentStr = await getComponentStrFunc(currentNav.nav);
		loading = false;
		highlightedCode = hljs.highlight(componentStr, {
			language: 'svelte',
			ignoreIllegals: true
		}).value;
	};
	onMount(() => {
		if (titleDom) {
			demoHeight = document.documentElement.clientHeight - 70 - titleDom.offsetHeight - 100;
			navBarHeight = document.documentElement.clientHeight - 56;
		}
		window.addEventListener('resize', getDemoHeightFun);
		initFn();
		return () => {
			window.removeEventListener('resize', getDemoHeightFun);
		};
	});

	//监听箭头按键，方便键盘操作
	const handleKeydown = (event: KeyboardEvent) => {
		if ($isCmdKStore) {
			return;
		}
		//左右箭头切换 Tab
		if (event.code === 'ArrowLeft') {
			if (currentTab > 0) {
				isShowIframe = false;
				setTimeout(() => {
					isShowIframe = true;
				}, 10);
				currentTab--;
				params.set('tab', currentTab.toString());
				goto(`/components?nav=${params.get('nav') ? params.get('nav') : 'button'}&tab=${currentTab}`);
			}
		}
		if (event.code === 'ArrowRight') {
			if (currentTab < 4) {
				isShowIframe = false;
				setTimeout(() => {
					isShowIframe = true;
				}, 10);
				currentTab++;
				params.set('tab', currentTab.toString());
				goto(`/components?nav=${params.get('nav') ? params.get('nav') : 'button'}&tab=${currentTab}`);
			}
		}
		//上下箭头切换组件
		if (event.code === 'ArrowUp') {
			let currentMenuIndex = menuChildList.findIndex((item) => item.nav === currentNav?.nav);
			if (currentMenuIndex > 0) {
				visible = false;
				menuChange = false;
				setTimeout(async () => {
					visible = true;
					currentNav = menuChildList[currentMenuIndex - 1];
					params.set('nav', currentNav.nav);
					goto(`/components?nav=${currentNav.nav}&tab=${currentTab}`);
					const componentStr = await getComponentStrFunc(currentNav.nav);
					highlightedCode = hljs.highlight(componentStr, {
						language: 'svelte',
						ignoreIllegals: true
					}).value;
					menuChange = true;
				}, 10);
			}
		}
		if (event.code === 'ArrowDown') {
			let currentMenuIndex = menuChildList.findIndex((item) => item.nav === currentNav?.nav);
			if (currentMenuIndex < menuChildList.length - 1) {
				visible = false;
				setTimeout(async () => {
					visible = true;
					menuChange = false;
					currentNav = menuChildList[currentMenuIndex + 1];
					params.set('nav', currentNav.nav);
					goto(`/components?nav=${currentNav.nav}&tab=${currentTab}`);
					const componentStr = await getComponentStrFunc(currentNav.nav);
					highlightedCode = hljs.highlight(componentStr, {
						language: 'svelte',
						ignoreIllegals: true
					}).value;
					menuChange = true;
				}, 10);
			}
		}
	};
	const menuClickFun = (currentMenu: MenuListChild) => {
		$isShowNavStore && ($isShowNavStore = false);
		visible = false;
		menuChange = false;
		setTimeout(async () => {
			visible = true;
			currentNav = currentMenu;
			params.set('nav', currentMenu.nav);
			goto(`/components?nav=${currentMenu.nav}&tab=${params.get('tab') ? params.get('tab') : '0'}`);
			const componentStr = await getComponentStrFunc(currentMenu.nav);
			highlightedCode = hljs.highlight(componentStr, { language: 'svelte', ignoreIllegals: true }).value;
			menuChange = true;
		}, 10);
	};

	const tabClickFun = (i: number) => {
		isShowIframe = false;
		setTimeout(() => {
			isShowIframe = true;
		}, 10);
		currentTab = i;
		params.set('tab', currentTab.toString());
		goto(`/components?nav=${params.get('nav') ? params.get('nav') : 'button'}&tab=${currentTab}`);
	};
	let QRValue = $derived(
		(import.meta.env.DEV ? location.protocol + '//' + location.hostname + ':8888/' : 'https://demo.stdf.design/') +
			currentNav?.nav +
			(isZh ? '/zh_CN' : '/en_US')
	);
</script>

<svelte:window onkeydown={handleKeydown} />

<div class="flex">
	<div
		class="fixed -left-52 top-14 z-[100] w-52 overflow-y-scroll border-black/10 bg-white transition-all duration-300 md:left-0 md:bg-transparent dark:border-white/20 dark:bg-black dark:md:bg-transparent"
		class:left-0={$isShowNavStore}
		class:-left-52={!$isShowNavStore}
		style="height:{navBarHeight + 'px'}"
	>
		<Menu {menuList} currentNav={currentNav?.nav} onclickMenu={menuClickFun} />
	</div>
	{#if visible}
		<div
			class="mx-auto flex w-full flex-col md:pl-48 {$isWideScreenStore ? 'max-w-full' : 'max-w-[1472px]'}"
			in:fly={{ x: 100, duration: 500 }}
			out:fly={{ x: 100, duration: 100 }}
		>
			<div class="relative z-20 px-4 pt-4 md:flex md:space-x-4 md:px-8" bind:this={titleDom}>
				{#if loading}
					{isZh ? '请等待...' : 'Please wait...'}
				{:else}
					<div class="flex items-center text-2xl font-bold md:text-4xl">
						<div>
							{isZh ? currentNav?.title : currentNav?.title_en}
						</div>
						<a href={QRValue} target="_blank" aria-label={isZh ? '扫码预览' : 'Scan to preview'}>
							<div class="ml-2 h-8 w-8 rounded-sm bg-gray-100 p-1 text-gray-500 md:hidden dark:bg-gray-700">
								<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style="fill: currentColor">
									<path fill="none" d="M0 0h24v24H0z" />
									<path
										d="M13 21v2h-2v-2H3a1 1 0 0 1-1-1V6h20v14a1 1 0 0 1-1 1h-8zm-9-2h16V8H4v11zm9-9h5v2h-5v-2zm0 4h5v2h-5v-2zm-4-4v3h3a3 3 0 1 1-3-3zM2 3h20v2H2V3z"
									/>
								</svg>
							</div>
						</a>
					</div>
					<div class="mt-4 text-xs text-gray-500 md:text-sm">
						{isZh ? currentNav?.tip : currentNav?.tip_en}
					</div>
				{/if}
			</div>
			<div class="relative z-10 -mt-14 p-4 md:px-8 md:py-4" bind:clientWidth={titleWidth}>
				<Tab {currentTab} onclickTab={tabClickFun} />
			</div>
			<div class="my-4 ml-4">
				<!-- <div class="h-px bg-black/10 dark:bg-white/20"></div> -->
			</div>
			<div>
				<!-- 示例 -->
				{#if currentTab === 0}
					<div
						in:fly={{ y: 100, duration: 500 }}
						out:fly={{ y: 100, duration: 100 }}
						class="mt-2 flex flex-1 justify-around py-4 md:pl-8 md:pr-4"
						style="width:{titleWidth}px;"
					>
						<div class="bg-codeLight dark:bg-codeDark grow overflow-y-scroll rounded-sm" style="height:{demoHeight}px;">
							<Component {highlightedCode} />
						</div>
						<div
							class="ml-2 hidden w-[392px] shrink-0 grow-0 border border-black/10 md:block dark:border-white/10"
							style="height:{demoHeight}px"
						>
							{#if currentNav?.nav}
								{#if isShowIframe}
									<iframe
										title="Demo"
										id="iframe-id"
										src={import.meta.env.DEV
											? `http://localhost:8888/${currentNav?.nav}/${isZh ? 'zh_CN' : 'en_US'}?channel=iframe&theme=${$currentColorStore}&darkMode=${$currentThemeStore}&lang=${localStorage.getItem('lang')}`
											: `https://demo.stdf.design/${currentNav?.nav}/${isZh ? 'zh_CN' : 'en_US'}?channel=iframe&theme=${$currentColorStore}&darkMode=${$currentThemeStore}&lang=${localStorage.getItem('lang')}`}
										height={demoHeight - 2}
										width="390"
									></iframe>
								{:else}
									<div class="text-primary dark:text-dark flex flex-col justify-center" style="width:390px;height:{demoHeight - 2}px;">
										<div>
											<svg class="mx-auto my-1 h-10 w-10 animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
												<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" />
												<path
													class="opacity-75"
													fill="currentColor"
													d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
												/>
											</svg>
										</div>
									</div>
								{/if}
							{/if}
						</div>
					</div>
				{/if}
				{#if currentTab === 1}
					<!-- api -->
					{#if menuChange}
						<div class={` left-full mt-4 flex-1 p-4 md:px-8 md:py-4`} style="width:{titleWidth}px;">
							<Api api={currentNav?.nav} />
						</div>
					{/if}
				{/if}
				{#if currentTab === 2}
					<!-- 指南 -->
					{#if menuChange}
						<div class="mx-auto mt-4 flex-1 rounded-sm p-4 md:px-8 md:py-4" style="width:{titleWidth}px;">
							<Guide guide={currentNav?.nav} />
						</div>
					{/if}
				{/if}
				{#if currentTab === 3}
					<!-- FAQ -->
					{#if menuChange}
						<div class={`mt-4 flex-1 rounded-sm p-4 md:px-8 md:py-4 `} style="width:{titleWidth}px;">
							<FAQ guide={currentNav?.nav} />
						</div>
					{/if}
				{/if}
				{#if currentTab === 4}
					<!-- Version -->
					{#if menuChange}
						<div class={`mt-4 flex-1 rounded-sm p-4 md:px-8 md:py-4 `} style="width:{titleWidth}px;">
							<Version guide={currentNav?.nav} />
						</div>
					{/if}
				{/if}
			</div>
		</div>
	{/if}
</div>



================================================
FILE: docs/site/src/routes/components/Api.svelte
================================================
<script lang="ts">
	import { onMount } from 'svelte';
	import { mdTextToHljs } from './../../utils/index';

	interface Props {
		api?: string;
	}

	let { api = 'button' }: Props = $props();
	const isZh = localStorage.getItem('lang') === 'zh_CN';

	let loading = $state(true);
	const getMdStrFunc = async (nav: string) => {
		loading = true;
		const rawObj = await import(`../../../../mds/components/${nav}/api${isZh ? '' : '_en'}.md`);
		const mdStr = rawObj.default;
		loading = false;
		return mdTextToHljs(mdStr.replace(/<a href="/g, '<a target="_blank" href="'), 'javascript');
	};
	let apiText: string | null = $state(null);
	onMount(async () => {
		apiText = await getMdStrFunc(api);
	});
</script>

<article
	class="prose dark:prose-invert prose-table:break-all prose-td:whitespace-nowrap md:prose-td:whitespace-normal max-w-none overflow-x-auto pb-12"
>
	{#if loading}
		{isZh ? '请等待...' : 'Please wait...'}
	{:else}
		{@html apiText}
	{/if}
</article>
<div class="flex gap-2 pb-8 text-xs">
	<a
		href={'https://github.com/any-tdf/stdf/edit/main/docs/mds/components/' + api + '/api' + (isZh ? '' : '_en') + '.md'}
		target="_blank"
		class="text-primary dark:text-dark flex"
	>
		<span class="mr-1 h-4 w-4">
			<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="h-4 w-4" style="fill: currentColor;">
				<path
					d="M12.8995 6.85431L17.1421 11.0969L7.24264 20.9964H3V16.7538L12.8995 6.85431ZM14.3137 5.44009L16.435 3.31877C16.8256 2.92825 17.4587 2.92825 17.8492 3.31877L20.6777 6.1472C21.0682 6.53772 21.0682 7.17089 20.6777 7.56141L18.5563 9.68273L14.3137 5.44009Z"
				/>
			</svg>
		</span>
		{isZh ? '在 GitHub 上编辑' : 'Edit on GitHub'}
	</a>
</div>



================================================
FILE: docs/site/src/routes/components/Component.svelte
================================================
<script lang="ts">
	let { highlightedCode = '' } = $props();
</script>

<article class={`prose max-w-none text-sm dark:prose-invert`}>
	<pre><code class="hljs">{@html highlightedCode}</code></pre>
</article>



================================================
FILE: docs/site/src/routes/components/FAQ.svelte
================================================
<script lang="ts">
	import { onMount } from 'svelte';

	import { mdTextToHljs } from '../../utils/index';

	interface Props {
		guide?: string;
	}

	let { guide = 'button' }: Props = $props();
	const isZh = localStorage.getItem('lang') === 'zh_CN';

	let loading = $state(true);
	const getMdStrFunc = async (nav: string) => {
		loading = true;
		const rawObj = await import(`../../../../mds/components/${nav}/FAQ${isZh ? '' : '_en'}.md`);
		const mdStr = rawObj.default;
		loading = false;
		return mdTextToHljs(mdStr.replace(/<a href="/g, '<a target="_blank" href="'));
	};
	let guideText: string | null = $state(null);
	onMount(async () => {
		guideText = await getMdStrFunc(guide);
	});
</script>

<p class="mb-4 text-xs text-black/40 dark:text-white/30">
	{isZh
		? '注：请将开发中遇到的问题或想法提到 GitHub Issue，后续会筛选出有代表性的问题整理在此处。'
		: 'Note: Please raise any issues or ideas encountered in development to GitHub Issue, and then select representative issues to organize here.'}
</p>
<article
	class="prose dark:prose-invert prose-table:break-all prose-td:whitespace-nowrap md:prose-td:whitespace-normal max-w-none overflow-x-auto pb-12"
>
	{#if loading}
		{isZh ? '请等待...' : 'Please wait...'}
	{:else}
		{@html guideText}
	{/if}
</article>
<div class="flex gap-2 pb-8 text-xs">
	<a
		href={'https://github.com/any-tdf/stdf/edit/main/docs/mds/components/' + guide + '/FAQ' + (isZh ? '' : '_en') + '.md'}
		target="_blank"
		class="text-primary dark:text-dark flex"
	>
		<span class="mr-1 h-4 w-4">
			<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="h-4 w-4" style="fill: currentColor;">
				<path
					d="M12.8995 6.85431L17.1421 11.0969L7.24264 20.9964H3V16.7538L12.8995 6.85431ZM14.3137 5.44009L16.435 3.31877C16.8256 2.92825 17.4587 2.92825 17.8492 3.31877L20.6777 6.1472C21.0682 6.53772 21.0682 7.17089 20.6777 7.56141L18.5563 9.68273L14.3137 5.44009Z"
				/>
			</svg>
		</span>
		{isZh ? '在 GitHub 上编辑' : 'Edit on GitHub'}
	</a>
</div>



================================================
FILE: docs/site/src/routes/components/Guide.svelte
================================================
<script lang="ts">
	import { onMount } from 'svelte';
	import { mdTextToHljs } from './../../utils/index';
	import { themeStore, sysThemeStore } from '../../store';

	interface Props {
		guide?: string;
	}

	let { guide = 'button' }: Props = $props();

	const isZh = localStorage.getItem('lang') === 'zh_CN';
	let loading = $state(true);
	let theme = $derived($themeStore === 'auto' ? ($sysThemeStore === 'dark' ? 'dark' : 'light') : $themeStore);
	const getMdStrFunc = async (nav: string) => {
		loading = true;
		const rawObj = await import(`../../../../mds/components/${nav}/guide${isZh ? '' : '_en'}.md`);
		const mdStr = rawObj.default;
		loading = false;
		return mdTextToHljs(
			mdStr
				.replace(/<img src="/g, `<img class="w-full md:w-1/2${theme === 'dark' ? ' invert' : ''}" src="./assets/images/guide/`)
				.replace(/<a href="/g, '<a target="_blank" href="')
		);
	};
	let guideText: string | null = $state(null);
	onMount(async () => {
		guideText = await getMdStrFunc(guide);
	});
</script>

<article class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark max-w-none pb-12">
	{#if loading}
		{isZh ? '请等待...' : 'Please wait...'}
	{:else}
		{@html guideText}
	{/if}
</article>

<div class="flex gap-2 pb-8 text-xs">
	<a
		href={'https://github.com/any-tdf/stdf/edit/main/docs/mds/components/' + guide + '/guide' + (isZh ? '' : '_en') + '.md'}
		target="_blank"
		class="text-primary dark:text-dark flex"
	>
		<span class="mr-1 h-4 w-4">
			<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="h-4 w-4" style="fill: currentColor;">
				<path
					d="M12.8995 6.85431L17.1421 11.0969L7.24264 20.9964H3V16.7538L12.8995 6.85431ZM14.3137 5.44009L16.435 3.31877C16.8256 2.92825 17.4587 2.92825 17.8492 3.31877L20.6777 6.1472C21.0682 6.53772 21.0682 7.17089 20.6777 7.56141L18.5563 9.68273L14.3137 5.44009Z"
				/>
			</svg>
		</span>
		{isZh ? '在 GitHub 上编辑' : 'Edit on GitHub'}
	</a>
</div>



================================================
FILE: docs/site/src/routes/components/Version.svelte
================================================
<script lang="ts">
	import { onMount } from 'svelte';
	import { mdTextToHljs } from '../../utils/index';

	interface Props {
		guide?: string;
	}

	let { guide = 'button' }: Props = $props();
	const isZh = localStorage.getItem('lang') === 'zh_CN';

	let loading = $state(true);

	//提取字符中以‘[!tag’开头且以‘]’结尾的所有字符串，组成数组，并返回数组
	const getTags = (str: string) => {
		return str.match(/\[!tag[^\]]+\]/g);
	};

	//提取字符中以‘[!issue‘开头且以‘]’结尾的所有字符串，组成数组，并返回数组
	const getIssues = (str: string) => {
		return str.match(/\[!issue[^\]]+\]/g);
	};

	//提取字符中以‘[!contribute‘开头且以‘]’结尾的所有字符串，组成数组，并返回数组
	const getContributes = (str: string) => {
		return str.match(/\[!contribute[^\]]+\]/g);
	};

	// 传入 tag 类型和 index，返回对应的 emoji
	const spanTextFun = (type: string, index: string) => {
		if (type === 'O') {
			return '👏';
		}
		if (type === 'A') {
			return '💪';
		}
		switch (index) {
			case '1':
				return '👊';
			case '2':
				return '✊';
			case '3':
				return '👎';
			default:
				return '👎';
		}
	};
	//替换 Markdown 中的标签
	const mdTextToHljsFun = (string: string) => {
		//替换 tag
		const tagList = getTags(string);
		if (tagList) {
			tagList.forEach((item) => {
				const arr = item.split('|');
				// const span = `<span class="w-2 h-2 text-xs inline-block rounded-full mr-1 ${bgClassFun(arr[1], arr[2])}"></span>`;
				const span = `<span class="mr-1">${spanTextFun(arr[1], arr[2])}</span>`;
				string = string.replace(item, span);
			});
		}
		//替换 issue
		const issueList = getIssues(string);
		if (issueList) {
			issueList.forEach((item) => {
				const arr = item.split('|');
				const span = `<span><a class="size-4 translate-y-0.5 rounded-full overflow-hidden inline-flex items-center justify-center" href="https://github.com/${
					arr[1]
				}" target="_blank"><img class="w-full h-full" src="https://avatars.githubusercontent.com/${
					arr[1]
				}" title="${isZh ? '感谢' : 'Thanks'} ${arr[1]} ${isZh ? '提出 Issue' : 'raise an Issue'}" alt=""></a></span>`;
				string = string.replace(item, span);
			});
		}
		//替换 contribute
		const contributeList = getContributes(string);
		if (contributeList) {
			contributeList.forEach((item) => {
				const arr = item.split('|');
				const span = `<span><a class="size-4 translate-y-0.5 rounded-full overflow-hidden inline-flex items-center justify-center" href="https://github.com/${
					arr[1]
				}" target="_blank"><img class="w-full h-full" src="https://avatars.githubusercontent.com/${
					arr[1]
				}" title="${isZh ? '感谢' : 'Thanks'} ${arr[1]} ${isZh ? '贡献代码' : 'contribute code'}" alt=""></a></span>`;
				string = string.replace(item, span);
			});
		}
		return string;
	};

	const getMdStrFunc = async (nav: string) => {
		loading = true;
		const rawObj = await import(`../../../../mds/components/${nav}/version${isZh ? '' : '_en'}.md`);
		const mdStr = rawObj.default;
		loading = false;
		return mdTextToHljs(mdStr.replace(/<a href="/g, '<a target="_blank" href="'));
	};
	let guideText: string | null = $state(null);
	onMount(async () => {
		const guideTextStr = await getMdStrFunc(guide);
		guideText = mdTextToHljsFun(guideTextStr);
	});
</script>

<div class="mb-4 max-w-5xl text-xs text-black/40 dark:text-white/30">
	{isZh
		? '注：👊、✊、👎 分别表示严重、一般、轻微三个等级的 BUG，👏 表示优化，💪 表示新增。描述后面的头像表示此项的提出者或贡献者，感谢他们。'
		: 'Note: 👊, ✊, and 👎 represent three levels of severity for bugs, with 👊 being the most severe and 👎 the least severe. 👏 means optimization, and 💪 means new feature. The avatar after the description represents the proposer or contributor of the item. We thank them for their contributions. '}
</div>
<article
	class="prose dark:prose-invert prose-table:break-all prose-td:whitespace-nowrap md:prose-td:whitespace-normal max-w-none overflow-x-auto pb-12"
>
	{#if loading}
		{isZh ? '请等待...' : 'Please wait...'}
	{:else}
		{@html guideText}
	{/if}
</article>
<div class="flex gap-2 pb-8 text-xs">
	<a
		href={'https://github.com/any-tdf/stdf/edit/main/docs/mds/components/' + guide + '/version' + (isZh ? '' : '_en') + '.md'}
		class="text-primary dark:text-dark flex"
		target="_blank"
	>
		<span class="mr-1 h-4 w-4">
			<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="h-4 w-4" style="fill: currentColor;">
				<path
					d="M12.8995 6.85431L17.1421 11.0969L7.24264 20.9964H3V16.7538L12.8995 6.85431ZM14.3137 5.44009L16.435 3.31877C16.8256 2.92825 17.4587 2.92825 17.8492 3.31877L20.6777 6.1472C21.0682 6.53772 21.0682 7.17089 20.6777 7.56141L18.5563 9.68273L14.3137 5.44009Z"
				/>
			</svg>
		</span>
		{isZh ? '在 GitHub 上编辑' : 'Edit on GitHub'}
	</a>
</div>



================================================
FILE: docs/site/src/routes/guide/+layout.svelte
================================================
<script lang="ts">
	import { onMount } from 'svelte';
	import { isShowNavStore, isWideScreenStore } from '../../store';
	import Menu from '$lib/menu/Menu.svelte';
	import { page } from '$app/stores';
	import type { MenuListChild } from '../../data/menuList.js';
	import { goto } from '$app/navigation';

	let { children } = $props();

	const isZh = localStorage.getItem('lang') === 'zh_CN';

	type menuListChildsProps = { title: string; title_en: string; nav: string; doc?: string };
	type menuListProps = { class: string; class_en: string; childs: menuListChildsProps[] };
	const menuList: menuListProps[] = [
		{
			class: '常规',
			class_en: 'General',
			childs: [
				{ title: '快速上手', title_en: 'Quick start', nav: 'quick-start', doc: 'quickStart' },
				{ title: '主题配置', title_en: 'Theme', nav: 'theme', doc: 'theme' },
				{ title: '图标', title_en: 'Icon', nav: 'icon', doc: 'icon' },
				{
					title: '国际化',
					title_en: 'Internationalization',
					nav: 'internation',
					doc: 'internation'
				},
				{ title: '更新日志', title_en: 'Changelog', nav: 'changelog', doc: 'changelog' },
				{ title: '常见问题', title_en: 'FAQ', nav: 'faq', doc: 'faq' },
				{
					title: '贡献指南',
					title_en: 'Contribution Guide',
					nav: 'contribution',
					doc: 'contribution'
				},
				{ title: '兼容性', title_en: 'Compatibility', nav: 'compatibility', doc: 'compatibility' }
			]
		},
		{
			class: '设计',
			class_en: 'Design',
			childs: [
				{ title: '色彩', title_en: 'Color', nav: 'color' },
				{ title: 'LOGO', title_en: 'LOGO', nav: 'logo' }
			]
		},
		{
			class: '工具',
			class_en: 'Tools',
			childs: [
				{ title: '主题生成器', title_en: 'Theme generator', nav: 'generator' },
				{ title: 'IDE 插件', title_en: 'IDE plugin', nav: 'vscode', doc: 'vscode' },
				{ title: '脚手架', title_en: 'Create cli', nav: 'create' },
				{ title: '图标插件', title_en: 'Icon plugin', nav: 'icon-plugin' },
				{ title: 'MD 插件', title_en: 'MD plugin', nav: 'md' },
				{ title: '快捷键', title_en: 'Shortcut key', nav: 'shortkey' }
			]
		},
		{
			class: '其他',
			class_en: 'Other',
			childs: [
				{ title: '关于', title_en: 'About', nav: 'about', doc: 'about' },
				{ title: '里程碑', title_en: 'Milestone', nav: 'milestone', doc: 'milestone' },
				{ title: '计划', title_en: 'Future', nav: 'future', doc: 'future' }
			]
		}
	];
	//扁平 menuList
	const flatMenuList: menuListChildsProps[] = [];
	for (let e = 0; e < menuList.length; e++) {
		flatMenuList.push(...menuList[e].childs);
	}
	let currentNav = $state(menuList[0].childs[0]);
	let menuHeight = $state(0);
	const getMenuHeightFun = () => {
		menuHeight = document.documentElement.clientHeight - 56;
	};
	const menuClickFun = (currentMenu: MenuListChild) => {
		if ($isShowNavStore) {
			isShowNavStore.set(false);
		}
		currentNav = currentMenu;
		// 将当前点击的 currentMenu 设置 url 参数
		// window.location.href = '/guide?nav=' + currentMenu.nav;
		goto(`/guide${currentMenu.nav === 'quick-start' ? '' : `/${currentMenu.nav}`}`);
	};

	onMount(() => {
		menuHeight = document.documentElement.clientHeight - 56;
		window.addEventListener('resize', getMenuHeightFun);

		// 根据 $page.url.pathname 获取 currentNav
		const urlNav = flatMenuList.find((item) => ($page.url.pathname.includes(item.nav) ? item : null));
		currentNav = urlNav || flatMenuList[0];

		return () => {
			window.removeEventListener('resize', getMenuHeightFun);
		};
	});
	// 全屏
	const changeFullFunc = () => {
		if ($isWideScreenStore) {
			isWideScreenStore.set(false);
			localStorage.setItem('isFull', 'notFull');
		} else {
			isWideScreenStore.set(true);
			localStorage.setItem('isFull', 'full');
		}
	};
	// 编辑地址处理
	const editUrlFn = (nav: string) => {
		const baseUrl = 'https://github.com/any-tdf/stdf/edit/main/';
		if (nav === 'create') {
			return baseUrl + 'packages/create-stdf/README' + (isZh ? '_CN' : '') + '.md';
		}
		if (nav === 'icon-plugin') {
			return baseUrl + 'packages/rollup-plugin-stdf-icon/README' + (isZh ? '_CN' : '') + '.md';
		}
		return baseUrl + `docs/mds/guide/${flatMenuList.filter((item) => item.nav === nav)[0]?.doc}${isZh ? '' : '_en'}.md`;
	};
</script>

<div class="flex">
	<div
		class="fixed -left-52 top-14 z-[100] w-48 overflow-y-scroll border-black/10 bg-white transition-all duration-300 md:left-0 md:bg-transparent dark:border-white/20 dark:bg-black dark:md:bg-transparent"
		class:left-0={$isShowNavStore}
		class:-left-52={!$isShowNavStore}
		style="height:{menuHeight + 'px'}"
	>
		<Menu {menuList} currentNav={currentNav.nav} onclickMenu={menuClickFun} showNum={false} />
	</div>
	<div class="w-screen md:pl-48">
		<!-- {#if !$page.url.pathname.includes('generator')}
			<div class="px-4 py-12 md:px-8 md:py-4">
				<div class="text-4xl font-bold">
					{isZh ? currentNav.title : currentNav.title_en}
				</div>
			</div>
			<div class="h-px bg-black/10 dark:bg-white/20"></div>
		{/if} -->
		<div class="px-4 pt-4 {$page.url.pathname.includes('generator') ? 'md:px-4 md:pt-4' : 'md:px-8 md:pt-12'}">
			{@render children()}
		</div>
		{#if !$page.url.pathname.includes('generator') && currentNav.nav != 'color' && currentNav.nav != 'logo' && currentNav.nav != 'shortkey'}
			<div class="mx-auto flex gap-2 px-4 pb-8 text-xs {$isWideScreenStore ? 'max-w-full md:px-8' : 'max-w-7xl md:px-0'}">
				<a href={editUrlFn(currentNav.nav)} class="text-primary dark:text-dark flex w-full" target="_blank">
					<span class="mr-1 h-4 w-4">
						<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="h-4 w-4" style="fill: currentColor;">
							<path
								d="M12.8995 6.85431L17.1421 11.0969L7.24264 20.9964H3V16.7538L12.8995 6.85431ZM14.3137 5.44009L16.435 3.31877C16.8256 2.92825 17.4587 2.92825 17.8492 3.31877L20.6777 6.1472C21.0682 6.53772 21.0682 7.17089 20.6777 7.56141L18.5563 9.68273L14.3137 5.44009Z"
							/>
						</svg>
					</span>
					{isZh ? '在 GitHub 上编辑' : 'Edit on GitHub'}
				</a>
			</div>
		{/if}
	</div>
</div>
{#if !$page.url.pathname.includes('generator')}
	<button
		class="bg-primary shadow-primary/50 dark:bg-dark dark:shadow-dark/50 fixed bottom-4 right-2 z-50 hidden h-8 w-8 cursor-pointer rounded-full p-1.5 text-white shadow-md md:block dark:text-black"
		onclick={changeFullFunc}
	>
		{#if $isWideScreenStore}
			<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
				><path
					d="M20 3C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3H20ZM11 5H5V19H11V15H13V19H19V5H13V9H11V5ZM15 9L18 12L15 15V13H9V15L6 12L9 9V11H15V9Z"
					fill="currentColor"
				></path></svg
			>
		{:else}
			<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
				><path
					d="M20 3C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3H20ZM11 5H5V10.999H7V9L10 12L7 15V13H5V19H11V17H13V19H19V13H17V15L14 12L17 9V10.999H19V5H13V7H11V5ZM13 13V15H11V13H13ZM13 9V11H11V9H13Z"
					fill="currentColor"
				></path></svg
			>
		{/if}
	</button>
{/if}
<!-- 为 code-groups 预先编译 tailwind -->
<div
	class="peer-checked/tab-0-0:border-primary peer-checked/tab-0-1:border-primary peer-checked/tab-0-2:border-primary peer-checked/tab-0-3:border-primary peer-checked/tab-0-4:border-primary peer-checked/tab-0-5:border-primary
peer-checked/tab-1-0:border-primary peer-checked/tab-1-1:border-primary peer-checked/tab-1-2:border-primary
peer-checked/tab-1-3:border-primary peer-checked/tab-1-4:border-primary peer-checked/tab-1-5:border-primary
peer-checked/tab-2-0:border-primary peer-checked/tab-2-1:border-primary peer-checked/tab-2-2:border-primary
peer-checked/tab-2-3:border-primary peer-checked/tab-2-4:border-primary peer-checked/tab-2-5:border-primary
peer-checked/tab-3-0:border-primary peer-checked/tab-3-1:border-primary peer-checked/tab-3-2:border-primary
peer-checked/tab-3-3:border-primary peer-checked/tab-3-4:border-primary peer-checked/tab-3-5:border-primary
peer-checked/tab-4-0:border-primary peer-checked/tab-4-1:border-primary peer-checked/tab-4-2:border-primary
peer-checked/tab-4-3:border-primary peer-checked/tab-4-4:border-primary peer-checked/tab-4-5:border-primary
dark:peer-checked/tab-0-0:border-dark dark:peer-checked/tab-0-1:border-dark dark:peer-checked/tab-0-2:border-dark
dark:peer-checked/tab-0-3:border-dark dark:peer-checked/tab-0-4:border-dark dark:peer-checked/tab-0-5:border-dark
dark:peer-checked/tab-1-0:border-dark dark:peer-checked/tab-1-1:border-dark dark:peer-checked/tab-1-2:border-dark
dark:peer-checked/tab-1-3:border-dark dark:peer-checked/tab-1-4:border-dark dark:peer-checked/tab-1-5:border-dark
dark:peer-checked/tab-2-0:border-dark dark:peer-checked/tab-2-1:border-dark dark:peer-checked/tab-2-2:border-dark
dark:peer-checked/tab-2-3:border-dark dark:peer-checked/tab-2-4:border-dark dark:peer-checked/tab-2-5:border-dark
dark:peer-checked/tab-3-0:border-dark dark:peer-checked/tab-3-1:border-dark dark:peer-checked/tab-3-2:border-dark
dark:peer-checked/tab-3-3:border-dark dark:peer-checked/tab-3-4:border-dark dark:peer-checked/tab-3-5:border-dark
dark:peer-checked/tab-4-0:border-dark dark:peer-checked/tab-4-1:border-dark dark:peer-checked/tab-4-2:border-dark
dark:peer-checked/tab-4-3:border-dark dark:peer-checked/tab-4-4:border-dark dark:peer-checked/tab-4-5:border-dark
hidden border-b-2 border-black/10 peer-checked/tab-0-0:block
peer-checked/tab-0-1:block peer-checked/tab-0-2:block peer-checked/tab-0-3:block
peer-checked/tab-0-4:block peer-checked/tab-0-5:block peer-checked/tab-1-0:block
peer-checked/tab-1-1:block peer-checked/tab-1-2:block peer-checked/tab-1-3:block
peer-checked/tab-1-4:block peer-checked/tab-1-5:block peer-checked/tab-2-0:block
peer-checked/tab-2-1:block peer-checked/tab-2-2:block peer-checked/tab-2-3:block
peer-checked/tab-2-4:block peer-checked/tab-2-5:block peer-checked/tab-3-0:block
peer-checked/tab-3-1:block peer-checked/tab-3-2:block peer-checked/tab-3-3:block
peer-checked/tab-3-4:block peer-checked/tab-3-5:block peer-checked/tab-4-0:block
peer-checked/tab-4-1:block peer-checked/tab-4-2:block peer-checked/tab-4-3:block
peer-checked/tab-4-4:block peer-checked/tab-4-5:block dark:border-white/10 dark:bg-[#202020]"
></div>



================================================
FILE: docs/site/src/routes/guide/+page.svelte
================================================
<script lang="ts">
	import { mdTextToHljs, groupIconMdPlugin } from '../../utils/index';
	import { isWideScreenStore } from '../../store';

	// @ts-ignore
	import quickStartText from '../../../../mds/guide/quickStart.md';
	// @ts-ignore
	import quickStartText_en from '../../../../mds/guide/quickStart_en.md';

	const isZh = localStorage.getItem('lang') === 'zh_CN';
	const text = groupIconMdPlugin(
		mdTextToHljs(isZh ? quickStartText : quickStartText_en).replace(/<a href="/g, '<a target="_blank" href="')
	);
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto pb-12 {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	<!-- eslint-disable-next-line svelte/no-at-html-tags -->
	{@html text}
</article>



================================================
FILE: docs/site/src/routes/guide/Create.svelte
================================================
<script>
	import { mdTextToHljs, groupIconMdPlugin } from '../../utils/index.js';
	import { isWideScreenStore } from '../../store.js';

	// @ts-ignore
	import createText from '../../../../../../packages/create-stdf/README_CN.md';
	// @ts-ignore
	import createText_en from '../../../../../../packages/create-stdf/README.md';

	const isZh = localStorage.getItem('lang') === 'zh_CN';
	const text = groupIconMdPlugin(
		(isZh ? mdTextToHljs(createText) : mdTextToHljs(createText_en)).replace(/<a href="/g, '<a target="_blank" href="')
	);
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark pb-12 {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-5xl'}"
>
	<!-- eslint-disable-next-line svelte/no-at-html-tags -->
	{@html text}
</article>



================================================
FILE: docs/site/src/routes/guide/about/+page.svelte
================================================
<script lang="ts">
	import { mdTextToHljs } from '../../../utils/index';
	import { isWideScreenStore } from '../../../store';

	// @ts-ignore
	import text from '../../../../../mds/guide/about.md';
	// @ts-ignore
	import text_en from '../../../../../mds/guide/about_en.md';

	const isZh = localStorage.getItem('lang') === 'zh_CN';

	const hljsText = mdTextToHljs((isZh ? text : text_en).replace(/<a href="/g, '<a target="_blank" href="'));
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto pb-8 {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	<!-- eslint-disable-next-line svelte/no-at-html-tags -->
	{@html hljsText}
</article>



================================================
FILE: docs/site/src/routes/guide/changelog/+page.svelte
================================================
<script lang="ts">
	import { mdTextToHljs } from '../../../utils/index';
	import { isWideScreenStore } from '../../../store';

	// @ts-ignore
	import text from '../../../../../mds/guide/changelog.md';
	// @ts-ignore
	import text_en from '../../../../../mds/guide/changelog_en.md';

	const isZh = localStorage.getItem('lang') === 'zh_CN';
	//提取字符中以‘[!tag’开头且以‘]’结尾的所有字符串，组成数组，并返回数组
	const getTags = (str: string) => str.match(/\[!tag[^\]]+\]/g);
	//提取字符中以‘[!issue‘开头且以‘]’结尾的所有字符串，组成数组，并返回数组
	const getIssues = (str: string) => str.match(/\[!issue[^\]]+\]/g);
	//提取字符中以‘[!contribute‘开头且以‘]’结尾的所有字符串，组成数组，并返回数组
	const getContributes = (str: string) => str.match(/\[!contribute[^\]]+\]/g);
	const spanTextFun = (type: 'A' | 'B' | 'O', index: '1' | '2' | '3') => {
		const typeMap = { A: '💪', O: '👌' };
		const indexMap = { '1': '👊', '2': '✊', '3': '👎' };
		if (type === 'O' || type === 'A') {
			return typeMap[type];
		} else {
			return indexMap[index];
		}
	};
	//替换 Markdown 中的标签
	const mdTextToHljsFun = (string: string) => {
		//替换 tag
		const tagList = getTags(string);
		if (tagList) {
			tagList.forEach((item) => {
				const arr: string[] = item.split('|');
				const span = `<span class="mr-1">${spanTextFun(arr[1] as 'A' | 'B' | 'O', arr[2] as '1' | '2' | '3')}</span>`;
				string = string.replace(item, span);
			});
		}
		//替换 issue
		const issueList = getIssues(string);
		if (issueList) {
			issueList.forEach((item) => {
				const arr = item.split('|');
				const span = `<span><a href="https://github.com/${
					arr[1]
				}" target="_blank"><img class="w-4 h-4 ml-1 p-0 m-0 rounded-full overflow-hidden inline" src="https://avatars.githubusercontent.com/${
					arr[1]
				}" title="${isZh ? '感谢' : 'Thanks '} ${arr[1]} ${isZh ? '提出 Issue' : 'raise an Issue'}" alt=""></a></span>`;
				string = string.replace(item, span);
			});
		}
		//替换 contribute
		const contributeList = getContributes(string);
		if (contributeList) {
			contributeList.forEach((item) => {
				const arr = item.split('|');
				const span = `<span><a href="https://github.com/${
					arr[1]
				}" target="_blank"><img class="w-4 h-4 ml-1 p-0 m-0 rounded-full overflow-hidden inline" src="https://avatars.githubusercontent.com/${
					arr[1]
				}" title="${isZh ? '感谢' : 'Thanks '} ${arr[1]} ${isZh ? '贡献代码' : 'contribute code'}" alt=""></a></span>`;
				string = string.replace(item, span);
			});
		}
		return string;
	};
	const hljsText = mdTextToHljs((isZh ? text : text_en).replace(/<a href="/g, '<a target="_blank" href="'));
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto pb-8 text-xs {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	<p class="mb-4 text-xs text-black/40 dark:text-white/30">
		{isZh
			? '注：此处仅展示站点更新说明或总体概述，具体组件更新内容请查看组件内部更新日志。描述后面的头像表示此项的提出者或贡献者，感谢他们。发布时间格式均为 GMT+8。'
			: 'Note: Only the site update instructions or general overview are displayed here. For the specific component update content, please refer to the update log inside the component. The avatars after the description represent the submitter or contributor, thank them for their contribution. The release time format is GMT+8.'}
	</p>
	<!-- eslint-disable-next-line svelte/no-at-html-tags -->
	{@html mdTextToHljsFun(hljsText)}
</article>



================================================
FILE: docs/site/src/routes/guide/color/+page.svelte
================================================
<script lang="ts">
	import Color from './Color.svelte';
</script>

<Color />



================================================
FILE: docs/site/src/routes/guide/color/Color.svelte
================================================
<script lang="ts">
	import { onMount, onDestroy } from 'svelte';
	import ColorCard from '$lib/colorCard/ColorCard.svelte';
	import ModeSwitch from '$lib/modeSwitch/ModeSwitch.svelte';
	import ThemeSwitch from '$lib/themeSwitch/ThemeSwitch.svelte';
	import themes from '../../../data/themes';
	import { currentColorStore, isWideScreenStore } from '../../../store';
	import { colorConvertFunc, colorObjToArr, getOklchOpacity } from '../../../utils';
	import hljs from 'highlight.js';
	import { type ThemeProps, type PrimaryAndDarkColor } from 'stdf/theme';

	const isZh = localStorage.getItem('lang') === 'zh_CN';

	const colorGrayList = [
		{ key: 'gray-50', color: 'oklch(0.961 0 0)' },
		{ key: 'gray-100', color: 'oklch(0.925 0 0)' },
		{ key: 'gray-200', color: 'oklch(0.845 0 0)' },
		{ key: 'gray-300', color: 'oklch(0.767 0 0)' },
		{ key: 'gray-400', color: 'oklch(0.683 0 0)' },
		{ key: 'gray-500', color: 'oklch(0.6 0 0)' },
		{ key: 'gray-600', color: 'oklch(0.51 0 0)' },
		{ key: 'gray-700', color: 'oklch(0.42 0 0)' },
		{ key: 'gray-800', color: 'oklch(0.321 0 0)' },
		{ key: 'gray-900', color: 'oklch(0.218 0 0)' },
		{ key: 'gray-950', color: 'oklch(0.159 0 0)' }
	];
	onMount(() => hljs.highlightAll());

	let currentColorObj: ThemeProps | undefined = undefined;
	let primaryColors: PrimaryAndDarkColor | undefined = $state(undefined);
	// primaryColors 转为数组，且 default 在第 6 项
	let primaryColorsList = $derived(colorObjToArr(primaryColors ?? {}));
	let darkColors: PrimaryAndDarkColor | undefined = $state(undefined);
	let darkColorsList = $derived(colorObjToArr(darkColors ?? {}));
	let themeBlack: { primary: string; dark: string } | undefined = $state(undefined);
	let themeWhite: { primary: string; dark: string } | undefined = $state(undefined);
	let stateColor: { success: string; warning: string; error: string; info: string } | undefined = $state(undefined);
	let extendList: { color: string; alias: string }[] | undefined = $state(undefined);

	const unsubscribe = currentColorStore.subscribe((value) => {
		// 根据 $currentColorStore 从 themes 中获取对应的颜色对象
		currentColorObj = themes.find((item) => item.name === value)?.theme;
		// 传入数组，按照 Tailwind 规则生成颜色列表
		const createTWColorFunc = (colorList: string[]) => {
			if (colorList.length !== 11) {
				console.error('颜色列表长度必须为 11');
				return;
			}
			const colorArr: { n: number; hex: string; rgb: string; hsl: string }[] = [];
			colorList.forEach((item, index) => {
				// 第 0 项和最后一项的 key 为 50 和 950，其他项为 100-900，颜色有 hex、rgb、hsl 三种格式，注意 hsl 保留整数
				let colorObj: { n: number; hex: string; rgb: string; hsl: string; oklch: string } = {
					n: 0,
					hex: '',
					rgb: '',
					hsl: '',
					oklch: ''
				};
				if (index === 0) {
					colorObj = {
						n: 50,
						hex: item,
						rgb: colorConvertFunc(item).rgb,
						hsl: colorConvertFunc(item).hsl,
						oklch: colorConvertFunc(item).oklch
					};
				} else if (index === 10) {
					colorObj = {
						n: 950,
						hex: item,
						rgb: colorConvertFunc(item).rgb,
						hsl: colorConvertFunc(item).hsl,
						oklch: colorConvertFunc(item).oklch
					};
				} else {
					colorObj = {
						n: 100 * index,
						hex: item,
						rgb: colorConvertFunc(item).rgb,
						hsl: colorConvertFunc(item).hsl,
						oklch: colorConvertFunc(item).oklch
					};
				}
				colorArr.push(colorObj);
			});
			return colorArr;
		};
		if (!currentColorObj) return;
		primaryColors = currentColorObj.color.primary;
		darkColors = currentColorObj.color.dark;

		// 根据主题色生成主题黑和白
		themeBlack = { primary: currentColorObj.color.primaryBlack, dark: currentColorObj.color.darkBlack };
		themeWhite = { primary: currentColorObj.color.primaryWhite, dark: currentColorObj.color.darkWhite };
		stateColor = currentColorObj.color.functional;
		extendList = currentColorObj.color.extend;
	});
	// svelte 组件销毁时取消订阅
	onDestroy(() => {
		unsubscribe();
	});
	// 传入 rgb(0, 98, 57) 这种格式与透明度，返回 rgba(0, 98, 57, 0.1) 这种格式
	const rgbaFunc = (str = '#000', n = 0.1) => {
		const arr = str.split(',');
		const r = arr[0].split('(')[1];
		const g = arr[1];
		const b = arr[2].split(')')[0];
		return `rgba(${r}, ${g}, ${b}, ${n / 10})`;
	};
	// 传入 hsl(157, 100%, 15%) 这种格式与透明度，返回 hsla(157, 100%, 15%, 0.1) 这种格式
	const hslaFunc = (str = 'hsl(157, 100%, 15%)', n = 0.1) => {
		const arr = str.split(',');
		const h = arr[0].split('(')[1];
		const s = arr[1];
		const l = arr[2].split(')')[0];
		return `hsla(${h}, ${s}, ${l}, ${n / 10})`;
	};
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto pb-8 {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	<blockquote>
		{isZh
			? 'STDF 跟随 Tailwind CSS v4 推荐使用 oklch 颜色模式。'
			: 'STDF follows Tailwind CSS v4 recommendation to use the oklch color mode.'}
	</blockquote>
	<div class="mb-4 text-xs">
		{#if isZh}
			切换亮暗模式，选择下列内置主题可查看配色。到<a href="/guide/generator" target="_blank">主题生成器</a
			>可快速配置颜色系统并生成配置文件。具体使用方法请参考<a href="/guide/theme" target="_blank">主题配置</a>。
		{:else}
			Switch the light and dark mode, select the built-in theme to view the color. To <a href="/guide/generator" target="_blank"
				>Theme Generator</a
			>
			quickly configure the color system and generate the configuration file. For specific usage methods, please refer to
			<a href="/guide/theme" target="_blank">Theme Configuration</a>.
		{/if}
	</div>
	<div class="inline-flex items-center gap-4">
		<ModeSwitch />
	</div>
	<div class="flex items-center gap-4">
		<ThemeSwitch />
	</div>
	<h2>{isZh ? '概述' : 'Overview'}</h2>
	<p>
		{isZh
			? '使用合理的颜色系统，可以使整个应用配色更加统一和美观。借助 Tailwind 的配置，可以更加方便地实现这一功能，当然也包括暗模式。'
			: "Use a reasonable color system to make the entire application more unified and beautiful. With Tailwind's configuration, this function can be implemented more conveniently, including the dark mode."}
	</p>
	{#if isZh}
		<p>
			STDF 颜色系统包含主题色、功能色、中性色、扩展色四个部分。其中<strong>主题色和功能色是必须的</strong
			>；中性色一般使用默认配置即可；扩展色，也叫辅助色或装饰色，非必需，可根据实际情况自行添加。你可能需要根据你的应用修改成自己的颜色系统。
		</p>
	{:else}
		<p>
			STDF color system includes four parts: theme color, functional color, neutral color, and extended color. Among them, <strong
				>theme color and functional color are required</strong
			>；neutral color generally uses the default configuration; extended color, also called auxiliary color or decorative color, is not
			required, and can be added according to actual circumstances. You may need to modify it to your own color system according to your
			application.
		</p>
	{/if}
	<blockquote>
		{isZh
			? '颜色有别于技术，是一种主观、感性、难量化的事物，所以颜色的搭配没有好坏之分，只有适合不适合。'
			: 'Color is different from technology, it is a subjective, emotional, and difficult to quantify thing, so there is no good or bad in color combination, only whether it is suitable or not.'}
	</blockquote>
	<h2>{isZh ? '主题色' : 'Theme Color'}</h2>
	<p>
		{isZh
			? '主题色是应用中最核心、最高频使用的颜色，它可能用于任何地方，比如强调信息、引导操作，并在很大程度上决定了应用整体的颜色基调和配色风格。'
			: 'Theme color is the most core and frequently used color in the application. It may be used anywhere, such as emphasizing information, guiding operations, and largely determining the color tone and color scheme of the application.'}
	</p>
	{#if isZh}
		<p>
			一般情况，会使用区别于主色的另一种颜色适配暗模式，一种做法是不改变色相，只是将主色变浅提亮使其突出显现在暗背景下；另一种做法是完全取另一种色相，STDF
			推荐使用后者，以便暗模式下的主色更加明显。所以 STDF
			内置的主题色分为亮暗模式。当然，如果你需要将亮暗模式都设置为相同色相也是可以的，STDF 提供的<a href="/guide/generator" target="_blank">
				主题生成器
			</a>支持随意配置。
		</p>
	{:else}
		<p>
			Generally, a different color from the main color is used to adapt to the dark mode. One approach is to keep the same hue but make the
			main color lighter to stand out in the dark background; the other approach is to completely take another hue, STDF recommends the
			latter, so that the main color in the dark mode is more obvious. Therefore, STDF provides two sets of theme colors: one for the light
			mode and one for the dark mode. Of course, if you need to set both the light and dark modes to the same hue, the <a
				href="/guide/generator"
				target="_blank">Theme Generator</a
			> supports arbitrary configuration.
		</p>
	{/if}
	<div class="justify-between md:flex md:space-x-8">
		<div class="flex h-32 flex-1 flex-col justify-between rounded-sm p-4 text-white" style="background-color: {primaryColors?.default};">
			<div class="text-xl font-bold">{isZh ? 'primary（亮模式）' : 'primary (Light Mode)'}</div>
			<div>{primaryColors?.default}</div>
		</div>
		<div
			class="mt-4 flex h-32 flex-1 flex-col justify-between rounded-sm p-4 text-black md:mt-0"
			style="background-color: {darkColors?.default};"
		>
			<div class="text-xl font-bold">{isZh ? 'dark（暗模式）' : 'dark (Dark Mode)'}</div>
			<div>{darkColors?.default}</div>
		</div>
	</div>
	<h3>{isZh ? '梯度色板' : 'Gradient Color Palette'}</h3>
	{#if isZh}
		<p>
			Tailwind 内置了一套 <a href="https://tailwindcss.com/docs/customizing-colors" target="_blank">调色板</a
			>，但这并不能满足自定义的主题色，STDF 参照 Tailwind 的调色板命名规则，使用一套内置算法动态地将主题色计算出 11 种颜色组成梯度色板。其中
			600 号色作为默认颜色【省略 600 编号】，实际业务中使用淡颜色的场景会多一些，故淡颜色会多一些选择。
		</p>
	{:else}
		<p>
			Tailwind provides a <a href="https://tailwindcss.com/docs/customizing-colors" target="_blank">color palette</a>, but it cannot meet
			the custom theme color, STDF refers to Tailwind's color palette naming rules and uses a set of built-in algorithms to calculate the
			theme color into 11 colors to form a gradient color palette. The 600th color is the default color [omitting the 600 number], and in
			actual business, the scene of using light colors is more common, so there are more choices for light colors.
		</p>
	{/if}
	<div class="justify-between space-y-8 md:flex md:space-x-8 md:space-y-0">
		<div class="flex flex-1 flex-col justify-between rounded-sm bg-white text-sm">
			{#each primaryColorsList as item, index}
				<div
					class="p-4 transition hover:scale-105 hover:rounded-sm {index >= 6 ? 'text-white' : 'text-black'}"
					style="background-color: {item.value};"
				>
					<div class="flex items-center justify-between">
						<div class="flex-1 text-left font-bold">primary{index === 6 ? '' : `-${item.key}`}</div>
						<div class="text-right">
							<div>{item.value}</div>
						</div>
					</div>
				</div>
			{/each}
		</div>
		<div class="flex flex-1 flex-col justify-between rounded-sm bg-white text-sm">
			{#each darkColorsList as item, index}
				<div
					class="p-4 transition hover:scale-105 hover:rounded-sm {index >= 7 ? 'text-white' : 'text-black'}"
					style="background-color: {item.value};"
				>
					<div class="flex items-center justify-between">
						<div class="flex-1 text-left font-bold">dark{index === 6 ? '' : `-${item.key}`}</div>
						<div class="text-right">
							<div>{item.value}</div>
						</div>
					</div>
				</div>
			{/each}
		</div>
	</div>
	<h3>{isZh ? '透明度' : 'Opacity'}</h3>
	<p>
		{isZh
			? '某些应用场景中，需要使用到主题色的透明度。注意这与上述梯度色板的差异。'
			: 'In some application scenarios, you need to use the opacity of the theme color. Note the difference from the above gradient color palette.'}
	</p>
	<div class="transparent-background justify-between space-y-8 md:flex md:space-x-8 md:space-y-0">
		<div class="flex flex-1 flex-col justify-between rounded-sm text-black">
			{#each [0.05, 0.1, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.75, 0.8, 0.9, 0.95] as color}
				<div
					class="p-2 transition hover:scale-105 hover:rounded-sm"
					style="background-color: {getOklchOpacity(primaryColors?.default ?? '', color)};"
				>
					<div class="flex items-center justify-between text-sm">
						<div class="rounded-sm bg-white px-2 py-1">primary/{color * 100}</div>
						<div class="rounded-sm bg-white px-2 py-1 text-right">
							<div>{getOklchOpacity(primaryColors?.default ?? '', color)}</div>
						</div>
					</div>
				</div>
			{/each}
		</div>
		<div class="flex flex-1 flex-col justify-between rounded-sm text-black">
			{#each [0.05, 0.1, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.75, 0.8, 0.9, 0.95] as color}
				<div
					class="p-2 transition hover:scale-105 hover:rounded-sm"
					style="background-color: {getOklchOpacity(darkColors?.default ?? '', color)};"
				>
					<div class="flex items-center justify-between text-sm">
						<div class="rounded-sm bg-white px-2 py-1">dark/{color * 100}</div>
						<div class="rounded-sm bg-white px-2 py-1 text-right">
							<div>{getOklchOpacity(darkColors?.default ?? '', color)}</div>
						</div>
					</div>
				</div>
			{/each}
		</div>
	</div>
	<h3>{isZh ? '主题黑白色' : 'Theme Black and White'}</h3>
	<p>
		{isZh
			? '通常情况下，设计中应避免大面积使用纯黑色 oklch(0 0 0)，使用接近纯黑的颜色。同时 STDF 会根据算法计算出两个接近纯黑但是带有主题色的黑色，方便设计搭配。同样也会计算出两个接近纯白但是带有主题色的白色。一般可用于多套主题搭配时的文字颜色，亮暗背景颜色等场景。'
			: 'In most cases, designers should avoid using pure black oklch(0 0 0) on a large scale, and use a color close to pure black. At the same time, STDF will calculate two black colors close to pure black but with a theme color for design. Similarly, it will calculate two white colors close to pure white but with a theme color. Generally, it can be used in the text color of multiple theme combinations, the light and dark background color, etc.'}
	</p>
	<div class="flex-wrap justify-around space-y-4 md:flex md:space-x-4 md:space-y-0">
		{#each [themeBlack?.primary, themeBlack?.dark, themeWhite?.primary, themeWhite?.dark] as item, i}
			<div
				class="flex h-24 flex-1 flex-col justify-between rounded-sm border p-2 {i === 0 || i === 1
					? 'border-gray-700 text-white'
					: 'border-gray-300 text-black'}"
				style="background-color: {item};"
			>
				<div class="font-bold">
					{i === 0 ? 'primaryBlack' : i === 1 ? 'darkBlack' : i === 2 ? 'primaryWhite' : 'darkWhite'}
				</div>
				<div class="text-sm">{item}</div>
			</div>
		{/each}
	</div>
	<h2>{isZh ? '功能色' : 'Functional Color'}</h2>
	<p>
		{isZh
			? '功能色是指用于特定场景、特定状态等特殊语义的颜色，通常包含成功、警告、错误、信息四种。当然也都支持类似主题色的透明度写法。'
			: 'Functional color is a color used for specific scenarios, specific states, etc. It usually includes four types: success, warning, error, and information. Of course, it also supports the transparent writing method similar to the theme color.'}
	</p>
	<div class="flex-wrap justify-around space-y-4 md:flex md:space-x-4 md:space-y-0">
		{#each [stateColor?.success, stateColor?.warning, stateColor?.error, stateColor?.info] as item, i}
			<div class="flex h-24 flex-1 flex-col justify-between rounded-sm p-2 text-white" style="background-color: {item};">
				<div class="font-bold">{i === 0 ? 'success' : i === 1 ? 'warning' : i === 2 ? 'error' : 'info'}</div>
				<div class="text-sm">{item}</div>
			</div>
		{/each}
	</div>
	<h2>{isZh ? '中性色' : 'Neutral Color'}</h2>
	<p>
		{isZh
			? '中性色包含一系列带透明度的黑白色和不同程度的灰色，用于配置亮色与暗模式不同背景、文字、分割线等颜色。'
			: 'Neutral color includes a series of black and white colors with different degrees of transparency and different degrees of gray, used to configure different background, text, and split line colors in the light and dark modes.'}
	</p>
	<p class="text-xs">
		{isZh
			? '注：当下层为纯色时，带透明度的黑白色与灰色可能看起来一样但实际不一样，请注意区分使用。虽然灰色也可以使用透明度，但是需要透明度的地方一般通过黑白色配合透明度值使用。'
			: 'Note: When the lower layer is a pure color, the black and white colors with transparency may look the same but are actually different, please pay attention to the difference in use. Although gray can also use transparency, but the places that need transparency usually use the black and white colors with transparency.'}
	</p>
	<div class="justify-between space-y-8 text-black md:flex md:space-x-8 md:space-y-0">
		<div class="transparent-background flex flex-1 flex-col justify-between rounded-sm text-sm">
			{#each [0.5, 1, 2, 2.5, 3, 4, 5, 6, 7, 7.5, 8, 9, 9.5] as color}
				<div class="p-2 transition hover:scale-105 hover:rounded-sm" style="background-color: oklch(0 0 0 / {color / 10});">
					<div class="flex items-center justify-between">
						<div class="rounded-sm bg-white px-2 py-1 text-left">
							black{`/${color * 10}`}
						</div>
						<div class="rounded-sm bg-white px-2 py-1">
							<div class="flex-1 text-right">oklch(0 0 0 / {color / 10})</div>
						</div>
					</div>
				</div>
			{/each}
			<div class="p-2 transition hover:scale-105 hover:rounded-sm" style="background-color: oklch(0 0 0);">
				<div class="flex items-center justify-between">
					<div class="rounded-sm bg-white px-2 py-1 text-left">black</div>
					<div class="rounded-sm bg-white px-2 py-1">
						<div class="flex-1 text-right">oklch(0 0 0)</div>
					</div>
				</div>
			</div>
		</div>
		<div class="transparent-background flex flex-1 flex-col justify-between rounded text-sm">
			{#each [0.5, 1, 2, 2.5, 3, 4, 5, 6, 7, 7.5, 8, 9, 9.5] as color}
				<div class="p-2 transition hover:scale-105 hover:rounded-sm" style="background-color: oklch(1 0 0 / {color / 10});">
					<div class="flex items-center justify-between">
						<div class="rounded-sm bg-white px-2 py-1 text-left">
							white{`/${color * 10}`}
						</div>
						<div class="rounded-sm bg-white px-2 py-1">
							<div class="flex-1 text-right">oklch(1 0 0 / {color / 10})</div>
						</div>
					</div>
				</div>
			{/each}
			<div class="p-2 transition hover:scale-105 hover:rounded-sm" style="background-color: oklch(1 0 0);">
				<div class="flex items-center justify-between">
					<div class="rounded-sm bg-white px-2 py-1 text-left">white</div>
					<div class="rounded-sm bg-white px-2 py-1">
						<div class="flex-1 text-right">oklch(1 0 0)</div>
					</div>
				</div>
			</div>
		</div>
		<div class="flex flex-1 flex-col justify-between rounded-sm">
			<ColorCard colorList={colorGrayList} />
		</div>
	</div>
	<h2>{isZh ? '扩展色' : 'Extended Color'}</h2>
	{#if isZh}
		<p>
			扩展色是一些区分功能色与主题色的非必需装饰性颜色，主要是在需要多个颜色搭配的界面时使用。统一配置可以使全局搭配颜色更加协调，通过
			Tailwind 配置之后写起来也更加方便。数量不限，使用方式不限，使用规则不限。但请注意使用<strong
				>多主题时，不同主题的扩展色数量应保持一致。</strong
			>STDF 内置主题都提供了三种扩展色，请根据你的实际配色方案搭配。当然也都支持类似主题色的透明度写法。
		</p>
		<p>
			写扩展色类名时使用 extend0、extend1...
			这种方式不方便记忆，推荐使用颜色的别名。别名的命名规则不限，如颜色名称、品牌、情绪、场景、编号、关联事物......皆可。如下面的
			extend0、extend1、extend2 分别对应当前主题【{themes.find((item) => item.name === $currentColorStore)?.name_CN}】的三个扩展色。STDF
			提供的<a href="/guide/generator" target="_blank"> 主题生成器 </a>也支持配置别名。
		</p>
	{:else}
		<p>
			Extended color is some non-essential decorative colors that are not required to distinguish between functional colors and theme
			colors. Mainly used in interfaces that need multiple color combinations. Unifying the configuration can make the global color more
			harmonious, and writing it is also more convenient after Tailwind configuration. The number is unlimited, the usage is unlimited, and
			the usage rules are unlimited. But please note that when using multiple themes, the number of extended colors in different themes
			should be kept consistent. STDF provides three extended colors for the built-in themes, please match according to your actual color
			scheme. Of course, it also supports the transparent writing method similar to the theme color.
		</p>
		<p>
			When writing the class name of the extended color, use extend0, extend1..., this method is not convenient to remember, it is
			recommended to use the alias of the color. The naming rules of the alias are unlimited, such as the color name, brand, emotion, scene,
			number, related things... Such as the following extend0, extend1, extend2, which correspond to the three extended colors of the
			current theme [{themes.find((item) => item.name === $currentColorStore)?.name}]. STDF's
			<a href="/guide/generator" target="_blank">Theme Generator</a> also supports configuration aliases.
		</p>
	{/if}
	<div class="flex-wrap justify-around space-y-4 md:flex md:space-x-4 md:space-y-0">
		{#each extendList ?? [] as extend}
			<div class="flex h-24 flex-1 flex-col justify-between rounded-sm p-2 text-white" style="background-color: {extend.color};">
				<div class="font-bold">{extend.alias}</div>
				<div>{extend.color}</div>
			</div>
		{/each}
	</div>
</article>



================================================
FILE: docs/site/src/routes/guide/compatibility/+page.svelte
================================================
<script lang="ts">
	import { mdTextToHljs } from '../../../utils/index';
	import { isWideScreenStore } from '../../../store';

	// @ts-ignore
	import text from '../../../../../mds/guide/compatibility.md';
	// @ts-ignore
	import text_en from '../../../../../mds/guide/compatibility_en.md';

	const isZh = localStorage.getItem('lang') === 'zh_CN';
	const hljsText = mdTextToHljs((isZh ? text : text_en).replace(/<a href="/g, '<a target="_blank" href="'));
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto pb-8 {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	<!-- eslint-disable-next-line svelte/no-at-html-tags -->
	{@html hljsText}
</article>



================================================
FILE: docs/site/src/routes/guide/contribution/+page.svelte
================================================
<script lang="ts">
	import { mdTextToHljs, groupIconMdPlugin } from '../../../utils/index';
	import { isWideScreenStore } from '../../../store';

	// @ts-ignore
	import text from '../../../../../mds/guide/contribution.md';
	// @ts-ignore
	import text_en from '../../../../../mds/guide/contribution_en.md';

	const isZh = localStorage.getItem('lang') === 'zh_CN';
	const hljsText = groupIconMdPlugin(mdTextToHljs(isZh ? text : text_en).replace(/<a href="/g, '<a target="_blank" href="'));
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto pb-8 {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	<!-- eslint-disable-next-line svelte/no-at-html-tags -->
	{@html hljsText}
</article>



================================================
FILE: docs/site/src/routes/guide/create/+page.svelte
================================================
<script lang="ts">
	import { mdTextToHljs, groupIconMdPlugin } from '../../../utils/index';
	import { isWideScreenStore } from '../../../store';

	// @ts-ignore
	import createText from '../../../../../../packages/create-stdf/README_CN.md';
	// @ts-ignore
	import createText_en from '../../../../../../packages/create-stdf/README.md';

	const isZh = localStorage.getItem('lang') === 'zh_CN';
	const text = groupIconMdPlugin(
		(isZh ? mdTextToHljs(createText) : mdTextToHljs(createText_en)).replace(/<a href="/g, '<a target="_blank" href="')
	);
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto pb-8 {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	<!-- eslint-disable-next-line svelte/no-at-html-tags -->
	{@html text}
</article>



================================================
FILE: docs/site/src/routes/guide/faq/+page.svelte
================================================
<script lang="ts">
	import { mdTextToHljs } from '../../../utils/index';
	import { isWideScreenStore } from '../../../store';

	// @ts-ignore
	import text from '../../../../../mds/guide/faq.md';
	// @ts-ignore
	import text_en from '../../../../../mds/guide/faq_en.md';

	const isZh = localStorage.getItem('lang') === 'zh_CN';
	const hljsText = mdTextToHljs((isZh ? text : text_en).replace(/<a href="/g, '<a target="_blank" href="'));
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto pb-8 {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	<!-- eslint-disable-next-line svelte/no-at-html-tags -->
	{@html hljsText}
</article>



================================================
FILE: docs/site/src/routes/guide/future/+page.svelte
================================================
<script lang="ts">
	import { mdTextToHljs } from '../../../utils/index';
	import { isWideScreenStore } from '../../../store';

	// @ts-ignore
	import text from '../../../../../mds/guide/future.md';
	// @ts-ignore
	import text_en from '../../../../../mds/guide/future_en.md';

	const isZh = localStorage.getItem('lang') === 'zh_CN';
	const hljsText = mdTextToHljs((isZh ? text : text_en).replace(/<a href="/g, '<a target="_blank" href="'));
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto pb-8 {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	<!-- eslint-disable-next-line svelte/no-at-html-tags -->
	{@html hljsText}
</article>



================================================
FILE: docs/site/src/routes/guide/generator/+page.svelte
================================================
<script lang="ts">
	import { onDestroy, onMount } from 'svelte';
	import { fly } from 'svelte/transition';
	import ClipboardJS from 'clipboard';
	import ModeSwitch from '$lib/modeSwitch/ModeSwitch.svelte';
	import { currentColorStore } from '../../../store';
	import themes from '../../../data/themes';
	import type { STDFTheme } from 'stdf/theme';
	import {
		generatePalette,
		generateThemeBlack,
		generateThemeWhite,
		colorConvertFunc,
		throttle,
		hexToRgb,
		getOklchFunc,
		getHexFunc
	} from '../../../utils';
	import colorList from '../../../data/color';
	import GeneratorPreview from './GeneratorPreview.svelte';
	import hljs from 'highlight.js';

	const isZh = localStorage.getItem('lang') === 'zh_CN';

	let showTip = $state(true);
	let windowWidth = $state(0);
	let windowHeight = $state(0);
	const initTheme = themes.find((item) => item.name === $currentColorStore) as ThemeItem;

	type ThemeItem = {
		name: string;
		name_CN: string;
		theme: typeof STDFTheme;
	};

	const setPropertyFunc = (name: string, value: string) => {
		const rgbStr = value.startsWith('oklch') ? value : hexToRgb(value);
		document.documentElement.style.setProperty(name, rgbStr);
	};
	// 使用 extendList 返回 extendListStr
	const extendListStrFunc = (extendList: { color: string; alias: string }[]) => {
		let extendListStr = '	{';
		extendList.forEach((item) => {
			extendListStr += `
			color: '${colorConvertFunc(item.color).oklch}', // ${item.color} ${colorConvertFunc(item.color).hsl}
			alias: "${item.alias}",
		},`;
			extendListStr += `
		{`;
		});
		// 如果 extendListStr 最后一个是换行符，则删除换行
		extendListStr = extendListStr.slice(0, extendListStr.lastIndexOf('\n'));
		return extendListStr;
	};
	// 使用 extendList 返回 extendListStr2
	const extendListStrFunc2 = (extendList: { color: string; alias: string }[]) => {
		let extendListStr = '';
		extendList.forEach((item, index) => {
			extendListStr += `	--color-extend${index}: ${getOklchFunc(item.color)};
	--color-${item.alias}: ${getOklchFunc(item.color)};
`;
		});
		// 如果 extendListStr 最后一个是换行符，则删除换行
		extendListStr = extendListStr.slice(0, extendListStr.lastIndexOf('\n'));
		return extendListStr;
	};
	const numbers = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
	let colors = $state([
		{ type: 'primary', color: initTheme.theme.color.primary.default, hex: getHexFunc(initTheme.theme.color.primary.default) },
		{ type: 'dark', color: initTheme.theme.color.dark.default, hex: getHexFunc(initTheme.theme.color.dark.default) },
		{ type: 'success', color: initTheme.theme.color.functional.success, hex: getHexFunc(initTheme.theme.color.functional.success) },
		{ type: 'warning', color: initTheme.theme.color.functional.warning, hex: getHexFunc(initTheme.theme.color.functional.warning) },
		{ type: 'error', color: initTheme.theme.color.functional.error, hex: getHexFunc(initTheme.theme.color.functional.error) },
		{ type: 'info', color: initTheme.theme.color.functional.info, hex: getHexFunc(initTheme.theme.color.functional.info) }
	]);
	let currentColorObj = {
		name: '',
		color: {
			primary: { default: '' },
			dark: { default: '' },
			functional: { success: '', warning: '', error: '', info: '' },
			extend: [{ color: '', alias: '' }]
		}
	};
	let primaryColors: { hex: string; hsl: string; n: number; rgb: string; oklch: string }[] = $state([]);
	let darkColors: { hex: string; hsl: string; n: number; rgb: string; oklch: string }[] = $state([]);
	let themeBlack = $state({
		primary: { hex: '', hsl: '', rgb: '', oklch: '' },
		dark: { hex: '', hsl: '', rgb: '', oklch: '' }
	});
	let themeWhite = $state({
		primary: { hex: '', hsl: '', rgb: '', oklch: '' },
		dark: { hex: '', hsl: '', rgb: '', oklch: '' }
	});
	let stateColor = $state({ success: '', warning: '', error: '', info: '' });
	let extendList: { color: string; alias: string; hex: string }[] = $state(
		initTheme.theme.color.extend.map((item) => ({ ...item, hex: getHexFunc(item.color) }))
	);

	let name = $state(initTheme.name);
	let showCopyTip = $state(false);
	let showCopyTip2 = $state(false);
	let extendListStr = $derived(extendListStrFunc(extendList));

	let extendListStr2 = $derived(extendListStrFunc2(extendList));

	let configStr = $derived(
		hljs.highlight(
			`// ${isZh ? '主题配置' : 'Theme configuration'}
name: '${name}',
color: {
	primary: {
		50: '${primaryColors[0].oklch}', // ${primaryColors[0].hex} ${primaryColors[0].hsl}
		100: '${primaryColors[1].oklch}', // ${primaryColors[1].hex} ${primaryColors[1].hsl}
		200: '${primaryColors[2].oklch}', // ${primaryColors[2].hex} ${primaryColors[2].hsl}
		300: '${primaryColors[3].oklch}', // ${primaryColors[3].hex} ${primaryColors[3].hsl}
		400: '${primaryColors[4].oklch}', // ${primaryColors[4].hex} ${primaryColors[4].hsl}
		500: '${primaryColors[5].oklch}', // ${primaryColors[5].hex} ${primaryColors[5].hsl}
		default: '${primaryColors[6].oklch}', // ${primaryColors[6].hex} ${primaryColors[6].hsl}
		700: '${primaryColors[7].oklch}', // ${primaryColors[7].hex} ${primaryColors[7].hsl}
		800: '${primaryColors[8].oklch}', // ${primaryColors[8].hex} ${primaryColors[8].hsl}
		900: '${primaryColors[9].oklch}', // ${primaryColors[9].hex} ${primaryColors[9].hsl}
		950: '${primaryColors[10].oklch}', // ${primaryColors[10].hex} ${primaryColors[10].hsl}
	},
	dark: {
		50: '${darkColors[0].oklch}', // ${darkColors[0].hex} ${darkColors[0].hsl}
		100: '${darkColors[1].oklch}', // ${darkColors[1].hex} ${darkColors[1].hsl}
		200: '${darkColors[2].oklch}', // ${darkColors[2].hex} ${darkColors[2].hsl}
		300: '${darkColors[3].oklch}', // ${darkColors[3].hex} ${darkColors[3].hsl}
		400: '${darkColors[4].oklch}', // ${darkColors[4].hex} ${darkColors[4].hsl}
		500: '${darkColors[5].oklch}', // ${darkColors[5].hex} ${darkColors[5].hsl}
		default: '${darkColors[6].oklch}', // ${darkColors[6].hex} ${darkColors[6].hsl}
		700: '${darkColors[7].oklch}', // ${darkColors[7].hex} ${darkColors[7].hsl}
		800: '${darkColors[8].oklch}', // ${darkColors[8].hex} ${darkColors[8].hsl}
		900: '${darkColors[9].oklch}', // ${darkColors[9].hex} ${darkColors[9].hsl}
		950: '${darkColors[10].oklch}', // ${darkColors[10].hex} ${darkColors[10].hsl}
	},
	primaryBlack: '${getOklchFunc(themeBlack.primary.hex)}', // ${themeBlack.primary.hex} ${themeBlack.primary.hsl}
	primaryWhite: '${getOklchFunc(themeWhite.primary.hex)}', // ${themeWhite.primary.hex} ${themeWhite.primary.hsl}
	darkBlack: '${getOklchFunc(themeBlack.dark.hex)}', // ${themeBlack.dark.hex} ${themeBlack.dark.hsl}
	darkWhite: '${getOklchFunc(themeWhite.dark.hex)}', // ${themeWhite.dark.hex} ${themeWhite.dark.hsl}
	functional: {
		success: '${getOklchFunc(stateColor.success)}', // ${stateColor.success} ${colorConvertFunc(stateColor.success).hsl}
		warning: '${getOklchFunc(stateColor.warning)}', // ${stateColor.warning} ${colorConvertFunc(stateColor.warning).hsl}
		error: '${getOklchFunc(stateColor.error)}', // ${stateColor.error} ${colorConvertFunc(stateColor.error).hsl}
		info: '${getOklchFunc(stateColor.info)}', // ${stateColor.info} ${colorConvertFunc(stateColor.info).hsl}
	},
	extend: [
	${extendListStr}
	],
},`,
			{ language: 'javascript', ignoreIllegals: true }
		).value
	);

	let configStr2 = $derived(
		hljs.highlight(
			`/* ${isZh ? '初始主题 CSS 变量' : 'Initial theme CSS variables'} */
@theme {
	--color-primary-50: ${primaryColors[0].oklch};
	--color-primary-100: ${primaryColors[1].oklch};
	--color-primary-200: ${primaryColors[2].oklch};
	--color-primary-300: ${primaryColors[3].oklch};
	--color-primary-400: ${primaryColors[4].oklch};
	--color-primary-500: ${primaryColors[5].oklch};
	--color-primary: ${primaryColors[6].oklch};
	--color-primary-700: ${primaryColors[7].oklch};
	--color-primary-800: ${primaryColors[8].oklch};
	--color-primary-900: ${primaryColors[9].oklch};
	--color-primary-950: ${primaryColors[10].oklch};

	--color-dark-50: ${darkColors[0].oklch};
	--color-dark-100: ${darkColors[1].oklch};
	--color-dark-200: ${darkColors[2].oklch};
	--color-dark-300: ${darkColors[3].oklch};
	--color-dark-400: ${darkColors[4].oklch};
	--color-dark-500: ${darkColors[5].oklch};
	--color-dark: ${darkColors[6].oklch};
	--color-dark-700: ${darkColors[7].oklch};
	--color-dark-800: ${darkColors[8].oklch};
	--color-dark-900: ${darkColors[9].oklch};
	--color-dark-950: ${darkColors[10].oklch};

	--color-primaryBlack: ${getOklchFunc(themeBlack.primary.hex)};
	--color-primaryWhite: ${getOklchFunc(themeWhite.primary.hex)};
	--color-darkBlack: ${getOklchFunc(themeBlack.dark.hex)};
	--color-darkWhite: ${getOklchFunc(themeWhite.dark.hex)};

	--color-success: ${getOklchFunc(stateColor.success)};
	--color-warning: ${getOklchFunc(stateColor.warning)};
	--color-error: ${getOklchFunc(stateColor.error)};
	--color-info: ${getOklchFunc(stateColor.info)};
	
${extendListStr2}

	--color-black: oklch(0 0 0);
	--color-white: oklch(1 0 0);
	--color-gray-50: oklch(0.961 0 0);
	--color-gray-100: oklch(0.925 0 0);
	--color-gray-200: oklch(0.845 0 0);
	--color-gray-300: oklch(0.767 0 0);
	--color-gray-400: oklch(0.683 0 0);
	--color-gray-500: oklch(0.6 0 0);
	--color-gray-600: oklch(0.51 0 0);
	--color-gray-700: oklch(0.42 0 0);
	--color-gray-800: oklch(0.321 0 0);
	--color-gray-900: oklch(0.218 0 0);
	--color-gray-950: oklch(0.159 0 0);
	--color-transparent: transparent;
}
`,
			{ language: 'css', ignoreIllegals: true }
		).value
	);

	// 统一生成颜色
	const generateFunc = () => {
		// 传入数组，按照 Tailwind 规则生成颜色列表
		const createTWColorFunc = (colorList: string[]) => {
			if (colorList.length !== 11) {
				console.error('颜色列表长度必须为 11');
				return;
			}
			const colorArr: { hex: string; hsl: string; n: number; rgb: string; oklch: string }[] = [];
			colorList.forEach((item, index) => {
				// 第 0 项和最后一项的 key 为 50 和 950，其他项为 100-900，颜色有 hex、rgb、hsl 三种格式，注意 hsl 保留整数
				let colorObj: { hex: string; hsl: string; n: number; rgb: string; oklch: string } = { hex: '', hsl: '', n: 0, rgb: '', oklch: '' };
				if (index === 0) {
					colorObj = {
						n: 50,
						hex: item,
						rgb: colorConvertFunc(item).rgb,
						hsl: colorConvertFunc(item).hsl,
						oklch: colorConvertFunc(item).oklch
					};
				} else if (index === 10) {
					colorObj = {
						n: 950,
						hex: item,
						rgb: colorConvertFunc(item).rgb,
						hsl: colorConvertFunc(item).hsl,
						oklch: colorConvertFunc(item).oklch
					};
				} else {
					colorObj = {
						n: 100 * index,
						hex: item,
						rgb: colorConvertFunc(item).rgb,
						hsl: colorConvertFunc(item).hsl,
						oklch: colorConvertFunc(item).oklch
					};
				}
				colorArr.push(colorObj);
			});
			return colorArr;
		};
		const primaryColorList = generatePalette(currentColorObj.color.primary.default) as string[];
		const darkColorList = generatePalette(currentColorObj.color.dark.default) as string[];
		primaryColors = createTWColorFunc(primaryColorList) as {
			hex: string;
			hsl: string;
			n: number;
			rgb: string;
			oklch: string;
		}[];

		darkColors = createTWColorFunc(darkColorList) as {
			hex: string;
			hsl: string;
			n: number;
			rgb: string;
			oklch: string;
		}[];

		// 根据主题色生成主题黑和白
		const primaryColorB = generateThemeBlack(currentColorObj.color.primary.default);
		const darkColorB = generateThemeBlack(currentColorObj.color.dark.default);
		// 查找 meta 标签，name="theme-color" 且 media="(prefers-color-scheme: dark)"
		const darkMeta = document.querySelector('meta[name="theme-color"][media="(prefers-color-scheme: dark)"]');
		// 如果找到了，就修改它的 content 属性
		if (darkMeta) {
			darkMeta.setAttribute('content', darkColorB.hex);
		}
		themeBlack = { primary: primaryColorB, dark: darkColorB };

		const primaryColorW = generateThemeWhite(currentColorObj.color.primary.default);
		// 查找 meta 标签，name="theme-color" 且 media="(prefers-color-scheme: light)"
		const lightMeta = document.querySelector('meta[name="theme-color"][media="(prefers-color-scheme: light)"]');
		// 如果找到了，就修改它的 content 属性
		if (lightMeta) {
			lightMeta.setAttribute('content', primaryColorW.hex);
		}
		const darkColorW = generateThemeWhite(currentColorObj.color.dark.default);
		themeWhite = { primary: primaryColorW, dark: darkColorW };
		stateColor = currentColorObj.color.functional;

		primaryColors.forEach((item) => {
			setPropertyFunc(item.n === 600 ? '--color-primary' : `--color-primary-${item.n}`, item.oklch);
		});
		darkColors.forEach((item) => {
			setPropertyFunc(item.n === 600 ? '--color-dark' : `--color-dark-${item.n}`, item.oklch);
		});
		setPropertyFunc('--color-primaryBlack', primaryColorB.oklch);
		setPropertyFunc('--color-primaryWhite', primaryColorW.oklch);
		setPropertyFunc('--color-darkBlack', darkColorB.oklch);
		setPropertyFunc('--color-darkWhite', darkColorW.oklch);
	};
	const changeFunc = (type = 'primary', e: null | Event, value: string) => {
		const colorValue = e ? (e.target as HTMLInputElement).value : value;
		const primaryObj = currentColorObj.color.primary;
		const darkObj = currentColorObj.color.dark;
		const functionalObj = currentColorObj.color.functional;
		const newColors = [...colors];
		const item = newColors.find((item) => item.type === type);
		if (item) {
			item.color = colorValue.indexOf('#') === 0 ? colorValue : getOklchFunc(colorValue);
			item.hex = colorValue.indexOf('#') === 0 ? colorValue : getHexFunc(colorValue);
		}
		colors = newColors;
		if (type === 'primary') {
			numbers.forEach((item) => {
				if (item === 600) {
					primaryObj['default'] = colorValue;
				} else {
					(primaryObj as unknown as Record<string, string>)[item] = colorValue;
				}
			});
		} else if (type === 'dark') {
			numbers.forEach((item) => {
				if (item === 600) {
					darkObj['default'] = colorValue;
				} else {
					(darkObj as unknown as Record<string, string>)[item] = colorValue;
				}
			});
		} else {
			setPropertyFunc(`--color-functional-${type}`, item?.color ?? '');
			(functionalObj as unknown as Record<string, string>)[type] = colorValue;
		}
		currentColorObj = {
			name: name,
			color: {
				primary: primaryObj,
				dark: darkObj,
				functional: functionalObj,
				extend: extendList
			}
		};
		generateFunc();
	};
	const unsubscribe = currentColorStore.subscribe((value) => {
		// 根据 $currentColorStore 从 themes 中获取对应的颜色对象
		const theme = themes.find((item) => item.name === value);
		if (!theme) {
			return;
		}
		currentColorObj = theme.theme;
		generateFunc();

		// 根据 currentColorObj 设置 colors
		const newColors = [...colors];
		newColors.forEach((item) => {
			if (item.type === 'primary') {
				item.color = currentColorObj.color.primary.default;
				item.hex = getHexFunc(currentColorObj.color.primary.default);
			} else if (item.type === 'dark') {
				item.color = currentColorObj.color.dark.default;
				item.hex = getHexFunc(currentColorObj.color.dark.default);
			} else {
				// 确保 item.type 是 functional 对象中的有效键
				if (item.type in currentColorObj.color.functional) {
					item.color = currentColorObj.color.functional[item.type as keyof typeof currentColorObj.color.functional];
					item.hex = getHexFunc(currentColorObj.color.functional[item.type as keyof typeof currentColorObj.color.functional]);
				}
			}
		});
		colors = newColors;
		name = currentColorObj.name;
		extendList = currentColorObj.color.extend.map((item) => ({ ...item, hex: getHexFunc(item.color) }));
	});
	// svelte 组件销毁时取消订阅
	onDestroy(() => {
		unsubscribe();
	});
	// 随机事件
	const randomFunc = () => {
		// 从 colorList 中随机取出一个 mode 为 dark 的颜色，再随机取出一个 mode 为 light 的颜色
		const randomDarkColor = colorList.filter((item) => item.mode === 'dark')[
			Math.floor(Math.random() * colorList.filter((item) => item.mode === 'dark').length)
		];
		const randomLightColor = colorList.filter((item) => item.mode === 'light')[
			Math.floor(Math.random() * colorList.filter((item) => item.mode === 'light').length)
		];
		name = `${randomDarkColor.name}/${randomLightColor.name}`;
		// 根据随机颜色生成主题
		changeFunc('primary', null, randomDarkColor.hex);
		changeFunc('dark', null, randomLightColor.hex);
		// 获取当前 extendList 的长度
		const extendListLength = extendList.length;
		// 从 colorList 中随机取出 extendListLength 个 mode 为 dark 的颜色，作为扩展色
		const randomExtendList = colorList
			.filter((item) => item.mode === 'dark')
			.sort(() => Math.random() - 0.5)
			.slice(0, extendListLength);
		let newExtendList = [];
		newExtendList = randomExtendList.map((item) => {
			return { color: item.hex, alias: item.name, hex: getHexFunc(item.hex) };
		});
		extendList = newExtendList;
	};
	// 重置事件
	const resetFunc = () => {
		// 刷新页面
		window.location.reload();
	};
	// 删除扩展色
	const deleteFunc = (i: number) => {
		let newExtendList = [...extendList];
		newExtendList.splice(i, 1);
		extendList = newExtendList;
	};
	// 选择 extendList 的颜色
	const changeExtendFunc = (e: Event, i: number) => {
		const colorValue = (e.target as HTMLInputElement).value;
		let newExtendList = [...extendList];
		newExtendList[i].color = colorValue;
		extendList = newExtendList;
	};
	// 输入 extendList 的别名
	const inputExtendFunc = (e: Event, i: number) => {
		const aliasValue = (e.target as HTMLInputElement).value;
		let newExtendList = [...extendList];
		newExtendList[i].alias = aliasValue;
		extendList = newExtendList;
	};
	// 新增扩展色
	const addExtendFunc = () => {
		let newExtendList = [...extendList];
		newExtendList.push({ color: '#000000', alias: '', hex: getHexFunc('#000000') });
		extendList = newExtendList;
	};
	// 监听窗口变化
	const windowResizeFun = () => {
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	};
	onMount(() => {
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
		window.addEventListener('resize', windowResizeFun);

		// 复制
		const clipboard = new ClipboardJS('#copyButton', {
			target: () => {
				return document.querySelector('#myCodeBlock')!;
			}
		});
		clipboard.on('success', function () {
			showCopyTip = true;
			setTimeout(() => {
				showCopyTip = false;
			}, 2000);
		});
		clipboard.on('error', function () {
			console.error('无法将内容复制到剪贴板');
		});

		// 复制
		const clipboard2 = new ClipboardJS('#copyButton2', {
			target: () => {
				return document.querySelector('#myCodeBlock2')!;
			}
		});
		clipboard2.on('success', function () {
			showCopyTip2 = true;
			setTimeout(() => {
				showCopyTip2 = false;
			}, 2000);
		});
		clipboard2.on('error', function () {
			console.error('无法将内容复制到剪贴板');
		});
	});
	onDestroy(() => {
		window.removeEventListener('resize', windowResizeFun);
	});
</script>

<div class="block md:hidden">{isZh ? '请在桌面端使用！' : 'Please use it on the desktop!'}</div>
<div class="hidden justify-between md:flex">
	<div>
		<div class="mb-2 text-center font-bold">{isZh ? '配置' : 'Configure'}</div>
		<div class="flex flex-col gap-1 text-center">
			<div class="text-left">{isZh ? '主题名称' : 'Theme name'}</div>
			<div class="flex-1">
				<input
					class="focus:outline-primary dark:focus:outline-dark rounded-xs w-full bg-transparent px-1 py-1 text-xs outline outline-black/10 dark:outline-white/20"
					type="text"
					bind:value={name}
					placeholder={isZh ? '请输入主题名称' : 'Please enter theme name'}
				/>
			</div>
		</div>
		<div class="mt-4 flex gap-2">
			<div class="flex flex-col gap-4 text-center">
				<!-- 输入框 主题色与功能色 -->
				{#each colors as item, i}
					<div class="{i === 2 ? 'mt-6' : 'mt-0'} relative">
						<!-- <div class="mb-1 text-left text-xs">{getOklchFunc(item.color)}</div> -->
						<div class="flex items-center gap-2">
							<input
								type="color"
								bind:value={item.hex}
								oninput={(e) => throttle(() => changeFunc(item.type, e, item.color), 100)()}
								class="h-6 w-6 flex-none cursor-pointer"
								style="background-color: {item.color};"
								onclick={() => (showTip = false)}
							/>
							<span>{item.type}</span>
						</div>
						{#if i === 0 && showTip}
							<div class="pointer-events-none absolute left-2 top-0 rotate-[135deg]">
								<div class="animate-bounce text-3xl">👇</div>
							</div>
						{/if}
					</div>
				{/each}
				<!-- 扩展色 -->
				<div class="mt-6 flex flex-col gap-4 overflow-y-auto" style="height: {windowHeight - 480}px;">
					{#each extendList as item, i}
						<div class="flex flex-col gap-2">
							<div class="flex gap-2">
								<input
									type="color"
									bind:value={item.hex}
									class="h-6 w-6"
									style="background-color: {item.color};"
									oninput={(e) => throttle(() => changeExtendFunc(e, i), 100)()}
								/>
								<div>extend{i}</div>
								<!-- <div class="w-16 flex-none overflow-hidden text-left text-sm leading-6">
									{item.color}
								</div> -->
								<button aria-label="delete" class="rounded-sm bg-black/5 px-1 dark:bg-white/10" onclick={() => deleteFunc(i)}>
									<svg class="h-4 w-6 transition-all hover:scale-90" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
										<path
											class="fill-error"
											d="M17 6H22V8H20V21C20 21.5523 19.5523 22 19 22H5C4.44772 22 4 21.5523 4 21V8H2V6H7V3C7 2.44772 7.44772 2 8 2H16C16.5523 2 17 2.44772 17 3V6ZM18 8H6V20H18V8ZM9 11H11V17H9V11ZM13 11H15V17H13V11ZM9 4V6H15V4H9Z"
										>
										</path>
									</svg>
								</button>
							</div>
							<div class="flex px-0.5">
								<input
									class="focus:outline-primary dark:focus:outline-dark rounded-xs h-6 w-full bg-transparent px-1 py-1 text-xs outline outline-black/10 dark:outline-white/20"
									type="text"
									bind:value={item.alias}
									placeholder={isZh ? `请输入 extend${i} 别名` : `Please enter extend${i} alias`}
									oninput={(e) => throttle(() => inputExtendFunc(e, i))}
								/>
							</div>
						</div>
					{/each}
					<div>
						<button
							class="items-centers border-primary dark:border-dark flex w-full justify-center gap-2 rounded-sm border py-1.5 text-sm text-black dark:text-white"
							onclick={addExtendFunc}
						>
							<span>
								<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
									<path class="fill-black dark:fill-white" d="M11 11V5H13V11H19V13H13V19H11V13H5V11H11Z"></path>
								</svg>
							</span>
							{isZh ? '新增' : 'Add'}</button
						>
					</div>
				</div>
			</div>
		</div>
	</div>
	<div class="flex-1">
		<div class="mb-4 text-center font-bold">{isZh ? '色板 & 配置文件' : 'Palette & Profiles'}</div>
		<div class="flex flex-col px-4 text-center text-xs">
			<div class="mb-1 flex flex-1 justify-between gap-1">
				{#each primaryColors as color, index}
					<div
						class="h-12 rounded-sm {index >= 5 ? 'text-primaryWhite' : 'text-primaryBlack'}"
						style="background-color: {color.oklch};flex: {index === 6 ? '2' : '1'}"
					>
						<div class="flex flex-col items-center justify-between">
							<div class="flex-1 leading-10 mt-1{index === 6 ? ' text-xl font-bold' : ''}">
								{index === 6 ? 'primary' : `${color.n}`}
							</div>
						</div>
					</div>
				{/each}
			</div>
			<div class="flex flex-1 justify-between gap-1">
				{#each darkColors as color, index}
					<div
						class="h-12 rounded-sm {index <= 6 ? 'text-darkBlack' : 'text-darkWhite'}"
						style="background-color: {color.oklch};flex: {index === 6 ? '2' : '1'};"
					>
						<div class="flex items-center justify-between">
							<div class="flex-1 leading-10 mt-1{index === 6 ? ' text-xl font-bold' : ''}">
								{index === 6 ? 'dark' : `${color.n}`}
							</div>
						</div>
					</div>
				{/each}
			</div>
		</div>
		<div class="mt-1 flex justify-between gap-1 px-4 text-center text-xs">
			{#each [themeBlack.primary, themeBlack.dark, themeWhite.primary, themeWhite.dark] as item, i}
				<div
					class="h-12 flex-1 rounded-sm border pt-4 {i === 0 || i === 1 ? 'border-gray-700 text-white' : 'border-gray-300 text-black'}"
					style="background-color: {item.oklch};"
				>
					<div>
						{i === 0 ? 'primaryBlack' : i === 1 ? 'darkBlack' : i === 2 ? 'primaryWhite' : 'darkWhite'}
					</div>
				</div>
			{/each}
		</div>
		<!-- 功能色 -->
		<div class="mt-1 flex justify-between gap-1 px-4 text-center text-xs text-white">
			<div class="h-12 flex-1 rounded-sm pt-4" style="background-color: {stateColor.success};">success</div>
			<div class="h-12 flex-1 rounded-sm pt-4" style="background-color: {stateColor.warning};">warning</div>
			<div class="h-12 flex-1 rounded-sm pt-4" style="background-color: {stateColor.error};">error</div>
			<div class="h-12 flex-1 rounded-sm pt-4" style="background-color: {stateColor.info};">info</div>
		</div>
		<!-- 扩展色 -->
		<div class="mt-1 flex h-12 justify-between gap-1 px-4 text-center text-xs text-white">
			{#if extendList}
				{#each extendList as item, i}
					<div class="flex h-12 flex-1 flex-col justify-center gap-1 rounded-sm py-1" style="background-color: {item.color};">
						<div class="text-xs">extend{i}</div>
						<div>{item.alias}</div>
					</div>
				{/each}
			{/if}
		</div>
		<!-- 配置文件 -->
		<div class="mx-4 mt-1 flex" style="height:{windowHeight - 388}px;width:{windowWidth - 858 + 46}px">
			<div class="bg-codeLight dark:bg-codeDark relative mr-1 grow">
				<div class="overflow-auto rounded-sm" style="height:{windowHeight - 388}px;width:{((windowWidth - 858) / 5) * 3 - 6 + 46}px">
					<article class="prose dark:prose-invert max-w-none text-xs">
						<!-- eslint-disable-next-line svelte/no-at-html-tags -->
						<pre><code class="hljs" id="myCodeBlock">{@html configStr}</code></pre>
					</article>
				</div>
				<button
					aria-label="copy"
					class="absolute right-0 top-0 rounded-bl-sm bg-black/5 px-3 py-2 text-sm hover:opacity-80 dark:bg-white/10"
					id="copyButton"
				>
					<svg class="h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
						<path
							class="fill-gray-700 dark:fill-gray-300"
							d="M6 4V8H18V4H20.0066C20.5552 4 21 4.44495 21 4.9934V21.0066C21 21.5552 20.5551 22 20.0066 22H3.9934C3.44476 22 3 21.5551 3 21.0066V4.9934C3 4.44476 3.44495 4 3.9934 4H6ZM8 2H16V6H8V2Z"
						></path>
					</svg>
				</button>
				{#if showCopyTip}
					<div in:fly={{ x: 50, duration: 500 }} out:fly={{ x: 50, duration: 300 }} class="absolute right-14 top-1 text-sm">
						{isZh ? '已复制！' : 'Copied!'}
					</div>
				{/if}
			</div>
			<div class="bg-codeLight dark:bg-codeDark relative grow">
				<div class="overflow-auto rounded-sm" style="height:{windowHeight - 388}px;width:{((windowWidth - 858) / 5) * 2 + 4}px">
					<article class="prose dark:prose-invert max-w-none text-xs">
						<!-- eslint-disable-next-line svelte/no-at-html-tags -->
						<pre><code class="hljs" id="myCodeBlock2">{@html configStr2}</code></pre>
					</article>
				</div>
				<button
					aria-label="copy"
					class="absolute right-0 top-0 rounded-bl-sm bg-black/5 px-3 py-2 text-sm hover:opacity-80 dark:bg-white/10"
					id="copyButton2"
				>
					<svg class="h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
						<path
							class="fill-gray-700 dark:fill-gray-300"
							d="M6 4V8H18V4H20.0066C20.5552 4 21 4.44495 21 4.9934V21.0066C21 21.5552 20.5551 22 20.0066 22H3.9934C3.44476 22 3 21.5551 3 21.0066V4.9934C3 4.44476 3.44495 4 3.9934 4H6ZM8 2H16V6H8V2Z"
						></path>
					</svg>
				</button>
				{#if showCopyTip2}
					<div in:fly={{ x: 50, duration: 500 }} out:fly={{ x: 50, duration: 300 }} class="absolute right-14 top-1 text-sm">
						{isZh ? '已复制！' : 'Copied!'}
					</div>
				{/if}
			</div>
		</div>
	</div>
	<div class="flex w-[390px] gap-4">
		<div>
			<div class="flex w-full justify-between pb-2">
				<div>
					<button
						class="bg-primary dark:bg-dark cursor-pointer rounded-sm px-4 py-1.5 text-xs text-white hover:opacity-90 dark:text-black"
						onclick={randomFunc}
					>
						{isZh ? '随机主题' : 'Random theme'}
					</button>
					<button
						class="border-primary dark:border-dark ml-2 cursor-pointer rounded-sm border px-4 py-1.5 text-xs text-black hover:opacity-90 dark:text-white"
						onclick={resetFunc}
					>
						{isZh ? '重置' : 'Reset'}
					</button>
				</div>
				<div>
					<ModeSwitch />
				</div>
			</div>
			<div
				class="border-primary/20 bg-primaryWhite dark:border-dark/20 dark:bg-darkBlack h-96 w-[392px] overflow-auto border dark:border-gray-700"
				style="height:{windowHeight - 130}px"
			>
				<GeneratorPreview />
			</div>
		</div>
	</div>
</div>

<style>
	input[type='color'] {
		-webkit-appearance: none;
		appearance: none;
		border: none;
		padding: 0;
		border-radius: 2px;
	}
	input[type='color']::-webkit-color-swatch-wrapper {
		padding: 0;
		margin: 0;
	}
	input[type='color']::-webkit-color-swatch {
		border: 1px solid #666;
		border-radius: 2px;
	}
</style>



================================================
FILE: docs/site/src/routes/guide/generator/Calendar.svelte
================================================
<script lang="ts">
	import { getNowBeforeOrAfterMonth, getCalendarData, getMonthListRange, getDateRange } from 'stdf/utils';
	import { zh_CN, en_US } from 'stdf/lang';

	const isZh = localStorage.getItem('lang') === 'zh_CN';

	// 当前语言
	// current language
	const currentLang = isZh ? zh_CN : en_US;
	const calendarLang = currentLang.calendar;

	// 传入的开始月，默认为当前月前 6 个月
	// 传入的结束月，默认为当前月后 6 个月
	// 选择模式，single 单选，multiple 多选，range 范围选择
	// 是否从周日开始
	// 周末文字是否标红
	// 月数据是否使用卡片样式
	// 是否显示月份水印
	// 月份水印文字大小
	// 显示信息的日期
	// 不允许选择日期集合
	// 圆角风格
	// 自动滚动到某个月时，是否使用动画
	// 高亮显示今天
	/**
	 * @typedef {Object} Props
	 * @property {any} [startMonth]
	 * @property {any} [endMonth]
	 * @property {string} [mode]
	 * @property {boolean} [startSunday]
	 * @property {boolean} [weekendRed]
	 * @property {boolean} [monthCard]
	 * @property {boolean} [monthMark]
	 * @property {string} [monthMarkSize]
	 * @property {any} [infoDates]
	 * @property {any} [disabledDates]
	 * @property {string} [radius]
	 * @property {boolean} [useAnimation]
	 * @property {boolean} [highlightToday]
	 */

	/** @type {Props} */
	let {
		startMonth = getNowBeforeOrAfterMonth(0),
		endMonth = getNowBeforeOrAfterMonth(0),
		mode = 'range',
		startSunday = false,
		weekendRed = false,
		monthCard = true,
		monthMark = false,
		monthMarkSize = 'xl',
		infoDates = [],
		disabledDates = [],
		radius = 'xl',
		useAnimation = true,
		highlightToday = true
	} = $props();

	// 圆角风格样式
	// Rounded style style
	const radiusClass = {
		sm: 'rounded-sm',
		xl: 'rounded-xl',
		'2xl': 'rounded-2xl',
		none: 'rounded-none'
	};

	// 月份水印文字大小样式
	// Month watermark text size style
	const monthMarkSizeClass = {
		'3xl': 'text-3xl',
		'4xl': 'text-4xl',
		'5xl': 'text-5xl',
		'6xl': 'text-6xl',
		'7xl': 'text-7xl',
		'8xl': 'text-8xl',
		'9xl': 'text-9xl'
	};

	// 当天日期字符串，YYYYMMDD，日和天不足两位时前面补 0
	// Today's date string, YYYYMMDD, day and day are not less than two digits, and 0 is filled in front
	const now = new Date();
	const nowYear = now.getFullYear();
	const nowMonth = now.getMonth() + 1;
	const nowDay = now.getDate();
	const todayStr = `${nowYear}${nowMonth < 10 ? '0' + nowMonth : nowMonth}${nowDay < 10 ? '0' + nowDay : nowDay}`;

	// 是否点击了快速选择
	// Whether to click the quick selection
	let isQuickSelect = false;

	// 定义周数据文字
	// Define the week data text
	const weekTexts = startSunday ? calendarLang.weekSundayStartTextList : calendarLang.weekTextList;

	// 传入 startSunday 和位于周的索引，返回是否是周末
	// Pass in startSunday and the index of the week, and return whether it is a weekend
	const isWeekendFunc = (startSunday: boolean, index: number) => {
		if (startSunday) {
			return index === 0 || index === 6;
		} else {
			return index === 5 || index === 6;
		}
	};

	// 根据 startMonth 和 endMonth 将月份数据组成 monthList
	// According to startMonth and endMonth, the month data is assembled into monthList
	const monthList = getMonthListRange(startMonth, endMonth);

	// 循环 monthList，根据每个月份的数据，生成全部的日历数据，其中 month 为当前月，year 为年，data 为日期数组
	// Loop monthList, generate all calendar data according to the data of each month, where month is the current month, year is the year, and data is the date array
	const allMonthData: {
		year: string;
		month: string;
		data: { text: string; info?: string; disabled?: boolean; start?: boolean; end?: boolean }[];
	}[] = monthList.map((monthStr) => {
		return {
			year: monthStr.slice(0, 4),
			month: monthStr.slice(4),
			data: getCalendarData(monthStr, startSunday).map((item) => ({
				text: item,
				info: '',
				disabled: false,
				start: false,
				end: false
			}))
		};
	});

	// 如果 infoDates 不为空，循环 allMonthData，循环 data，循环 infoDates，如果 infoDates 中的日期和 data 中的日期相同，将 infoDates 中的 info 赋值给 data 中的 info
	// If infoDates is not empty, loop allMonthData, loop data, loop infoDates, if the date in infoDates is the same as the date in data, assign the info in infoDates to the info in data
	if (infoDates.length > 0) {
		allMonthData.forEach((item) => {
			item.data.forEach((data) => {
				infoDates.forEach((info) => {
					if (info.date === item.year + item.month + data.text) {
						data.info = info.info;
					}
				});
			});
		});
	}

	// 如果 disabledDates 不为空，循环 allMonthData，循环 data，循环 disabledDates，如果 disabledDates 中的日期和 data 中的日期相同，将 disabledDates 中的 disabled 赋值给 data 中的 disabled
	// If disabledDates is not empty, loop allMonthData, loop data, loop disabledDates, if the date in disabledDates is the same as the date in data, assign the disabled in disabledDates to the disabled in data
	if (disabledDates.length > 0) {
		allMonthData.forEach((item) => {
			item.data.forEach((data) => {
				disabledDates.forEach((disabled) => {
					if (disabled === item.year + item.month + data.text) {
						data.disabled = true;
					}
				});
			});
		});
	}

	// 生成一个随机数，在 5-20 之间，作为选定天数
	// Generate a random number between 5-20 as the selected day
	const randomDayNum = Math.floor(Math.random() * 16) + 5;

	// 从当前月份随机找到连续的 randomDayNum 天，作为 selectedDate 初始值，如 ['20231108', '20231109', '20231110', '20231111', '20231112']
	// From the current month, find randomDayNum consecutive days at random as the initial value of selectedDate, such as ['20231108', '20231109', '20231110', '20231111', '20231112']
	// 先获取当前月份所有日期，再获取当前月份所有日期中的连续 randomDayNum 天
	// First get all the dates of the current month, and then get randomDayNum consecutive days in all the dates of the current month
	let currentMonthAllDays: string[] = [];
	const currentMonth = new Date().getMonth() + 1;
	const currentYear = new Date().getFullYear();
	const currentMonthData = getCalendarData(`${currentYear}${currentMonth < 10 ? '0' + currentMonth : currentMonth}`, startSunday);

	const currentMonthDays = currentMonthData.filter((item) => item).map((item) => item);
	currentMonthDays.forEach((item) => {
		currentMonthAllDays.push(`${currentYear}${currentMonth < 10 ? '0' + currentMonth : currentMonth}${item}`);
	});
	// 从 currentMonthAllDays 随机找到连续的 5 天
	// Find 5 consecutive days at random from currentMonthAllDays
	const randomIndex = Math.floor(Math.random() * (currentMonthAllDays.length - randomDayNum));
	let selectedDate = $state(currentMonthAllDays.slice(randomIndex, randomIndex + randomDayNum));

	// 范围选择时，点击的开始与结束
	// When range selection is clicked, the beginning and end are clicked
	let rangeArr: string[] = [];

	// selectedDate 字符串
	// selectedDate string
	let selectedDateStr = $derived(selectedDate.join(','));

	// 点击日期事件
	// Click date event
	const clickDayFunc = (
		year: string,
		month: string,
		dayData: { text: string; info?: string; disabled?: boolean; start?: boolean; end?: boolean }
	) => {
		if (!dayData.text) {
			return;
		}
		if (isQuickSelect) {
			isQuickSelect = false;
			selectedDate = [];
		}
		rangeArr.push(`${year}${month}${dayData.text}`);
		if (rangeArr.length === 2) {
			// 将 rangeArr 排序，保证第一个日期小于第二个日期
			// Sort rangeArr to ensure that the first date is less than the second date
			rangeArr.sort((a, b) => {
				return Number(a) - Number(b);
			});
			selectedDate = getDateRange(rangeArr[0], rangeArr[1], disabledDates);
			rangeArr = [];
		} else {
			selectedDate = rangeArr;
		}

		// 对 selectedDate 按照日期排序
		// Sort selectedDate by date
		selectedDate.sort((a, b) => {
			return Number(a) - Number(b);
		});
	};
</script>

<div>
	<div class="left-0 top-0 z-10 w-full">
		<div class="flex h-10 items-center justify-around gap-1 px-6 text-center leading-10">
			{#each weekTexts as item, index}
				<div class="flex-1 font-bold{weekendRed && isWeekendFunc(startSunday, index) ? ' text-error' : ''}">
					{item}
				</div>
			{/each}
		</div>
	</div>
	<div class="calendar-container flex flex-col gap-4 overflow-y-auto px-4 py-2 {useAnimation ? 'scroll-smooth' : 'scroll-auto'}">
		{#each allMonthData as item}
			<div class="{monthCard ? 'rounded-xl bg-white shadow-md dark:bg-black dark:shadow-white/5 ' : ''}relative">
				<div class="px-4 pt-4 text-xl text-black/30 dark:text-white/30">
					<span class="mr-2 font-bold text-black dark:text-white">
						{calendarLang.monthTextList[Number(item.month) - 1]}
					</span>
					{item.year}
				</div>
				<div class="grid grid-cols-7 gap-y-1 p-2 text-center">
					{#each item.data as i}
						<button
							class="p-px cursor-pointer{i.text ? ' bg-primary/10 dark:bg-dark/20' : ''}"
							onclick={() => {
								if (!i.disabled) clickDayFunc(item.year, item.month, i);
							}}
							class:!bg-transparent={!selectedDateStr.includes(`${item.year}${item.month}${i.text}`)}
							class:!rounded-l-xl={radius === 'xl' &&
								mode === 'range' &&
								(selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) === 0 || i.start)}
							class:!rounded-r-xl={radius === 'xl' &&
								mode === 'range' &&
								(selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) === selectedDateStr.length - 8 || i.end)}
							class:!rounded-xl={radius === 'xl' && mode !== 'range'}
							class:!rounded-l-2xl={radius === '2xl' &&
								mode === 'range' &&
								(selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) === 0 || i.start)}
							class:!rounded-r-2xl={radius === '2xl' &&
								mode === 'range' &&
								(selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) === selectedDateStr.length - 8 || i.end)}
							class:!rounded-2xl={radius === '2xl' && mode !== 'range'}
							class:!rounded-l-none={radius === 'none' &&
								mode === 'range' &&
								(selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) === 0 || i.start)}
							class:!rounded-r-none={radius === 'none' &&
								mode === 'range' &&
								(selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) === selectedDateStr.length - 8 || i.end)}
							class:!rounded-none={radius === 'none' && mode !== 'range'}
							class:!rounded-l-sm={radius === 'sm' &&
								mode === 'range' &&
								(selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) === 0 || i.start)}
							class:!rounded-r-sm={radius === 'sm' &&
								mode === 'range' &&
								(selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) === selectedDateStr.length - 8 || i.end)}
							class:!rounded-sm={radius === 'sm' && mode !== 'range'}
						>
							<div
								class="{radiusClass[radius as keyof typeof radiusClass] ||
									'rounded-xl'} relative flex h-full w-full flex-col justify-center {i.info ? 'py-1' : 'py-2'}"
								class:bg-primary={(i.text && mode !== 'range' && selectedDateStr.includes(`${item.year}${item.month}${i.text}`)) ||
									(i.text &&
										selectedDateStr.includes(`${item.year}${item.month}${i.text}`) &&
										mode === 'range' &&
										(selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) === 0 ||
											selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) === selectedDateStr.length - 8))}
								class:dark:bg-dark={(i.text && mode !== 'range' && selectedDateStr.includes(`${item.year}${item.month}${i.text}`)) ||
									(i.text &&
										selectedDateStr.includes(`${item.year}${item.month}${i.text}`) &&
										mode === 'range' &&
										(selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) === 0 ||
											selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) === selectedDateStr.length - 8))}
								class:text-white={(i.text && mode !== 'range' && selectedDateStr.includes(`${item.year}${item.month}${i.text}`)) ||
									(i.text &&
										selectedDateStr.includes(`${item.year}${item.month}${i.text}`) &&
										mode === 'range' &&
										(selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) === 0 ||
											selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) === selectedDateStr.length - 8))}
								class:dark:text-black={(i.text && mode !== 'range' && selectedDateStr.includes(`${item.year}${item.month}${i.text}`)) ||
									(i.text &&
										selectedDateStr.includes(`${item.year}${item.month}${i.text}`) &&
										mode === 'range' &&
										(selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) === 0 ||
											selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) === selectedDateStr.length - 8))}
								class:text-primary={mode === 'range' &&
									selectedDateStr.includes(`${item.year}${item.month}${i.text}`) &&
									selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) !== 0 &&
									selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) !== selectedDateStr.length - 8}
								class:dark:text-dark={mode === 'range' &&
									selectedDateStr.includes(`${item.year}${item.month}${i.text}`) &&
									selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) !== 0 &&
									selectedDateStr.indexOf(`${item.year}${item.month}${i.text}`) !== selectedDateStr.length - 8}
								class:border={item.year + item.month + i.text === todayStr && highlightToday}
								class:border-primary={item.year + item.month + i.text === todayStr && highlightToday}
								class:dark:border-dark={item.year + item.month + i.text === todayStr && highlightToday}
							>
								<div class="font-bold">
									{i.text ? Number(i.text) : ''}
								</div>
								<div class="text-xs opacity-50">{i.info || ''}</div>
							</div>
						</button>
					{/each}
				</div>
				{#if monthMark}
					<div
						class="pointer-events-none absolute w-full {monthMarkSizeClass[monthMarkSize as keyof typeof monthMarkSizeClass] ??
							'text-7xl'} left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 text-center font-bold text-black/5 {monthCard
							? 'dark:text-white/10'
							: 'dark:text-white/5'}"
					>
						{calendarLang.monthTextList[Number(item.month) - 1]}
					</div>
				{/if}
			</div>
		{/each}
	</div>
</div>



================================================
FILE: docs/site/src/routes/guide/generator/GeneratorPreview.svelte
================================================
<script lang="ts">
	import { Button, Switch, Progress, ProgressLoop, Loading, NoticeBar, Icon, Slider } from 'stdf';
	import Calendar from './Calendar.svelte';
	import { currentThemeStore } from '../../../store';

	const isZh = localStorage.getItem('lang') === 'zh_CN';
	const icons = ['ri-spy-fill', 'ri-chrome-fill', 'ri-riding-line', 'ri-switch-fill'];
	let textList = $derived(['请配置您喜欢的颜色主题！', '这是第一条测试通告！']);
	let textList_en = $derived(['Please configure the color theme you like!', 'This is the first test notice!']);
</script>

<NoticeBar textList={isZh ? textList : textList_en} />

<svg xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 614 383.76">
	<defs>
		<style>
			.cls-1 {
				isolation: isolate;
			}

			.cls-2 {
				fill: url(#linear-gradient);
			}

			.cls-3 {
				fill: red;
			}
			.cls-moon {
				fill: #fff;
			}

			.cls-4 {
				fill: url(#linear-gradient-2);
			}

			.cls-5 {
				fill: var(--color-primary-500);
				/* fill: #d35f5f; */
			}

			.cls-5-dark {
				fill: var(--color-dark-500);
				/* fill: #d35f5f; */
			}

			.cls-6 {
				fill: var(--color-primary-700);
				/* fill: #841818; */
			}

			.cls-6-dark {
				fill: var(--color-dark-800);
				/* fill: #841818; */
			}

			.cls-7 {
				opacity: 0.61;
				fill: url(#linear-gradient-3);
			}

			.cls-17,
			.cls-21,
			.cls-22,
			.cls-7,
			.cls-8 {
				mix-blend-mode: overlay;
			}

			.cls-8 {
				fill: url(#linear-gradient-4);
			}

			.cls-9 {
				fill: url(#linear-gradient-5);
			}

			.cls-10 {
				fill: url(#linear-gradient-6);
			}

			.cls-11 {
				fill: #260202;
			}

			.cls-12 {
				fill: url(#linear-gradient-7);
			}

			.cls-13 {
				fill: url(#linear-gradient-8);
			}

			.cls-14 {
				fill: url(#linear-gradient-9);
			}

			.cls-15 {
				fill: url(#linear-gradient-10);
			}

			.cls-16 {
				fill: url(#linear-gradient-11);
			}

			.cls-17 {
				fill: url(#linear-gradient-12);
			}

			.cls-18 {
				fill: url(#linear-gradient-13);
			}

			.cls-19 {
				fill: url(#linear-gradient-14);
			}

			.cls-20 {
				fill: url(#linear-gradient-15);
			}

			.cls-21 {
				fill: url(#linear-gradient-16);
			}

			.cls-22 {
				fill: url(#linear-gradient-17);
			}

			.cls-23 {
				fill: url(#linear-gradient-18);
			}

			.cls-24 {
				fill: url(#linear-gradient-19);
			}

			.cls-25 {
				fill: url(#linear-gradient-20);
			}

			.cls-26 {
				fill: url(#linear-gradient-21);
			}

			.cls-27 {
				fill: url(#linear-gradient-22);
			}

			.cls-28 {
				fill: url(#linear-gradient-23);
			}

			.cls-29 {
				fill: url(#linear-gradient-24);
			}

			.cls-30 {
				fill: url(#linear-gradient-25);
			}

			.cls-31 {
				opacity: 0.7;
				mix-blend-mode: screen;
				fill: url(#radial-gradient);
			}

			.cls-moon-light {
				opacity: 0.4;
				mix-blend-mode: screen;
				fill: url(#radial-gradient-moon);
			}
		</style>
		<!-- 背景 -->
		<linearGradient id="linear-gradient" x1="307" y1="369.32" x2="307" y2="23.88" gradientUnits="userSpaceOnUse">
			<stop offset="0" stop-color={$currentThemeStore === 'dark' ? 'var(--color-dark-400)' : 'var(--color-primary-50)'} />
			<stop offset="1" stop-color={$currentThemeStore === 'dark' ? 'var(--color-dark-800)' : 'var(--color-primary-500)'} />
		</linearGradient>
		<!-- 山 0 -->
		<linearGradient id="linear-gradient-2" x1="375" y1="390.15" x2="375" y2="207.5" xlink:href="#linear-gradient" />
		<!-- 浅色山与云 -->
		<linearGradient id="linear-gradient-3" x1="481.92" y1="363.2" x2="481.92" y2="267.14" gradientUnits="userSpaceOnUse">
			<stop offset="0" stop-color="#fff" stop-opacity="0" />
			<stop offset="0.12" stop-color="#fff" stop-opacity="0.18" />
			<stop offset="0.3" stop-color="#fff" stop-opacity="0.42" />
			<stop offset="0.48" stop-color="#fff" stop-opacity="0.63" />
			<stop offset="0.64" stop-color="#fff" stop-opacity="0.79" />
			<stop offset="0.78" stop-color="#fff" stop-opacity="0.91" />
			<stop offset="0.91" stop-color="#fff" stop-opacity="0.98" />
			<stop offset="1" stop-color="#fff" />
		</linearGradient>
		<!-- 山 1 -->
		<linearGradient id="linear-gradient-4" x1="293.94" y1="377.42" x2="299.58" y2="307.74" xlink:href="#linear-gradient-3" />
		<!-- 房子下土地 -->
		<linearGradient id="linear-gradient-5" x1="304.08" y1="357.53" x2="589.55" y2="357.53" gradientUnits="userSpaceOnUse">
			<stop
				offset="0"
				stop-color="rgba({$currentThemeStore === 'dark' ? 'var(--color-dark-900), 0.1)' : 'var(--color-primary-900), 0.1'})"
			/>
			<stop offset="1" stop-color={$currentThemeStore === 'dark' ? 'var(--color-dark-900)' : 'var(--color-primary-900)'} />
		</linearGradient>
		<!-- 小树 -->
		<linearGradient id="linear-gradient-6" x1="615.64" y1="385.54" x2="615.64" y2="337.77" gradientUnits="userSpaceOnUse">
			<stop offset="0" stop-color={$currentThemeStore === 'dark' ? 'var(--color-dark-700)' : 'var(--color-primary-700)'} />
			<stop offset="1" stop-color={$currentThemeStore === 'dark' ? 'var(--color-dark-500)' : 'var(--color-primary-500)'} />
		</linearGradient>
		<linearGradient id="linear-gradient-7" x1="645.03" y1="386.28" x2="645.03" y2="344.39" xlink:href="#linear-gradient-6" />
		<linearGradient id="linear-gradient-8" x1="530.63" y1="385.84" x2="530.63" y2="340.47" xlink:href="#linear-gradient-6" />
		<linearGradient id="linear-gradient-9" x1="395.26" y1="388.24" x2="395.26" y2="353.31" xlink:href="#linear-gradient-6" />
		<!-- 大树 -->
		<linearGradient id="linear-gradient-10" x1="89.92" y1="448.19" x2="226.82" y2="254.6" gradientUnits="userSpaceOnUse">
			<stop offset="0" stop-color={$currentThemeStore === 'dark' ? 'var(--color-darkBlack)' : 'var(--color-primaryBlack)'} />
			<stop offset="1" stop-color={$currentThemeStore === 'dark' ? 'var(--color-dark-800)' : 'var(--color-primary-800)'} />
		</linearGradient>
		<linearGradient id="linear-gradient-11" x1="141.89" y1="484.94" x2="278.79" y2="291.35" xlink:href="#linear-gradient-10" />
		<!-- 云 -->
		<linearGradient id="linear-gradient-12" x1="169.94" y1="166.78" x2="169.94" y2="82.46" xlink:href="#linear-gradient-3" />
		<!-- 小河 -->
		<linearGradient id="linear-gradient-13" x1="151.99" y1="365.33" x2="582.81" y2="365.33" xlink:href="#linear-gradient" />
		<!-- 土地 -->
		<linearGradient id="linear-gradient-14" x1="243.34" y1="586.07" x2="399.62" y2="365.09" xlink:href="#linear-gradient-10" />
		<linearGradient id="linear-gradient-15" x1="201.81" y1="475.52" x2="208" y2="401.64" xlink:href="#linear-gradient-10" />
		<!-- 云 -->
		<linearGradient id="linear-gradient-16" x1="500.15" y1="179.64" x2="862.56" y2="179.64" xlink:href="#linear-gradient-3" />
		<linearGradient id="linear-gradient-17" x1="532.11" y1="134.72" x2="532.11" y2="80.96" xlink:href="#linear-gradient-3" />
		<!-- 鸟 -->
		<linearGradient id="linear-gradient-18" x1="297.29" y1="245.04" x2="294.84" y2="236.16" xlink:href="#linear-gradient-10" />
		<linearGradient
			id="linear-gradient-19"
			x1="353.05"
			y1="283.25"
			x2="348.44"
			y2="266.53"
			gradientTransform="matrix(1, 0.01, -0.01, 1, 0.8, 4.06)"
			xlink:href="#linear-gradient-10"
		/>
		<linearGradient
			id="linear-gradient-20"
			x1="391.03"
			y1="260.57"
			x2="386.96"
			y2="245.77"
			gradientTransform="matrix(0.97, 0.26, -0.26, 0.97, 80.16, -79.02)"
			xlink:href="#linear-gradient-10"
		/>
		<linearGradient
			id="linear-gradient-21"
			x1="448.52"
			y1="222.49"
			x2="445.09"
			y2="210.06"
			gradientTransform="translate(108.87 -112.9) rotate(19.64)"
			xlink:href="#linear-gradient-10"
		/>
		<!-- 房 -->
		<linearGradient id="linear-gradient-22" x1="512.44" y1="317.53" x2="511.66" y2="307.93" xlink:href="#linear-gradient-6" />
		<linearGradient id="linear-gradient-23" x1="518.15" y1="344.39" x2="518.15" y2="315.46" xlink:href="#linear-gradient-10" />
		<linearGradient id="linear-gradient-24" x1="493.07" y1="353.96" x2="493.07" y2="305.26" xlink:href="#linear-gradient" />
		<linearGradient id="linear-gradient-25" x1="493.07" y1="334.45" x2="493.07" y2="312.8" xlink:href="#linear-gradient-10" />
		<!-- 日光晕 -->
		<radialGradient
			id="radial-gradient"
			cx="353.5"
			cy="241.44"
			r="179"
			gradientTransform="translate(274.26 -179.24) rotate(45)"
			gradientUnits="userSpaceOnUse"
		>
			<stop offset="0" stop-color="red" />
			<stop offset="1" />
		</radialGradient>
		<!-- 月光晕 -->
		<radialGradient
			id="radial-gradient-moon"
			cx="353.5"
			cy="241.44"
			r="179"
			gradientTransform="translate(274.26 -179.24) rotate(45)"
			gradientUnits="userSpaceOnUse"
		>
			<stop offset="0" stop-color="white" />
			<stop offset="1" />
		</radialGradient>
	</defs>
	<!-- <title>2623046</title> -->
	<!-- <g class="cls-1"> -->
	<g id="OBJECTS">
		<rect class="cls-2" width="614" height="383.76" />
		<!-- 太阳 -->
		<circle
			class="cls-3 transition-all duration-1000 dark:translate-y-full"
			cx="348.85"
			cy="246.41"
			r="32.45"
			transform="translate(-114.76 27.34) rotate(-13.1)"
		/>
		<!-- 月亮 -->
		<path
			class="cls-moon translate-y-full transition-all duration-1000 dark:translate-y-0"
			d="M311.533 177.529C308.429 178.533 305.117 179.075 301.679 179.075C284.01 179.075 269.687 164.752 269.687 147.083C269.687 141.22 271.265 135.725 274.018 131C260.177 134.77 250 147.428 250 162.464C250 180.472 264.599 195.071 282.607 195.071C295.181 195.071 306.092 187.954 311.533 177.529Z"
		/>

		<path
			class="cls-4"
			d="M618.71,258.8c-31.85,23.89-57.07,1.77-104-38.93-47.74-41.43-95.56,9.29-142,37.16S308.37,221.2,238,199.3c-64.75-20.16-125.43,2-170,29.33V441.88H682V264.06C657.67,234.51,642.92,240.64,618.71,258.8Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-5 dark:hidden"
			d="M549.25,273c-61.05-35.84-89.58,8-144,34.5s-84.93,20-207.71-46.45C147,233.67,103.56,227.38,68,231.24V441.88H682V219.05C613.42,213.69,602.69,304.32,549.25,273Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-5-dark hidden dark:block"
			d="M549.25,273c-61.05-35.84-89.58,8-144,34.5s-84.93,20-207.71-46.45C147,233.67,103.56,227.38,68,231.24V441.88H682V219.05C613.42,213.69,602.69,304.32,549.25,273Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6 dark:hidden"
			d="M604,364.53c-42.8-27.87-35.83-2-95.56,5s-93.23-86.6-169.21-64.7c-45.36,13.07-67,19.91-162.25-11.95-30-10-72.33,5.64-109,19.85V441.88H682V361.3C662.54,371.51,631.08,382.17,604,364.53Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6-dark hidden dark:block"
			d="M604,364.53c-42.8-27.87-35.83-2-95.56,5s-93.23-86.6-169.21-64.7c-45.36,13.07-67,19.91-162.25-11.95-30-10-72.33,5.64-109,19.85V441.88H682V361.3C662.54,371.51,631.08,382.17,604,364.53Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6 dark:hidden"
			d="M500.77,337.32c-4.93,0-8.92,8.06-8.92,18a34.64,34.64,0,0,0,.39,5.29,8.59,8.59,0,0,0,8.11,7.22v6.77a.42.42,0,1,0,.84,0v-6.77a8.6,8.6,0,0,0,8.12-7.22,36,36,0,0,0,.39-5.29C509.7,345.38,505.7,337.32,500.77,337.32Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6 dark:hidden"
			d="M567.8,330.69c-3.49,0-6.31,5.69-6.31,12.71a24.9,24.9,0,0,0,.28,3.74,6.05,6.05,0,0,0,5.73,5.1V357a.3.3,0,0,0,.59,0v-4.79a6.07,6.07,0,0,0,5.74-5.1,24.93,24.93,0,0,0,.27-3.74C574.1,336.38,571.28,330.69,567.8,330.69Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6 dark:hidden"
			d="M89.56,290.43c-3.16,0-5.71,5.15-5.71,11.5a23,23,0,0,0,.25,3.39,5.49,5.49,0,0,0,5.19,4.61v4.33a.27.27,0,1,0,.53,0v-4.33A5.49,5.49,0,0,0,95,305.32a23,23,0,0,0,.25-3.39C95.26,295.58,92.71,290.43,89.56,290.43Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6 dark:hidden"
			d="M120.66,281.36c-2.86,0-5.18,4.68-5.18,10.45a20.14,20.14,0,0,0,.23,3.07,5,5,0,0,0,4.71,4.19V303a.25.25,0,1,0,.49,0v-3.93a5,5,0,0,0,4.71-4.19,20.14,20.14,0,0,0,.23-3.07C125.85,286,123.52,281.36,120.66,281.36Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6 dark:hidden"
			d="M142.78,284.24c-2.34,0-4.24,3.82-4.24,8.54a17,17,0,0,0,.19,2.52,4.09,4.09,0,0,0,3.85,3.43v3.21a.2.2,0,0,0,.4,0v-3.21a4.1,4.1,0,0,0,3.86-3.43,17,17,0,0,0,.18-2.52C147,288.06,145.12,284.24,142.78,284.24Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6 dark:hidden"
			d="M375,291.65c-2.34,0-4.24,3.82-4.24,8.54a17,17,0,0,0,.19,2.52,4.09,4.09,0,0,0,3.85,3.43v3.21a.2.2,0,0,0,.4,0v-3.21a4.09,4.09,0,0,0,3.85-3.43,17,17,0,0,0,.19-2.52C379.28,295.47,377.38,291.65,375,291.65Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6 dark:hidden"
			d="M343.52,293.91c-2.1,0-3.8,3.43-3.8,7.65a14.68,14.68,0,0,0,.17,2.25,3.65,3.65,0,0,0,3.45,3.07v2.88a.18.18,0,0,0,.18.18.18.18,0,0,0,.17-.18v-2.88a3.64,3.64,0,0,0,3.45-3.07,14.68,14.68,0,0,0,.17-2.25C347.31,297.34,345.61,293.91,343.52,293.91Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6 dark:hidden"
			d="M320.29,303.65c-1.63,0-3,2.67-3,6a12.31,12.31,0,0,0,.13,1.75,2.85,2.85,0,0,0,2.69,2.39V316a.14.14,0,0,0,.28,0v-2.24a2.85,2.85,0,0,0,2.69-2.39,12.31,12.31,0,0,0,.13-1.75C323.25,306.32,321.92,303.65,320.29,303.65Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6 dark:hidden"
			d="M394.56,301.23c-1.64,0-3,2.67-3,6a12.31,12.31,0,0,0,.13,1.75,2.85,2.85,0,0,0,2.69,2.39v2.24a.14.14,0,0,0,.14.14.14.14,0,0,0,.14-.14v-2.24a2.83,2.83,0,0,0,2.68-2.39,11,11,0,0,0,.13-1.75C397.51,303.9,396.19,301.23,394.56,301.23Z"
			transform="translate(-68 -58.12)"
		/>
		<!-- dark tree -->
		<path
			class="cls-6-dark hidden dark:block"
			d="M500.77,337.32c-4.93,0-8.92,8.06-8.92,18a34.64,34.64,0,0,0,.39,5.29,8.59,8.59,0,0,0,8.11,7.22v6.77a.42.42,0,1,0,.84,0v-6.77a8.6,8.6,0,0,0,8.12-7.22,36,36,0,0,0,.39-5.29C509.7,345.38,505.7,337.32,500.77,337.32Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6-dark hidden dark:block"
			d="M567.8,330.69c-3.49,0-6.31,5.69-6.31,12.71a24.9,24.9,0,0,0,.28,3.74,6.05,6.05,0,0,0,5.73,5.1V357a.3.3,0,0,0,.59,0v-4.79a6.07,6.07,0,0,0,5.74-5.1,24.93,24.93,0,0,0,.27-3.74C574.1,336.38,571.28,330.69,567.8,330.69Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6-dark hidden dark:block"
			d="M89.56,290.43c-3.16,0-5.71,5.15-5.71,11.5a23,23,0,0,0,.25,3.39,5.49,5.49,0,0,0,5.19,4.61v4.33a.27.27,0,1,0,.53,0v-4.33A5.49,5.49,0,0,0,95,305.32a23,23,0,0,0,.25-3.39C95.26,295.58,92.71,290.43,89.56,290.43Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6-dark hidden dark:block"
			d="M120.66,281.36c-2.86,0-5.18,4.68-5.18,10.45a20.14,20.14,0,0,0,.23,3.07,5,5,0,0,0,4.71,4.19V303a.25.25,0,1,0,.49,0v-3.93a5,5,0,0,0,4.71-4.19,20.14,20.14,0,0,0,.23-3.07C125.85,286,123.52,281.36,120.66,281.36Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6-dark hidden dark:block"
			d="M142.78,284.24c-2.34,0-4.24,3.82-4.24,8.54a17,17,0,0,0,.19,2.52,4.09,4.09,0,0,0,3.85,3.43v3.21a.2.2,0,0,0,.4,0v-3.21a4.1,4.1,0,0,0,3.86-3.43,17,17,0,0,0,.18-2.52C147,288.06,145.12,284.24,142.78,284.24Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6-dark hidden dark:block"
			d="M375,291.65c-2.34,0-4.24,3.82-4.24,8.54a17,17,0,0,0,.19,2.52,4.09,4.09,0,0,0,3.85,3.43v3.21a.2.2,0,0,0,.4,0v-3.21a4.09,4.09,0,0,0,3.85-3.43,17,17,0,0,0,.19-2.52C379.28,295.47,377.38,291.65,375,291.65Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6-dark hidden dark:block"
			d="M343.52,293.91c-2.1,0-3.8,3.43-3.8,7.65a14.68,14.68,0,0,0,.17,2.25,3.65,3.65,0,0,0,3.45,3.07v2.88a.18.18,0,0,0,.18.18.18.18,0,0,0,.17-.18v-2.88a3.64,3.64,0,0,0,3.45-3.07,14.68,14.68,0,0,0,.17-2.25C347.31,297.34,345.61,293.91,343.52,293.91Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6-dark hidden dark:block"
			d="M320.29,303.65c-1.63,0-3,2.67-3,6a12.31,12.31,0,0,0,.13,1.75,2.85,2.85,0,0,0,2.69,2.39V316a.14.14,0,0,0,.28,0v-2.24a2.85,2.85,0,0,0,2.69-2.39,12.31,12.31,0,0,0,.13-1.75C323.25,306.32,321.92,303.65,320.29,303.65Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-6-dark hidden dark:block"
			d="M394.56,301.23c-1.64,0-3,2.67-3,6a12.31,12.31,0,0,0,.13,1.75,2.85,2.85,0,0,0,2.69,2.39v2.24a.14.14,0,0,0,.14.14.14.14,0,0,0,.14-.14v-2.24a2.83,2.83,0,0,0,2.68-2.39,11,11,0,0,0,.13-1.75C397.51,303.9,396.19,301.23,394.56,301.23Z"
			transform="translate(-68 -58.12)"
		/>
		<!-- dark tree -->
		<path
			class="cls-7"
			d="M682,302.9V403H281.83S369.2,293.31,468.3,323.39c33.32,10.11,81.84,21.23,142.45-17.92C635.58,289.43,661.35,293.63,682,302.9Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-8"
			d="M434.45,360.55c-29.86-19.91-47.78,32.52-127.41-11.28S236.7,324.05,177,331.35c-37.86,4.63-81.84-.61-109-5.07v115.6H518.8C490.07,411.33,451.9,372.18,434.45,360.55Z"
			transform="translate(-68 -58.12)"
		/>
		<rect class="cls-9" y="331.3" width="614" height="52.46" />
		<path
			class="cls-10"
			d="M615.64,382.29a11.18,11.18,0,0,0,11.09-9.41,46.08,46.08,0,0,0,.51-6.88c0-12.92-5.2-23.39-11.6-23.39S604,353.08,604,366a46.08,46.08,0,0,0,.51,6.88,11.18,11.18,0,0,0,11.1,9.41Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-11"
			d="M619.84,358.34a.55.55,0,0,0-.77,0l-2.89,2.89v-7a.55.55,0,0,0-1.09,0v15.39l-4.92-4.92a.54.54,0,0,0-.77.77l5.69,5.69v19.87a.55.55,0,0,0,1.09,0V362.76l0,0,3.64-3.63A.55.55,0,0,0,619.84,358.34Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-12"
			d="M645,383.44a9.81,9.81,0,0,0,9.73-8.26,40.22,40.22,0,0,0,.45-6c0-11.33-4.56-20.51-10.18-20.51s-10.17,9.18-10.17,20.51a40.25,40.25,0,0,0,.44,6,9.82,9.82,0,0,0,9.73,8.26Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-11"
			d="M648.72,362.43a.48.48,0,0,0-.68,0L645.51,365v-6.09a.48.48,0,1,0-1,0v13.49l-4.32-4.31a.48.48,0,0,0-.68,0,.48.48,0,0,0,0,.67l5,5v17.42a.48.48,0,1,0,1,0V366.31l0,0,3.19-3.19A.48.48,0,0,0,648.72,362.43Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-13"
			d="M530.63,382.76a10.63,10.63,0,0,0,10.54-8.94,42.87,42.87,0,0,0,.49-6.54c0-12.27-4.94-22.21-11-22.21s-11,9.94-11,22.21a42.87,42.87,0,0,0,.49,6.54,10.63,10.63,0,0,0,10.53,8.94Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-11"
			d="M534.63,360a.5.5,0,0,0-.73,0l-2.75,2.74v-6.61a.52.52,0,0,0-1,0v14.62l-4.68-4.67a.52.52,0,0,0-.73.73l5.41,5.4v18.87a.52.52,0,1,0,1,0V364.2h0l3.46-3.45A.52.52,0,0,0,534.63,360Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-14"
			d="M395.26,385.86a8.16,8.16,0,0,0,8.11-6.88,32.49,32.49,0,0,0,.38-5c0-9.45-3.8-17.11-8.49-17.11s-8.48,7.66-8.48,17.11a33.8,33.8,0,0,0,.37,5,8.18,8.18,0,0,0,8.11,6.88Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-11"
			d="M398.34,368.35a.4.4,0,0,0-.57,0l-2.11,2.11v-5.09a.39.39,0,0,0-.4-.39.38.38,0,0,0-.39.39v11.26l-3.6-3.6a.4.4,0,0,0-.57,0,.4.4,0,0,0,0,.56l4.17,4.16v14.53a.39.39,0,0,0,.39.4.4.4,0,0,0,.4-.4v-20.7h0l2.66-2.66A.4.4,0,0,0,398.34,368.35Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-15"
			d="M197.81,242c-15.54,0-28.14,25.4-28.14,56.73a110.33,110.33,0,0,0,1.24,16.69,27.08,27.08,0,0,0,25.58,22.78v21.35a1.32,1.32,0,0,0,2.64,0V338.19a27.1,27.1,0,0,0,25.59-22.78A110.33,110.33,0,0,0,226,298.72C226,267.39,213.36,242,197.81,242Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-16"
			d="M264.47,266c-13.21,0-23.92,21.59-23.92,48.22a95,95,0,0,0,1,14.19,23,23,0,0,0,21.75,19.36v18.15a1.12,1.12,0,0,0,2.24,0V347.79a23,23,0,0,0,21.76-19.36,95,95,0,0,0,1-14.19C288.4,287.61,277.69,266,264.47,266Z"
			transform="translate(-68 -58.12)"
		/>
		<rect class="cls-18" y="346.89" width="614" height="36.87" />
		<path
			class="cls-19"
			d="M682,421.93c-84.8.85-250.57,1.52-382.92-48.11C203.52,338,116.6,343.55,68,357.91v84H682Z"
			transform="translate(-68 -58.12)"
		/>
		<path class="cls-20" d="M68,398.32v43.56H344.91C244.58,381.37,128.79,388.5,68,398.32Z" transform="translate(-68 -58.12)" />
		<!-- 云 -->
		<path
			class="cls-17 dark:hidden"
			d="M271.87,160.77H68V127.89c12.36-7.71,30.21-15.11,43.12-4.78,21.72,17.38,34.27-7.24,49.24,4.83s26.07,26.55,56.48,15.45S271.87,160.77,271.87,160.77Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-21 dark:hidden"
			d="M682,164.66c-6-2.15-12.2-2.09-17.28,2.78-15.93,15.27-52.42-16.59-67.69,4s-92.9.66-96.88,24.55H682Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-22 animate-cloudMove dark:hidden"
			d="M519.5,117.79c17.43,8.5,31.58-9.9,42.64,2.48s36.55.17,50.27,15.21H451.82S489,102.91,519.5,117.79Z"
			transform="translate(-68 -58.12)"
		/>
		<!-- 鸟 -->
		<path
			class="cls-23 dark:hidden"
			d="M294.88,236.75s-1.44-1.72-4.16-.42a4.77,4.77,0,0,1,4.6,2.7s.95-3.86,3.39-4C298.71,235.05,296.84,234.18,294.88,236.75Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-24 dark:hidden"
			d="M346.92,274.81s-2.68-3.26-7.82-.87c0,0,5.35-.71,8.61,5.17,0,0,1.87-7.25,6.45-7.44C354.16,271.67,350.65,270,346.92,274.81Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-25 dark:hidden"
			d="M390.73,259s-1.58-3.39-6.51-2.47c0,0,4.74.56,6.24,6.32,0,0,3.19-5.8,7.16-4.95C397.62,257.86,395,255.66,390.73,259Z"
			transform="translate(-68 -58.12)"
		/>
		<path
			class="cls-26 dark:hidden"
			d="M457.22,235.33s-1.09-3-5.28-2.52c0,0,3.93.8,4.79,5.73,0,0,3.08-4.64,6.34-3.65C463.07,234.89,461,232.87,457.22,235.33Z"
			transform="translate(-68 -58.12)"
		/>
		<!-- 鸟 -->
		<polygon class="cls-27" points="530.69 315.91 505.61 315.91 493.13 306.1 518.22 306.1 530.69 315.91" />
		<rect class="cls-28" x="505.61" y="315.91" width="25.08" height="22.41" />
		<polygon class="cls-29" points="505.61 315.91 505.61 338.32 480.52 338.32 480.52 315.91 493.13 306.1 505.61 315.91" />
		<polygon class="cls-30" points="498.64 324.83 498.64 317.54 493.1 313.17 487.49 317.54 487.49 324.83 498.64 324.83" />
		<circle class="cls-31 dark:hidden" cx="353.5" cy="241.44" r="179" transform="translate(-135.18 262.55) rotate(-45)" />
		<circle class="cls-moon-light hidden dark:block" cx="353.5" cy="241.44" r="179" transform="translate(-135.18 262.55) rotate(-45)" />
		<!-- star -->
		<path
			class="animate-starTwinkle hidden dark:block"
			d="M102 27.5C102 34.0667 105.441 39.5384 110 40.75C105.441 41.9616 102 47.4333 102 54C102 47.4333 98.5591 41.9616 94 40.75C98.5591 39.5384 102 34.0667 102 27.5Z"
			fill="#fff"
		/>
		<path
			class="animate-starTwinkle2 hidden dark:block"
			d="M555 21.4444C555 27.2815 558.011 32.1452 562 33.2222C558.011 34.2992 555 39.1629 555 45C555 39.1629 551.989 34.2992 548 33.2222C551.989 32.1452 555 27.2815 555 21.4444Z"
			fill="#fff"
		/>
		<path
			class="animate-starTwinkle3 hidden dark:block"
			d="M366 27.3333C366 31.7112 368.151 35.3589 371 36.1667C368.151 36.9744 366 40.6222 366 45C366 40.6222 363.849 36.9744 361 36.1667C363.849 35.3589 366 31.7112 366 27.3333Z"
			fill="#fff"
		/>
		<path
			class="animate-starTwinkle4 hidden dark:block"
			d="M534 94.3333C534 98.7112 536.151 102.359 539 103.167C536.151 103.974 534 107.622 534 112C534 107.622 531.849 103.974 529 103.167C531.849 102.359 534 98.7112 534 94.3333Z"
			fill="#fff"
		/>
	</g>
	<!-- </g> -->
</svg>

<div class="flex justify-between gap-4 p-4">
	<div class="w-1/3">
		<ProgressLoop />
	</div>
	<div class="flex flex-1 flex-col justify-between py-2">
		<div class="flex justify-around">
			<Loading theme />
			<Loading theme type="1_30" />
			<Loading theme type="1_13" />
		</div>
		<div class="flex justify-around">
			<Switch active />
			<Switch active injClass="bg-success dark:bg-success" />
			<Switch active injClass="!bg-error dark:!bg-error" />
		</div>
	</div>
</div>
<div class="flex flex-col gap-4 p-4">
	<Progress />
</div>
<div class="flex flex-wrap justify-between">
	{#each icons as icon}
		<div class="flex-1 py-2 text-center">
			<Icon name={icon} theme />
		</div>
	{/each}
</div>
<div class="p-4">
	<Slider />
</div>
<Button>{isZh ? '按钮' : 'Button'}</Button>
<Calendar />



================================================
FILE: docs/site/src/routes/guide/icon/+page.svelte
================================================
<script lang="ts">
	import { mdTextToHljs } from '../../../utils/index';
	import { isWideScreenStore } from '../../../store';

	// @ts-ignore
	import text from '../../../../../mds/guide/icon.md';
	// @ts-ignore
	import text_en from '../../../../../mds/guide/icon_en.md';

	const isZh = localStorage.getItem('lang') === 'zh_CN';
	const hljsText = mdTextToHljs((isZh ? text : text_en).replace(/<a href="/g, '<a target="_blank" href="'));
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto pb-8 {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	<!-- eslint-disable-next-line svelte/no-at-html-tags -->
	{@html hljsText}
</article>



================================================
FILE: docs/site/src/routes/guide/icon-plugin/+page.svelte
================================================
<script lang="ts">
	import { mdTextToHljs, groupIconMdPlugin } from '../../../utils/index';
	import { isWideScreenStore } from '../../../store';

	// @ts-ignore
	import iconPluginText from '../../../../../../packages/rollup-plugin-stdf-icon/README_CN.md';
	// @ts-ignore
	import iconPluginText_en from '../../../../../../packages/rollup-plugin-stdf-icon/README.md';

	const isZh = localStorage.getItem('lang') === 'zh_CN';
	const text = mdTextToHljs(
		(isZh ? groupIconMdPlugin(iconPluginText) : groupIconMdPlugin(iconPluginText_en)).replace(/<a href="/g, '<a target="_blank" href="')
	);
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto pb-8 {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	<!-- eslint-disable-next-line svelte/no-at-html-tags -->
	{@html text}
</article>



================================================
FILE: docs/site/src/routes/guide/internation/+page.svelte
================================================
<script lang="ts">
	import { mdTextToHljs } from '../../../utils/index';
	import { isWideScreenStore } from '../../../store';

	// @ts-ignore
	import text from '../../../../../mds/guide/internation.md';
	// @ts-ignore
	import text_en from '../../../../../mds/guide/internation_en.md';

	const isZh = localStorage.getItem('lang') === 'zh_CN';
	const hljsText = mdTextToHljs((isZh ? text : text_en).replace(/<a href="/g, '<a target="_blank" href="'));
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto pb-8 {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	<!-- eslint-disable-next-line svelte/no-at-html-tags -->
	{@html hljsText}
</article>



================================================
FILE: docs/site/src/routes/guide/logo/+page.svelte
================================================
<script lang="ts">
	import { isWideScreenStore } from '../../../store';
</script>

<div class="mx-auto {$isWideScreenStore ? 'max-w-full' : 'max-w-7xl'}">
	<div class="mb-4 flex justify-around gap-3 text-9xl font-bold md:justify-start md:gap-10">
		<div class="text-dark dark:text-primary">S</div>
		<div class="text-primary dark:text-dark">T</div>
		<div class="text-primary dark:text-dark">D</div>
		<div class="text-primary dark:text-dark">F</div>
	</div>
	<div class="max-w-full md:max-w-md">
		<svg class="w-full" viewBox="0 0 91 81" fill="none" xmlns="http://www.w3.org/2000/svg">
			<path
				fill-rule="evenodd"
				clip-rule="evenodd"
				d="M0 1H50C64.8057 1 77.7325 9.04398 84.6487 21H50H40V31H50C55.5229 31 60 35.4771 60 41C60 46.5229 55.5229 51 50 51H40V81H20V21H0V1ZM90 41C90 63.0914 72.0914 81 50 81V61C61.0457 61 70 52.0457 70 41C70 37.3571 69.0261 33.9417 67.3243 31H88.7398C89.5625 34.1962 90 37.547 90 41Z"
				class="fill-primary dark:fill-dark"
			/>
			<path fill-rule="evenodd" clip-rule="evenodd" d="M20 1V31H40L20 81V51H0L20 1Z" class="fill-dark dark:fill-primary" />
			<line y1="0.9" x2="90" y2="0.9" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line y1="10.9" x2="90" y2="10.9" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line y1="20.9" x2="90" y2="20.9" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line y1="30.9" x2="90" y2="30.9" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line y1="40.9" x2="90" y2="40.9" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line y1="50.9" x2="90" y2="50.9" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line y1="60.9" x2="90" y2="60.9" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line y1="70.9" x2="90" y2="70.9" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line y1="80.9" x2="90" y2="80.9" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line x1="0.1" y1="1" x2="0.0999965" y2="81" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line x1="10.1" y1="1" x2="10.1" y2="81" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line x1="20.1" y1="1" x2="20.1" y2="81" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line x1="30.1" y1="1" x2="30.1" y2="81" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line x1="40.1" y1="1" x2="40.1" y2="81" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line x1="50.1" y1="1" x2="50.1" y2="81" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line x1="60.1" y1="1" x2="60.1" y2="81" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line x1="70.1" y1="1" x2="70.1" y2="81" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line x1="80.1" y1="1" x2="80.1" y2="81" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<line x1="90.1" y1="1" x2="90.1" y2="81" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<circle cx="50" cy="41" r="39.9" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<circle cx="50" cy="41" r="19.9" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
			<circle cx="50" cy="41" r="9.9" class="stroke-gray-400 dark:stroke-gray-600" stroke-width="0.2" stroke-dasharray="2 2" />
		</svg>
	</div>
</div>



================================================
FILE: docs/site/src/routes/guide/md/+page.svelte
================================================
<script lang="ts">
	import { mdTextToHljs, groupIconMdPlugin } from '../../../utils/index';
	import { isWideScreenStore } from '../../../store';

	// @ts-ignore
	import mdPluginText from '../../../../../../packages/rollup-plugin-md-ts/README_CN.md';
	// @ts-ignore
	import mdPluginText_en from '../../../../../../packages/rollup-plugin-md-ts/README.md';

	const isZh = localStorage.getItem('lang') === 'zh_CN';
	const text = mdTextToHljs(
		(isZh ? groupIconMdPlugin(mdPluginText) : groupIconMdPlugin(mdPluginText_en)).replace(/<a href="/g, '<a target="_blank" href="')
	);
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto pb-8 {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	<!-- eslint-disable-next-line svelte/no-at-html-tags -->
	{@html text}
</article>



================================================
FILE: docs/site/src/routes/guide/milestone/+page.svelte
================================================
<script lang="ts">
	import { mdTextToHljs } from '../../../utils/index';
	import { isWideScreenStore } from '../../../store';

	// @ts-ignore
	import text from '../../../../../mds/guide/milestone.md';
	// @ts-ignore
	import text_en from '../../../../../mds/guide/milestone_en.md';

	const isZh = localStorage.getItem('lang') === 'zh_CN';

	const hljsText = mdTextToHljs((isZh ? text : text_en).replace(/<a href="/g, '<a target="_blank" href="'));
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto pb-8 {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	<!-- eslint-disable-next-line svelte/no-at-html-tags -->
	{@html hljsText}
</article>



================================================
FILE: docs/site/src/routes/guide/shortkey/+page.svelte
================================================
<script lang="ts">
	import { isWideScreenStore } from '../../../store';

	const isZh = localStorage.getItem('lang') === 'zh_CN';
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto hidden pb-8 md:block {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	{#if isZh}
		<h2>全站</h2>
		<ul>
			<li>唤起或关闭组件快速搜索框：<b>⌘ + K（Ctrl + K）</b>。</li>
			<li>快速搜索显示时：上下方向键切换选项，回车键选择，ESC 键聚焦输入框或关闭。</li>
		</ul>
		<h2>组件页面</h2>
		<ul>
			<li>上下方向键切换组件，左右方向键切换选项卡。</li>
		</ul>
	{:else}
		<h2>The whole website</h2>
		<ul>
			<li>Call up or close the component quick search box: <b>⌘ + K（Ctrl + K）</b>.</li>
			<li>
				When the quick search is displayed: use the up and down arrow keys to switch options, the enter key to select, and the ESC key to
				focus the input box or close it.
			</li>
		</ul>
		<h2>Componenst page</h2>
		<ul>
			<li>Use the up and down arrow keys to switch components, and the left and right arrow keys to switch tabs.</li>
		</ul>
	{/if}
</article>

<article class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark block max-w-5xl pb-12 md:hidden">
	{#if isZh}
		<p>快捷键仅用于桌面端。</p>
	{:else}
		<p>Keyboard shortcuts are only available on the desktop site.</p>
	{/if}
</article>



================================================
FILE: docs/site/src/routes/guide/theme/+page.svelte
================================================
<script lang="ts">
	import { mdTextToHljs } from '../../../utils/index';
	import { isWideScreenStore } from '../../../store';

	// @ts-ignore
	import theme from '../../../../../mds/guide/theme.md';
	// @ts-ignore
	import theme_en from '../../../../../mds/guide/theme_en.md';

	const isZh = localStorage.getItem('lang') === 'zh_CN';
	const text = mdTextToHljs((isZh ? theme : theme_en).replace(/<a href="/g, '<a target="_blank" href="'));
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto pb-12 {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	<!-- eslint-disable-next-line svelte/no-at-html-tags -->
	{@html text}
</article>



================================================
FILE: docs/site/src/routes/guide/vscode/+page.svelte
================================================
<script lang="ts">
	import { mdTextToHljs } from '../../../utils/index';
	import { isWideScreenStore } from '../../../store';

	// @ts-ignore
	import text from '../../../../../mds/guide/vscode.md';
	// @ts-ignore
	import text_en from '../../../../../mds/guide/vscode_en.md';

	const isZh = localStorage.getItem('lang') === 'zh_CN';
	const hljsText = mdTextToHljs((isZh ? text : text_en).replace(/<a href="/g, '<a target="_blank" href="'));
</script>

<article
	class="prose dark:prose-invert prose-strong:text-primary dark:prose-strong:text-dark mx-auto pb-8 {$isWideScreenStore
		? 'max-w-full'
		: 'max-w-7xl'}"
>
	<!-- eslint-disable-next-line svelte/no-at-html-tags -->
	{@html hljsText}
</article>



================================================
FILE: docs/site/src/utils/code-group-svg-data.js
================================================
export default [
	{
		name: 'pnpm',
		cli: 'pnpm create stdf',
		svg: '<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="#f9ad00" d="M30 10.75h-8.749V2H30Zm-9.626 0h-8.75V2h8.75Zm-9.625 0H2V2h8.749ZM30 20.375h-8.749v-8.75H30Z"/><path fill="#4e4e4e" d="M20.374 20.375h-8.75v-8.75h8.75Zm0 9.625h-8.75v-8.75h8.75ZM30 30h-8.749v-8.75H30Zm-19.251 0H2v-8.75h8.749Z"/></svg>'
	},
	{
		name: 'npm',
		cli: 'npm create stdf@latest',
		svg: '<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><path fill="#c12127" d="M0 256V0h256v256z"/><path fill="#fff" d="M48 48h160v160h-32V80h-48v128H48z"/></svg>'
	},
	{
		name: 'bun',
		cli: 'bun create stdf',
		svg: '<svg xmlns="http://www.w3.org/2000/svg" width="1.14em" height="1em" viewBox="0 0 256 225"><path d="M228.747 65.588a38 38 0 0 0-1.62-1.62c-.55-.519-1.07-1.102-1.62-1.62c-.551-.52-1.07-1.102-1.62-1.62c-.551-.52-1.07-1.103-1.62-1.621c-.552-.519-1.07-1.102-1.62-1.62c-.552-.519-1.07-1.102-1.621-1.62c-.551-.52-1.07-1.102-1.62-1.62a85.74 85.74 0 0 1 25.632 59.819c0 53.695-54.505 97.377-121.519 97.377c-37.525 0-71.097-13.707-93.424-35.192l1.62 1.62l1.62 1.62l1.62 1.62l1.621 1.621l1.62 1.62l1.62 1.62l1.621 1.62c22.295 22.393 56.612 36.813 95.044 36.813c67.014 0 121.519-43.682 121.519-97.215c0-22.878-9.851-44.557-27.253-61.602"/><path fill="#fbf0df" d="M234.937 114.066c0 49.288-50.779 89.243-113.418 89.243S8.101 163.354 8.101 114.066c0-30.558 19.443-57.552 49.32-73.56C87.3 24.498 105.9 8.101 121.52 8.101s28.97 13.384 64.097 32.405c29.878 16.008 49.32 43.002 49.32 73.56"/><path fill="#f6dece" d="M234.937 114.066a70.2 70.2 0 0 0-2.593-18.73c-8.846 107.909-140.476 113.093-192.227 80.818a129.62 129.62 0 0 0 81.402 27.155c62.542 0 113.418-40.02 113.418-89.243"/><path fill="#fffefc" d="M77.87 34.576c14.484-8.684 33.733-24.984 52.658-25.017a30.1 30.1 0 0 0-9.009-1.458c-7.842 0-16.203 4.05-26.734 10.143c-3.662 2.139-7.453 4.504-11.472 6.967c-7.55 4.666-16.202 9.948-25.924 15.23c-30.85 16.69-49.288 44.201-49.288 73.625v3.856C27.74 48.542 63.417 43.261 77.87 34.576"/><path fill="#ccbea7" d="M112.186 16.3a53.18 53.18 0 0 1-18.244 40.409c-.907.81-.194 2.365.972 1.912c10.92-4.245 25.665-16.948 19.443-42.58c-.259-1.459-2.17-1.07-2.17.259m7.356 0a52.63 52.63 0 0 1 5.217 43.65c-.388 1.134 1.005 2.106 1.783 1.166c7.096-9.073 13.286-27.09-5.25-46.534c-.94-.842-2.398.454-1.75 1.588zm8.944-.551a53.2 53.2 0 0 1 22.198 38.108a1.07 1.07 0 0 0 2.106.357c2.981-11.31 1.296-30.59-23.235-40.604c-1.296-.518-2.138 1.232-1.069 2.01zM68.666 49.45a54.9 54.9 0 0 0 33.928-29.164c.584-1.167 2.43-.713 2.14.583c-5.607 25.924-24.37 31.336-36.035 30.623c-1.232.032-1.2-1.685-.033-2.042"/><path d="M121.519 211.443C54.505 211.443 0 167.761 0 114.066c0-32.405 20.026-62.64 53.566-80.754c9.721-5.184 18.05-10.402 25.47-14.97c4.083-2.528 7.94-4.894 11.666-7.097C102.076 4.505 111.797 0 121.519 0s18.212 3.889 28.84 10.175c3.241 1.847 6.482 3.856 9.949 6.06c8.069 4.99 17.175 10.629 29.164 17.077c33.54 18.115 53.566 48.316 53.566 80.754c0 53.695-54.505 97.377-121.519 97.377m0-203.342c-7.842 0-16.203 4.05-26.734 10.143c-3.662 2.139-7.453 4.504-11.472 6.967c-7.55 4.666-16.202 9.948-25.924 15.23c-30.85 16.69-49.288 44.201-49.288 73.625c0 49.223 50.876 89.276 113.418 89.276s113.418-40.053 113.418-89.276c0-29.424-18.439-56.936-49.32-73.56c-12.25-6.48-21.81-12.573-29.554-17.369c-3.532-2.17-6.773-4.18-9.722-5.962c-9.818-5.833-16.98-9.074-24.822-9.074"/><path fill="#b71422" d="M144.365 137.722a28.94 28.94 0 0 1-9.463 15.263a22.07 22.07 0 0 1-12.962 6.092a22.17 22.17 0 0 1-13.383-6.092a28.94 28.94 0 0 1-9.333-15.263a2.333 2.333 0 0 1 2.593-2.625h39.988a2.333 2.333 0 0 1 2.56 2.625"/><path fill="#ff6164" d="M108.557 153.244a22.4 22.4 0 0 0 13.351 6.157a22.4 22.4 0 0 0 13.318-6.157a34.5 34.5 0 0 0 3.241-3.468a22.13 22.13 0 0 0-15.879-7.485a19.93 19.93 0 0 0-16.202 9.008c.745.681 1.393 1.33 2.171 1.945"/><path d="M109.076 150.684a17.37 17.37 0 0 1 13.577-6.74a19.44 19.44 0 0 1 12.962 5.476a51 51 0 0 0 2.139-2.495a22.68 22.68 0 0 0-15.263-6.254a20.61 20.61 0 0 0-15.846 7.647a31 31 0 0 0 2.43 2.366"/><path d="M121.81 161.021a24.05 24.05 0 0 1-14.42-6.481a30.85 30.85 0 0 1-10.077-16.365a3.89 3.89 0 0 1 .842-3.24a4.57 4.57 0 0 1 3.662-1.653h39.988a4.67 4.67 0 0 1 3.661 1.653a3.86 3.86 0 0 1 .81 3.24A30.85 30.85 0 0 1 136.2 154.54c-3.93 3.717-9 6-14.388 6.481m-19.993-23.98c-.519 0-.648.227-.68.292a26.86 26.86 0 0 0 8.846 14.16a20.2 20.2 0 0 0 11.828 5.672a20.35 20.35 0 0 0 11.828-5.606a26.9 26.9 0 0 0 8.814-14.161a.68.68 0 0 0-.648-.292z"/><g transform="translate(53.792 88.4)"><ellipse cx="117.047" cy="40.183" fill="#febbd0" rx="18.957" ry="11.147"/><ellipse cx="18.957" cy="40.183" fill="#febbd0" rx="18.957" ry="11.147"/><path d="M27.868 35.71a17.855 17.855 0 1 0-17.822-17.854c0 9.848 7.974 17.837 17.822 17.855m80.268 0A17.855 17.855 0 1 0 90.41 17.857c-.018 9.818 7.908 17.801 17.726 17.855"/><path fill="#fff" d="M22.36 18.99a6.708 6.708 0 1 0 .064-13.416a6.708 6.708 0 0 0-.065 13.416m80.267 0a6.708 6.708 0 1 0-.065 0z"/></g></svg>'
	},
	{
		name: 'yarn',
		cli: 'yarn create stdf',
		svg: '<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="#2188b6" d="M28.208 24.409a10.5 10.5 0 0 0-3.959 1.822a23.7 23.7 0 0 1-5.835 2.642a1.63 1.63 0 0 1-.983.55a62 62 0 0 1-6.447.577c-1.163.009-1.876-.3-2.074-.776a1.573 1.573 0 0 1 .866-2.074a4 4 0 0 1-.514-.379c-.171-.171-.352-.514-.406-.388c-.225.55-.343 1.894-.947 2.5c-.83.839-2.4.559-3.328.072c-1.019-.541.072-1.813.072-1.813a.73.73 0 0 1-.992-.343a4.85 4.85 0 0 1-.667-2.949a5.37 5.37 0 0 1 1.749-2.895a9.3 9.3 0 0 1 .658-4.4a10.45 10.45 0 0 1 3.165-3.661S6.628 10.747 7.35 8.817c.469-1.262.658-1.253.812-1.308a3.6 3.6 0 0 0 1.452-.857a5.27 5.27 0 0 1 4.41-1.7S15.2 1.4 16.277 2.09a18.4 18.4 0 0 1 1.533 2.886s1.281-.748 1.425-.469a11.33 11.33 0 0 1 .523 6.132a14 14 0 0 1-2.6 5.411c-.135.225 1.551.938 2.615 3.887c.983 2.7.108 4.96.262 5.212c.027.045.036.063.036.063s1.127.09 3.391-1.308a8.5 8.5 0 0 1 4.277-1.604a1.081 1.081 0 0 1 .469 2.11Z"/></svg>'
	}
];



================================================
FILE: docs/site/src/utils/index.ts
================================================
import Color from 'color';
import { oklch, parse, formatHex } from 'culori';
import codeGroupSvgData from './code-group-svg-data';
import hljs from 'highlight.js';
// @ts-expect-error - highlightjs-svelte 缺少类型定义
import hljs_svelte from 'highlightjs-svelte';

hljs_svelte(hljs);

/**
 * 节流，每 n 毫秒执行一次
 * @param {function} func - 需要节流的函数
 * @param {number} wait - 节流的时间间隔
 * @returns {function} - 返回节流后的函数
 * @example
 * const throttleFunc = throttle(() => console.log(123), 1000)
 */
export const throttle = <T extends (...args: unknown[]) => void>(func: T, wait: number = 100) => {
	let timer: null | ReturnType<typeof setInterval> = null;
	return function (...args: Parameters<T>) {
		if (timer) {
			return;
		}
		timer = setTimeout(() => {
			func(...args);
			timer = null;
		}, wait);
	};
};

/**
 * 字符过滤器，防止 HTML 的特殊字符如 <、>、& 等被转义
 * @param {string} text - 需要处理的字符串
 * @returns {string} - 返回处理后的字符串
 * @example
 * htmlFilter('<div>123</div>') // <div>123</div>
 */
const htmlFilter = (text: string) => {
	// 抽离成可配置的匹配列表
	const matchList = {
		'&lt;': '<',
		'&gt;': '>',
		'&amp;': '&',
		'&#34;': '"',
		'&quot;': '"',
		'&#39;': "'"
	};
	let regStr = '(' + Object.keys(matchList).toString() + ')';
	// ↑ ------------【*提取匹配列表 key 值*】.【组数转字符串】
	regStr = regStr.replace(/,/g, ')|(');
	// ↑ 通过匹配将其更新为正则的字符串类型
	const regExp = new RegExp(regStr, 'g');
	// ↑ ------- 字符串 转 正则 方法
	return text.replace(regExp, (match) => matchList[match as keyof typeof matchList]);
	// ↑ ------ 替换方法 (正则，当前 key => 返回当前被匹配的 key 值)
};

/**
 * 将字符串中的一部分替换成另一部分
 * @param {string} str - 需要处理的字符串
 * @param {string} findText - 需要被替换的部分
 * @param {string} replaceText - 需要替换成的部分
 * @returns {string} - 返回处理后的字符串
 * @example
 * replacePart('http://www.baidu.com?name=1&age=2', 'name=1', 'name=2') // http://www.baidu.com?name=2&age=2
 */
const replacePart = (str: string, findText: string, replaceText: string) => {
	return str.replace(findText, replaceText);
};

/**
 * 将 Markdown 文档中的 code 标签高亮
 * @param {string} mdText - 需要处理的 Markdown 文本
 * @returns {string} - 返回处理后的 Markdown 文本
 * @example
 * mdTextToHljs('```js\nconsole.log(123)\n```') // <code class="hljs language-js"><span class="hljs-built_in">console</span>.log(<span class="hljs-number">123</span>)</code>
 */
export const mdTextToHljs = (mdText: string, language: string = '') => {
	// 将所有 <td><code> 标签替换为 <td><code class="hljs language-typescript">
	mdText = mdText.replace(/<td><code>/g, `<td><code class="${language ? 'language-' + language : ''}">`);
	if (mdText.indexOf('<code class="') > 0) {
		let apiText = mdText.indexOf('<code class="') > 0 ? htmlFilter(mdText).replace(/<code class="/g, '<code class="hljs ') : mdText;
		const codeTexts = apiText.match(/<code[\s\S]*?<\/code>/g);
		if (!codeTexts) return apiText;
		for (let t = 0; t < codeTexts.length; t++) {
			const languageMatch = codeTexts[t].match(/<code class="hljs language-(.*?)">/);
			const language = languageMatch ? languageMatch[1] : ''; //语言
			const codeMatch = codeTexts[t].match(/<code[\s\S]*?>([\s\S]*?)<\/code>/);
			const code = codeMatch ? codeMatch[1] : '';
			const highlightedCode = language
				? hljs.highlight(code, {
						language,
						ignoreIllegals: true
					}).value
				: hljs.highlightAuto(code).value;
			// 将高亮代码替换原代码
			const newCode = codeTexts[t].replace(code, highlightedCode);
			apiText = replacePart(apiText, codeTexts[t], newCode);
		}

		return apiText;
	} else {
		return mdText;
	}
};

/**
 * 传入解析出来的 md 文档字符，找到其中  ::: code-group 与  ::: 之间的代码块，并将其分组，实现代码块的 tab 分组显示，
 * 其中 label 标签中的内容为 tab 标签的标题，并在文字前面增加一个 icon 标签，icon 标签的 class 内容为 iconfont 的类名
 * @param {string} md - 解析出来的 md 文档字符
 * @returns {string} - 返回处理后的 md 文档字符
 */
export const groupIconMdPlugin = (md: string) => {
	// 找出自字符中所有的 ::: code-group 与  ::: 之间的字符组成数组
	const codeGroupStrListAll = md.match(/<!-- :::code-groups -->[\s\S]*?<!-- ::: -->/g);
	if (!codeGroupStrListAll) {
		return md;
	}
	const codeGroupStrList = codeGroupStrListAll.map((item) =>
		item
			.replace(/<!-- :::code-groups -->/g, '')
			.replace(/<!-- ::: -->/g, '')
			.split('<!-- :: -->')
	);
	const codeGroupList = codeGroupStrList.map((item) =>
		item.map((subItem) => {
			return {
				tab: subItem.match(/<!-- (.*?) -->/)?.[1],
				code: subItem.replace(/<!-- (.*?) -->/, '')
			};
		})
	);

	const codeGroupHtmlList = codeGroupList.map((item, index) => {
		const arr: { label: string; code: string }[] = [];
		item.forEach((subItem, subIndex) => {
			const label = `
			<input id="tab-${index + '-' + subIndex}" type="radio" name="tab-${index}" class="peer/tab-${index + '-' + subIndex} w-0 hidden" ${
				subIndex === 0 ? 'checked' : ''
			} />
				<label
					for="tab-${index + '-' + subIndex}"
					class="border-b-2 border-black/10 dark:border-white/10 peer-checked/tab-${index + '-' + subIndex}:border-primary dark:peer-checked/tab-${
						index + '-' + subIndex
					}:border-dark transition duration-300 cursor-pointer py-2 px-3 inline-flex items-center gap-1 text-xs"
				>
					${codeGroupSvgData.find((icon) => icon.name === subItem.tab)?.svg}${subItem.tab}
				</label>
			`;
			const code = `<div class="hidden peer-checked/tab-${index + '-' + subIndex}:block w-full">${subItem.code}</div>`;
			arr.push({ label, code });
		});
		return `
			<section class="flex flex-row flex-wrap bg-black/5 dark:bg-[#202020] rounded-sm mb-4">
				${arr.map((item) => item.label).join('')}
				${arr.map((item) => item.code).join('')}
			</section>
			`;
	});
	const replaceCodeGroups = (inputString: string, replacements: string[]) => {
		// 定义正则表达式匹配 <!-- :::code-groups --> 与 <!-- ::: --> 之间的内容
		const regex = /<!--\s*:::code-groups\s*-->(.*?)<!--\s*:::\s*-->/gs;

		let index = 0;
		// 替换匹配到的部分
		inputString = inputString.replace(regex, () => {
			if (index < replacements.length) {
				return replacements[index++];
			}
			return '';
		});

		return inputString;
	};
	return replaceCodeGroups(md, codeGroupHtmlList).replace(/w-full">\n\n<pre>/g, 'w-full">\n\n<pre style="margin: 0;">');
};

/**
 * 去除 url 最后一项的？方法
 * @param {string} url - 需要处理的 url
 * @returns {string} - 返回处理后的 url
 * @example
 * delLastParamsUrl('http://www.baidu.com?') // http://www.baidu.com
 */
const delLastParamsUrl = (url: string) => {
	if (url.lastIndexOf('?') === url.length - 1) {
		url = url.substring(0, url.length - 1);
	}
	return url;
};

/**
 * 去除 url 中指定参数的方法
 * @param {string} url - 需要处理的 url
 * @param {string} name - 需要去除的参数名
 * @returns {string} - 返回处理后的 url
 * @example
 * delParamsUrl('http://www.baidu.com?name=1&age=2', 'name') // http://www.baidu.com?age=2
 */
export const delParamsUrl = (url: string, name: string) => {
	const baseUrl = url.split('?')[0] + '?';
	const query = url.split('?')[1];
	if (query.indexOf(name) > -1) {
		const obj: Record<string, string> = {};
		const arr = query.split('&');
		for (let i = 0; i < arr.length; i++) {
			const key = arr[i].split('=')[0];
			obj[key] = arr[i].split('=')[1];
		}
		delete obj[name];
		url = baseUrl + JSON.stringify(obj).replace(/["{}]/g, '').replace(/:/g, '=').replace(/,/g, '&');
		return delLastParamsUrl(url);
	} else {
		return delLastParamsUrl(url);
	}
};

/**
 * 传入 hex 格式的颜色值，将其转换成 oklch 格式，oklch(l c h),其中 lch 为 0-1 之间的值，保留三位小数
 * @param {string} str - 颜色值
 * @returns {string} - 返回 oklch 格式的颜色值
 * @example
 * getOklchFunc('#000') // 'oklch(0 0 0)'
 */
export const getOklchFunc = (str: string) => {
	const l = oklch(parse(str))?.l || 0;
	const c = oklch(parse(str))?.c || 0;
	const h = oklch(parse(str))?.h || 0;
	return `oklch(${parseFloat(l.toFixed(3))} ${parseFloat(c.toFixed(3))} ${parseFloat(h.toFixed(3))})`;
};

/**
 * 传入 oklch 格式色值，将其转为成 hex 格式
 * @param {string} str - 颜色值
 * @returns {string} - 返回 hex 格式的颜色值
 * @example
 * getHexFunc('oklch(0 0 0)') // '#000000'
 */
export const getHexFunc = (oklchString: string) => {
	// 解析字符串，提取 l, c, h 值
	const match = oklchString.match(/oklch\(([\d.]+)\s+([\d.]+)\s+([\d.]+)\)/);
	if (match) {
		const [_, l, c, h] = match.map(Number); // 转换为数字
		// 创建 OKLCH 对象
		const oklchColor = { mode: 'oklch' as const, l, c, h };
		// 转换为 HEX
		const hexColor = formatHex(oklchColor);
		return hexColor;
	} else {
		return oklchString;
	}
};

const formats = ['hex', 'rgb', 'hsl'];
/**
 * 获取颜色格式
 * @param {string} format - 颜色格式
 * @returns {string} - 返回颜色格式
 * @example
 * getFormat('hex') // hex
 */
const getFormat = (format: string) => {
	if (!format || formats.indexOf(format) < 0) {
		return 'hex';
	}
	return format;
};

/**
 * 获取颜色字符串
 * @param {object} color - 颜色对象
 * @param {string} format - 颜色格式
 * @returns {string} - 返回颜色字符串
 * @example
 * getColorString(Color('#fff'),'rgb') // rgb(255,255,255)
 */
const getColorString = (color: Color, format: string) => {
	const innerFormat = getFormat(format);

	if (innerFormat === 'hex') {
		return color[innerFormat as 'hex']();
	}
	return color[innerFormat as 'rgb' | 'hsl']().round().string();
};

/**
 * 动态梯度算法
 * @param {string} originColor - 颜色值
 * @param {number} i - 中间值
 * @param {string} format - 颜色格式
 * @returns {string} - 返回颜色字符串
 */
const colorPalette = (originColor: string, i: number, format: string) => {
	const color = Color(originColor.indexOf('#') > -1 ? originColor : getHexFunc(originColor));
	const h = color.hue();
	const s = color.saturationv();
	const v = color.value();

	const hueStep = 2;
	const maxSaturationStep = 100;
	const minSaturationStep = 9;

	const maxValue = 100;
	const minValue = 30;

	const getNewHue = (isLight: boolean, i: number) => {
		let hue;
		if (h >= 60 && h <= 240) {
			hue = isLight ? h - hueStep * i : h + hueStep * i;
		} else {
			hue = isLight ? h + hueStep * i : h - hueStep * i;
		}
		if (hue < 0) {
			hue += 360;
		} else if (hue >= 360) {
			hue -= 360;
		}
		return Math.round(hue);
	};

	const getNewSaturation = (isLight: boolean, i: number) => {
		let newSaturation;
		if (isLight) {
			newSaturation = s <= minSaturationStep ? s : s - ((s - minSaturationStep) / 5) * i;
		} else {
			newSaturation = s + ((maxSaturationStep - s) / 4) * i;
		}
		return newSaturation;
	};

	const getNewValue = (isLight: boolean, i: number) => {
		return isLight ? v + ((maxValue - v) / 5) * i : v <= minValue ? v : v - ((v - minValue) / 4) * i;
	};

	const isLight = i < 6;
	const index = isLight ? 6 - i : i - 6;
	const retColor =
		i === 6
			? color
			: Color({
					h: getNewHue(isLight, index),
					s: getNewSaturation(isLight, index) < 0 ? 4 : getNewSaturation(isLight, index),
					v: getNewValue(isLight, index)
				});

	return getColorString(retColor, format);
};

/**
 * 根据给定颜色通过算法生成指定包含十一个颜色的梯度色板
 * @param {string} color - 颜色值
 * @param {Object} options - 配置项
 * @param {number} options.index - 指定生成的颜色在梯度色板中的位置，取值范围为 1-10，默认为 6
 * @param {boolean} options.list - 是否生成包含十个颜色的梯度色板
 * @param {string} options.format 'hex' | 'rgb' | 'hsl'
 * @return string | string[]
 * @example
 * generatePalette('#0B24FB' { index: 1 }) // '#E8EEFF'
 */
export const generatePalette = (
	color: string,
	options: { list: boolean; index: number; format: string } = {
		list: true,
		index: 6,
		format: 'hex'
	}
) => {
	const { list, index, format } = options;
	if (list) {
		const list = [];
		for (let i = 0; i <= 10; i++) {
			list.push(colorPalette(color, i, format));
		}
		return list;
	}
	return colorPalette(color, index, format);
};

/**
 * 根据给定颜色计算出主题黑
 * @param {string} color - 颜色值 hex 格式
 * @return {object} - 返回两项主题黑，包含 hex、rgb、hsl、oklch 四种格式的颜色值
 * @example
 * generateThemeBlack('#0B24FB')
 */
export const generateThemeBlack = (color: string) => {
	// 将 hex 颜色转换成 hsl 格式
	const colorHsl = Color(color.indexOf('#') > -1 ? color : getHexFunc(color))
		.hsl()
		.round()
		.string();

	// 将 hsl 格式的颜色值转换成数组
	const colorHslArr = colorHsl.split(',');
	// 将 colorHslArr 的 s 和 l 值分别改为 95% 和 5% 生成主题黑
	colorHslArr[1] = ' 95%';
	colorHslArr[2] = ' 5%)';
	// 将 colorHslArr 转换成 hsl 格式
	const blackHsl = colorHslArr.join(',');
	// 将 hsl 格式的颜色值转换成 hex 格式和 rgb 格式
	const blackHex = Color(blackHsl).hex();
	const blackRgb = Color(blackHsl).rgb().round().string();
	// 将 hex 格式转换成 oklch 格式
	const colorOklch = getOklchFunc(blackHex);
	// 返回颜色值
	return { hex: blackHex, rgb: blackRgb, hsl: blackHsl, oklch: colorOklch };
};

/**
 * 根据给定颜色计算出主题白
 * @param {string} color - 颜色值 hex 格式
 * @return {object} - 返回两项主题白，包含 hex、rgb、hsl 三种格式的颜色值
 * @example
 * generateThemeWhite('#0B24FB')
 */
export const generateThemeWhite = (color: string) => {
	// 将 hex 颜色转换成 hsl 格式
	const colorHsl = Color(color.indexOf('#') > -1 ? color : getHexFunc(color))
		.hsl()
		.round()
		.string();
	// 将 hsl 格式的颜色值转换成数组
	const colorHslArr = colorHsl.split(',');
	// 将 colorHslArr 的 s 和 l 值分别改为 95% 和 5% 生成主题黑
	colorHslArr[1] = ' 5%';
	colorHslArr[2] = ' 95%)';
	// 将 colorHslArr 转换成 hsl 格式
	const whiteHsl = colorHslArr.join(',');
	// 将 hsl 格式的颜色值转换成 hex 格式和 rgb 格式
	const whiteHex = Color(whiteHsl).hex();
	const whiteRgb = Color(whiteHsl).rgb().round().string();
	// 返回主题白
	return { hex: whiteHex, rgb: whiteRgb, hsl: whiteHsl, oklch: getOklchFunc(whiteHex) };
};

/**
 * 颜色转换函数
 * @param {string} str - 颜色值
 * @returns {object} - 返回 hex、rgb、hsl、oklch 四种格式的颜色值
 * @example
 * colorConvertFunc('#000') // {hex: '#000000', rgb: 'rgb(0,0,0)', hsl: {h: 0, s: 0, l: 0}, oklch: 'oklch(0 0 0)'}
 */
export const colorConvertFunc = (str: string = '#000') => {
	// 传入 hsl(222, 100%, 98%) 这种字符，将其中的数字四舍五入取整后返回字符
	const getHslFunc = (str: string) => {
		const arr = str.split(',');
		const h = Math.round(Number(arr[0].split('(')[1]));
		const s = Math.round(Number(arr[1].split('%')[0]));
		const l = Math.round(Number(arr[2].split('%')[0]));
		return `hsl(${h}, ${s}%, ${l}%)`;
	};

	const colorObj = Color(str.indexOf('#') > -1 ? str : getHexFunc(str));

	return {
		hex: colorObj.hex(),
		rgb: colorObj.rgb().string(),
		hsl: getHslFunc(colorObj.hsl().string()),
		rgbStr: colorObj.rgb().array().join(', '),
		oklch: getOklchFunc(colorObj.hex())
	};
};

/**
 * 传入 hex 格式的颜色值，将其中所有颜色值转换成 rgb 格式
 * @param {string} str - 颜色值
 * @returns {string} - 返回 rgb 格式的颜色值
 * @example
 * hexToRgb('#000') // '0,0,0'
 */
export const hexToRgb = (str: string) => {
	return Color(str).rgb().array().join(', ');
};

/**
 * 将传入的对象转为数组，且 default 在第 6 项
 * @param {object} obj - 需要转换的对象
 * @returns {array} - 返回转换后的数组
 * @example
 * colorObjToArr({ 50: '#50', 100: '#100', 200: '#200', 300: '#300', 400: '#400', 500: '#500', 700: '#700', 800: '#800', 900: '#900', default: '#000' })
 * [{key: '50', value: '#50'}, {key: '100', value: '#100'}, {key: '200', value: '#200'}, {key: '300', value: '#300'}, {key: '400', value: '#400'}, {key: '500', value: '#500'},{key: 'default', value: '#000'},{key: '700', value: '#700'},{key: '800', value: '#800'},{key: '900', value: '#900'}]
 */
export const colorObjToArr = (obj: Record<string, string>) => {
	// 将 obj 转为数组
	const arr = Object.entries(obj).map(([key, value]) => ({ key, value }));
	// 将最后一项移动到第 6 项
	const lastItem = arr.pop();
	if (lastItem) {
		arr.splice(6, 0, lastItem);
	}
	return arr;
};

/**
 * 传入 oklch 格式的颜色值与透明度，返回带透明度的 oklch 格式
 * @param {string} str - 颜色值
 * @param {number} opacity - 透明度
 * @returns {string} - 返回带透明度的 oklch 格式
 * @example
 * getOklchOpacity('oklch(0.5 0.5 0)', 0.5) // 'oklch(0.5 0.5 0 / 0.5)'
 */
export const getOklchOpacity = (str: string, opacity: number) => {
	// 将最后一个 ) 替换为【/ 透明度】
	return str.replace(/\)$/, ` / ${opacity})`);
};



================================================
FILE: docs/site/static/assets/favicon_logo/site.webmanifest
================================================
{
	"name": "",
	"short_name": "",
	"icons": [
		{ "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" },
		{ "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" }
	],
	"theme_color": "#ffffff",
	"background_color": "#ffffff",
	"display": "standalone"
}



================================================
FILE: docs/site/static/assets/favicon_logo_dark/site.webmanifest
================================================
{
	"name": "",
	"short_name": "",
	"icons": [
		{ "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" },
		{ "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" }
	],
	"theme_color": "#ffffff",
	"background_color": "#ffffff",
	"display": "standalone"
}



================================================
FILE: docs/site/static/assets/fonts/JetBrainsMono-Regular.woff2
================================================
[Non-text file]









================================================
FILE: packages/create-stdf/README.md
================================================
[简体中文](https://github.com/any-tdf/stdf/blob/main/packages/create-stdf/README_CN.md)

# create-stdf

A CLI for creating new [STDF](https://stdf.design) projects. Just run...

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm create stdf
```
<!-- :: -->
<!-- npm -->
```sh
npm create stdf@latest
# or
npm init stdf@latest
# or
npx create-stdf@latest
```
<!-- :: -->
<!-- bun -->
```sh
bun create stdf
```
<!-- :: -->
<!-- yarn -->
```sh
yarn create stdf
```
<!-- ::: -->

...and follow the prompts.

You can also directly specify the project name and the template you want to use via additional command line options. For example, to create a new project named `my-app` using the **SvelteKit + Tailwind + TypeScript + STDF** template, run:

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm create stdf my-app
```
<!-- :: -->
<!-- npm -->
```sh
npm create stdf@latest my-app
```
<!-- :: -->
<!-- bun -->
```sh
bun create stdf my-app
```
<!-- :: -->
<!-- yarn -->
```sh
yarn create stdf my-app
```
<!-- ::: -->

If you want to use the **SvelteKit + Tailwind + STDF** template, run:

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm create stdf my-app --template skt
# or
pnpm create stdf my-app -t skt
```
<!-- :: -->
<!-- npm -->
```sh
npm create stdf@latest my-app --template skt
# or
npm create stdf@latest my-app -t skt
```
<!-- :: -->
<!-- bun -->
```sh
bun create stdf my-app --template skt
# or
bun create stdf my-app -t skt
```
<!-- :: -->
<!-- yarn -->
```sh
yarn create stdf my-app --template skt
# or
yarn create stdf my-app -t skt
```
<!-- ::: -->

Template presets include:

| Abbreviation | Template                                 | Description     |
| ------------ | ---------------------------------------- | --------------- |
| sktt         | SvelteKit + Tailwind + TypeScript + STDF | Default         |
| skt          | SvelteKit + Tailwind + STDF              | -               |
| skut         | SvelteKit + UnoCSS + TypeScript + STDF   | Not adapted yet |
| sku          | SvelteKit + UnoCSS + STDF                | Not adapted yet |

# Options

| Option          | Type   | Default | Description                                                                 |
| --------------- | ------ | ------- | --------------------------------------------------------------------------- |
| -               | string | -       | The name of the project, you can direct input.                              |
| -t / --template | string | sktt    | The template to use. Available templates are: `skt`, `sku`, `sktt`, `skut`. |
| -l / --language | string | en_US   | The language of the prompts.                                                |

# Supported Languages

| Code  | Language              |
| ----- | --------------------- |
| en_US | English (US)          |
| zh_CN | Chinese (Simplified)  |
| zh_TW | Chinese (Traditional) |
| ja_JP | Japanese              |
| ko_KR | Korean                |
| es_ES | Spanish               |
| ru_RU | Russian               |
| fr_FR | French                |
| de_DE | German                |
| it_IT | Italian               |

For example:

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm create stdf my-app -l zh_CN
```
<!-- :: -->
<!-- npm -->
```sh
npm create stdf@latest my-app -l zh_CN
```
<!-- :: -->
<!-- bun -->
```sh
bun create stdf my-app -l zh_CN
```
<!-- :: -->
<!-- yarn -->
```sh
yarn create stdf my-app -l zh_CN
```
<!-- ::: -->

# License

This project is licensed under the [MIT License](https://github.com/any-tdf/stdf/blob/main/LICENSE).



================================================
FILE: packages/create-stdf/index.js
================================================
#!/usr/bin/env node

import './dist/index.js';



================================================
FILE: packages/create-stdf/package.json
================================================
{
	"name": "create-stdf",
	"version": "0.1.2",
	"description": "A CLI for creating new STDF projects",
	"bin": {
		"create-stdf": "index.js"
	},
	"scripts": {
		"build": "rollup -c",
		"update": "node scripts/update",
		"test": "echo \"Error: no test specified\" && exit 1"
	},
	"files": [
		"dist/**",
		"templates/**"
	],
	"engines": {
		"node": ">=14.14"
	},
	"dependencies": {
		"@clack/prompts": "^0.10.0",
		"fs-extra": "^11.3.0",
		"kleur": "^4.1.5",
		"minimist": "^1.2.8"
	},
	"devDependencies": {
		"@rollup/plugin-terser": "^0.4.4",
		"rollup": "^4.39.0"
	},
	"keywords": [
		"svelte",
		"sveltekit",
		"tailwind",
		"unocss",
		"typescript",
		"stdf",
		"cli",
		"mobile",
		"vite"
	],
	"author": "any-tdf",
	"funding": "https://stdf.design?fund",
	"license": "MIT",
	"type": "module",
	"homepage": "https://github.com/any-tdf/stdf/blob/main/packages/create-stdf/README.md",
	"repository": {
		"type": "git",
		"url": "https://github.com/any-tdf/stdf"
	},
	"bugs": {
		"url": "https://github.com/any-tdf/stdf/issues?q=is:issue+is:open+create"
	}
}



================================================
FILE: packages/create-stdf/README_CN.md
================================================
[English](https://github.com/any-tdf/stdf/blob/main/packages/create-stdf/README.md)

# create-stdf

一个用于创建新的 [STDF](https://stdf.design) 项目的命令行工具。只需运行以下命令...

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm create stdf
```
<!-- :: -->
<!-- npm -->
```sh
npm create stdf@latest
# 或
npm init stdf@latest
# 或
npx create-stdf@latest
```
<!-- :: -->
<!-- bun -->
```sh
bun create stdf
```
<!-- :: -->
<!-- yarn -->
```sh
yarn create stdf
```
<!-- ::: -->

...然后按照提示进行操作。

你也可以通过额外的命令行选项直接指定项目名称和要使用的模板。例如，如果要使用 **SvelteKit + Tailwind + TypeScript + STDF** 模板创建一个名为 `my-app` 的新项目，请运行：

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm create stdf my-app
```
<!-- :: -->
<!-- npm -->
```sh
npm create stdf@latest my-app
```
<!-- :: -->
<!-- bun -->
```sh
bun create stdf my-app
```
<!-- :: -->
<!-- yarn -->
```sh
yarn create stdf my-app
```
<!-- ::: -->

如果要使用 **SvelteKit + Tailwind + STDF** 模板，请运行：

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm create stdf my-app --template skt
# 或
pnpm create stdf my-app -t skt
```
<!-- :: -->
<!-- npm -->
```sh
npm create stdf@latest my-app --template skt
# 或
npm create stdf@latest my-app -t skt
```
<!-- :: -->
<!-- bun -->
```sh
bun create stdf my-app --template skt
# 或
bun create stdf my-app -t skt
```
<!-- :: -->
<!-- yarn -->
```sh
yarn create stdf my-app --template skt
# 或
yarn create stdf my-app -t skt
```
<!-- ::: -->

模板预设包括：

| 简写 | 模板                                     | 描述     |
| ---- | ---------------------------------------- | -------- |
| sktt | SvelteKit + Tailwind + TypeScript + STDF | 默认     |
| skt  | SvelteKit + Tailwind + STDF              | -        |
| skut | SvelteKit + UnoCSS + TypeScript + STDF   | 尚未适配 |
| sku  | SvelteKit + UnoCSS + STDF                | 尚未适配 |

# 命令选项

| 命令            | 类型   | 默认  | 描述                                                       |
| --------------- | ------ | ----- | ---------------------------------------------------------- |
| -               | string | -     | 项目名称，可以直接输入。                                   |
| -t / --template | string | sktt  | 要使用的模板。可用的模板有：`skt`、`sku`、`sktt`、`skut`。 |
| -l / --language | string | en_US | 提示语言。                                                 |

# 支持的语言

| 代码  | 语言         |
| ----- | ------------ |
| en_US | 英语（美式） |
| zh_CN | 中文（简体） |
| zh_TW | 中文（繁体） |
| ja_JP | 日语         |
| ko_KR | 韩语         |
| es_ES | 西班牙语     |
| ru_RU | 俄语         |
| fr_FR | 法语         |
| de_DE | 德语         |
| it_IT | 意大利语     |

例如：

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm create stdf my-app -l zh_CN
```
<!-- :: -->
<!-- npm -->
```sh
npm create stdf@latest my-app -l zh_CN
```
<!-- :: -->
<!-- bun -->
```sh
bun create stdf my-app -l zh_CN
```
<!-- :: -->
<!-- yarn -->
```sh
yarn create stdf my-app -l zh_CN
```
<!-- ::: -->

# 许可证

本项目基于 [MIT 许可证](https://github.com/any-tdf/stdf/blob/main/LICENSE)。



================================================
FILE: packages/create-stdf/rollup.config.js
================================================
import terser from '@rollup/plugin-terser';

export default {
	input: 'src/index.js',
	output: [{ file: 'dist/index.js', format: 'es' }],
	external: ['path', 'fs-extra', '@clack/prompts', 'kleur/colors', 'minimist'],
	plugins: [terser()],
};



================================================
FILE: packages/create-stdf/scripts/update.js
================================================
import fs from 'node:fs';
import { exec } from 'node:child_process';

// 封装函数，传入版本号，需要修改的 package.json 中的 devDependencies 的 key 值，需要修改的文件路径，直接修改 package.json 并重新写入
// Encapsulate the function, pass in the version number, the key value of devDependencies in package.json that needs to be modified, the file path that needs to be modified, and directly modify package.json and rewrite
const updatePackageJson = (version, key, path) => {
	const packageJson = JSON.parse(fs.readFileSync(path, 'utf-8'));
	packageJson.devDependencies[key] = `^${version}`;
	fs.writeFileSync(path, JSON.stringify(packageJson, null, 4));
	console.log(`🎉 ${path} 更新成功`);
};

// 获取 stdf 最新版本
// Get the latest version of stdf
exec('npm show stdf version', (error, stdout, stderr) => {
	if (error) {
		console.error(`执行命令出错：${error.message}`);
		return;
	}
	if (stderr) {
		console.error(`命令错误：${stderr}`);
		return;
	}
	const version = stdout.trim();
	console.log(`👉 stdf 最新版本：${version}`);
	// 更新模板中的 package.json 的 stdf 版本号
	// Update the stdf version number in the template package.json
	updatePackageJson(version, 'stdf', 'templates/skt/package.json');
	updatePackageJson(version, 'stdf', 'templates/sktt/package.json');
});

// 获取 rollup-plugin-stdf-icon 最新版本
// Get the latest version of rollup-plugin-stdf-icon
exec('npm show rollup-plugin-stdf-icon version', (errorIcon, stdoutIcon, stderrIcon) => {
	if (errorIcon) {
		console.error(`执行命令出错：${errorIcon.message}`);
		return;
	}
	if (stderrIcon) {
		console.error(`命令错误：${stderrIcon}`);
		return;
	}
	const version = stdoutIcon.trim();
	console.log(`👉 rollup-plugin-stdf-icon 最新版本：${version}`);
	// 更新模板中的 package.json 的 rollup-plugin-stdf-icon 版本号
	// Update the rollup-plugin-stdf-icon version number in the template package.json
	updatePackageJson(version, 'rollup-plugin-stdf-icon', 'templates/skt/package.json');
	updatePackageJson(version, 'rollup-plugin-stdf-icon', 'templates/sktt/package.json');
});



================================================
FILE: packages/create-stdf/src/index.js
================================================
#!/usr/bin/env node

import fs from 'fs-extra';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import * as p from '@clack/prompts';
import { bold, cyan, grey, red, blue } from 'kleur/colors';
import minimist from 'minimist';

import * as langAll from './lang';

// 获取版本号
// Get version
// @ts-ignore
const { version } = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf-8'));

// 显示版本号
// Display version number
console.log(`
${grey(`create-stdf@${version}
`)}`);

const spinner = p.spinner();

p.intro('Welcome to use STDF!');

let lang = langAll.en_US;

// 获取命令行参数
// Get command line parameters
const argv = minimist(process.argv.slice(2));

// 获取项目名称和模板名称和语言
// Get project name and template name
const argvProjectName = argv._[0];
const argvTemplate = argv.template || argv.t;
const argvLanguage = argv.language || argv.l;

// 语言列表
// Language list
const languages = [];

// 循环 langAll 对象，将语言列表中的语言名字替换为对应的语言名字，且按照 sort 排序
// Loop through the langAll object and replace the language name in the language list with the corresponding language name, and sort by sort
for (const key in langAll) {
	languages.push({
		value: key,
		label: langAll[key].name,
		sort: langAll[key].sort,
	});
}

// 按照 sort 排序
// Sort by sort
languages.sort((a, b) => a.sort - b.sort);

// 如果命令行参数中有语言，且语言列表中有该语言，使用该语言，否则使用英语
// If there is a language in the command line parameters and the language list has the language, use the language, otherwise use English
lang = argvLanguage && languages.find(item => item.value === argvLanguage) ? langAll[argvLanguage] : langAll.en_US;

// 模板列表
// Template list
const templateOptions = [
	{ value: 'sktt', label: 'SvelteKit + Tailwind + TypeScript', template: 'sktt', finish: true },
	{ value: 'skt', label: 'SvelteKit + Tailwind', template: 'skt', finish: true },
	{ value: 'skut', label: 'SvelteKit + UnoCSS + TypeScript', template: 'skut', finish: false },
	{ value: 'sku', label: 'SvelteKit + UnoCSS', template: 'sku', finish: false },
];

// 包管理工具列表
// Package management tool list
const packageManagerOptions = [
	{ value: 'npm', label: 'NPM', install: 'npm i', dev: 'npm run dev' },
	{ value: 'bun', label: 'Bun', install: 'bun i', dev: 'bun dev' },
	{ value: 'pnpm', label: 'PNPM', install: 'pnpm i', dev: 'pnpm dev' },
	{ value: 'yarn', label: 'Yarn', install: 'yarn', dev: 'yarn run dev' },
];

// 如果命令行参数中有项目名称，但没有模板名称，直接使用默认模板 skt
// If there is a project name in the command line parameters, but no template name, use the default template skt directly
if (argvProjectName && !argvTemplate) {
	createFunc(argvProjectName, templateOptions[0]);
}
// 如果命令行参数中有项目名称和模板名称，直接使用命令行参数中的值
// If there is a project name and template name in the command line parameters, use the value in the command line parameters directly
else if (argvProjectName && argvTemplate) {
	const item = templateOptions.find(item => item.value === argvTemplate);
	if (!item) {
		p.intro(red(lang.pectn));
	} else if (!item.finish) {
		p.intro(red(item.label + ' ' + lang.hnay));
	} else {
		createFunc(argvProjectName, item);
	}
} else {
	(async () => {
		// 选择一种语言
		// Select a language
		const languageType = await p.select({
			message: bold('Please select your preferred language'),
			options: languages,
		});
		if (p.isCancel(languageType)) {
			p.cancel(red('⛔ ') + lang.oc);
			process.exit(0);
		}
		lang = langAll[languageType];

		//  选择一个模板
		// Select a template
		let template = await p.select({
			message: bold(lang.psat),
			options: templateOptions.map(item => ({
				...item,
				label: item.finish ? item.label : `(${lang.hnay}) ${item.label}`,
			})),
		});

		if (p.isCancel(template)) {
			p.cancel(red('⛔ ') + lang.oc);
			process.exit(0);
		}

		// 直到选择的 template 所在项 的 finish 为 true 为止，否则一直重新选择
		// Until the finish of the selected template is true, otherwise keep reselecting
		while (!templateOptions.find(item => item.value === template)?.finish) {
			if (p.isCancel(template)) {
				p.cancel(red('⛔ ') + lang.oc);
				process.exit(0);
			}

			p.intro(red(templateOptions.find(item => item.value === template).label + ' ' + lang.hnay + ' ' + lang.pca));
			template = await p.select({
				message: bold(lang.psat),
				options: templateOptions.map(item => ({
					...item,
					label: item.finish ? item.label : `(${lang.hnay}) ${item.label}`,
				})),
			});
		}

		// 输入项目名称
		// Enter the project name
		const projectName = await p.text({
			message: bold(lang.pn),
			placeholder: 'stdf-project',
			validate: value => {
				if (!value) {
					// 判断是否为空，提示 “项目名称不能为空”
					// Determine whether it is empty, prompt "Project name cannot be empty"
					return lang.pncbne;
				}
				if (fs.existsSync(value)) {
					// 判断是否已存在，提示 “项目名称已存在”
					// Determine whether it already exists, prompt "Project name already exists"
					return lang.pane;
				}
			},
		});

		if (p.isCancel(projectName)) {
			p.cancel(red('⛔ ') + lang.oc);
			process.exit(0);
		}

		// 使用什么包管理工具 npm / pnpm / yarn / bun / deno
		// What package management tool to use npm / pnpm / yarn / bun / deno
		const packageManager = await p.select({
			message: bold(lang.pm),
			options: packageManagerOptions,
		});

		if (p.isCancel(packageManager)) {
			p.cancel(red('⛔ ') + lang.oc);
			process.exit(0);
		}

		// 根据 template 的值，复制对应目录下的所有文件到当前目录
		// According to the value of template, copy all files under the corresponding directory to the current directory
		templateOptions.forEach(async item => {
			if (item.value === template) {
				createFunc(projectName, item, packageManager);
			}
		});
	})();
}

function createFunc(projectName, item, packageManager) {
	// 如果 projectName 是数字，转为字符串
	// If projectName is a number, convert it to a string
	if (typeof projectName === 'number') {
		projectName = projectName.toString();
	}

	// 项目目录
	// Project directory
	const projectDir = path.join(path.resolve(), projectName);

	spinner.start('🚀 ' + lang.cfsing);

	fs.mkdirSync(projectDir);

	// 获取模板目录的绝对路径，考虑到 Windows 系统的兼容性, 使用 path.join
	// Get the absolute path of the template directory, considering the compatibility of the Windows system, use path.join
	// @ts-ignore
	const templatePath = path.resolve(fileURLToPath(import.meta.url), '../..', `templates/${item.template}`);

	// 将 templatePath 目录下的所有文件复制到 projectDir 目录下
	// Copy all files under the templatePath directory to the projectDir directory\
	fs.copy(templatePath, projectDir)
		.then(() => {
			spinner.stop();
			p.outro(`${projectName} - ${lang.pcsucc} 🎉`);

			// 读取 package.json 文件
			// Read the package.json file
			const packageJson = JSON.parse(fs.readFileSync(`${projectDir}/package.json`, 'utf-8'));

			// 将项目内的 package.json 中的 name 属性修改为 projectName
			// Modify the name attribute in package.json in the project to projectName
			packageJson.name = projectName;

			// 将修改后的 packageJson 写入到项目内的 package.json 文件中
			// Write the modified packageJson to the package.json file in the project
			fs.writeFileSync(`${projectDir}/package.json`, JSON.stringify(packageJson, null, 4), 'utf-8');

			// 根据 item.value 的值，判断是否使用了 @sveltejs/kit
			// According to the value of item.value, determine whether @sveltejs/kit is used
			const isHasKit = item.value === 'skt' || item.value === 'sku' || item.value === 'sktt' || item.value === 'skut';

			// 根据 item.value 的值，判断使用 Tailwind 还是 UnoCSS
			// According to the value of item.value, determine whether to use Tailwind or UnoCSS
			const isHasUno = item.value === 'vu' || item.value === 'sku' || item.value === 'vut' || item.value === 'skut';

			// 获得依赖的版本号
			// get the version number of the dependency
			const versions = {
				vite: packageJson.devDependencies.vite.replace('^', ''),
				svelte: packageJson.devDependencies.svelte.replace('^', ''),
				stdf: packageJson.devDependencies.stdf.replace('^', ''),
			};

			if (isHasKit) {
				versions['@sveltejs/kit'] = packageJson.devDependencies['@sveltejs/kit'].replace('^', '');
			}

			if (isHasUno) {
				versions['unocss'] = packageJson.devDependencies.unocss.replace('^', '');
			} else {
				versions['tailwindcss'] = packageJson.devDependencies.tailwindcss.replace('^', '');
			}

			// 将 versions 的键值拼接为 bold('Vite:') cyan(versions.vite) bold('Svelte:') cyan(versions.svelte) 的形式
			// Splice the key value of versions into the form of bold('Vite:') cyan(versions.vite) bold('Svelte:') cyan(versions.svelte)
			let versionsString = '';
			for (const key in versions) {
				versionsString += bold(key) + ': ' + cyan(versions[key]) + ' ';
			}

			// 显示版本号
			// Display version number
			console.log(`📦 ${versionsString}
                `);

			// 显示提示信息
			// Display prompt information
			console.log(
				`👉 ${bold(lang.tgs)}

    ${blue(`1. cd ${projectName}`)}
    ${blue(`2. git init && git add -A && git commit -m "Initial commit"`)}
    ${blue(`3. ${packageManagerOptions.find(item => item.value === packageManager).install}`)}
    ${blue(`4. ${packageManagerOptions.find(item => item.value === packageManager).dev}`)}
    `
			);
			// 显示配置主题色
			// Display configuration theme color
			console.log(
				`🎨 ${grey(isHasUno ? lang.pcyt_vu : lang.pcyt_vt)}
    `
			);
		})
		.catch(err => {
			spinner.stop();
			console.error(red(lang.cferror + '--' + err));
		});
}



================================================
FILE: packages/create-stdf/src/lang.js
================================================
// 英语 english
export const en_US = {
	sort: 0,
	name: 'English',
	hnay: 'Has not adapted yet',
	pn: 'Please enter the project name',
	pncbne: 'Project name cannot be empty',
	pane: 'Project name already exists',
	psat: 'Please select a template',
	oc: 'Operation cancelled',
	pca: 'Please choose again',
	pm: 'Please select a package manager',
	cfsing: 'Creating file...',
	pcsucc: 'Project created successfully',
	tgs: 'To get started:',
	pcyt_vt: 'Tip: please configure Initial Color System in src/app.css, reference https://stdf.design/guide/theme',
	pcyt_vu: 'Tip: please configure Initial Color System in src/app.css, reference https://stdf.design/guide/theme',
	cferror: 'Failed to create file',
	pectn: 'Please enter the correct template name!',
};

// 简体中文 chinese
export const zh_CN = {
	sort: 1,
	name: '简体中文',
	hnay: '暂未适配',
	pn: '请输入项目名称',
	pncbne: '项目名称不能为空',
	pane: '项目名称已存在',
	psat: '请选择一个模板',
	oc: '操作已取消',
	pca: '请重新选择',
	pm: '请选择一个包管理工具',
	cfsing: '正在创建文件...',
	pcsucc: '项目创建成功',
	tgs: '开始：',
	pcyt_vt: '提示：请到 src/app.css 配置初始主题色，参考 https://stdf.design/guide/theme',
	pcyt_vu: '提示：请到 src/app.css 配置初始主题色，参考 https://stdf.design/guide/theme',
	cferror: '创建文件失败',
	pectn: '请输入正确的模板名称！',
};

// 繁體中文 chinese traditional
export const zh_TW = {
	sort: 2,
	name: '繁體中文',
	hnay: '暫未適配',
	pn: '請輸入項目名稱',
	pncbne: '項目名稱不能為空',
	pane: '項目名稱已存在',
	psat: '請選擇一個模板',
	oc: '操作已取消',
	pca: '請重新選擇',
	pm: '請選擇一個包管理工具',
	cfsing: '正在創建文件...',
	pcsucc: '項目創建成功',
	tgs: '開始：',
	pcyt_vt: '提示：請到 src/app.css 配置初始主題色，參考 https://stdf.design/guide/theme',
	pcyt_vu: '提示：請到 src/app.css 配置初始主題色，參考 https://stdf.design/guide/theme',
	cferror: '創建文件失敗',
	pectn: '請輸入正確的模板名稱！',
};

// 日语 japanese
export const ja_JP = {
	sort: 3,
	name: '日本語',
	hnay: 'まだ適応されていません',
	pn: 'プロジェクト名を入力してください',
	pncbne: 'プロジェクト名は空にできません',
	pane: 'プロジェクト名が既に存在します',
	psat: 'テンプレートを選択してください',
	oc: '操作がキャンセルされました',
	pca: 'もう一度選択してください',
	pm: 'パッケージマネージャーを選択してください',
	cfsing: 'ファイルを作成しています...',
	pcsucc: 'プロジェクトが正常に作成されました',
	tgs: '開始：',
	pcyt_vt: 'ヒント：src/app.css ファイルで初期カラーシステムを設定し、参考 https://stdf.design/guide/theme',
	pcyt_vu: 'ヒント：src/app.css ファイルで初期カラーシステムを設定し、参考 https://stdf.design/guide/theme',
	cferror: 'ファイルの作成に失敗しました',
	pectn: '正しいテンプレート名を入力してください！',
};

// 韩语 korean
export const ko_KR = {
	sort: 4,
	name: '한국어',
	hnay: '아직 적응하지 못했습니다',
	pn: '프로젝트 이름을 입력하십시오',
	pncbne: '프로젝트 이름은 비워 둘 수 없습니다',
	pane: '프로젝트 이름이 이미 있습니다',
	psat: '템플릿을 선택하십시오',
	oc: '작업이 취소되었습니다',
	pca: '다시 선택하십시오',
	pm: '패키지 관리자를 선택하십시오',
	cfsing: '파일을 만드는 중입니다...',
	pcsucc: '프로젝트가 성공적으로 생성되었습니다',
	tgs: '시작：',
	pcyt_vt: '팁: src/app.css 파일에서 초기 색상 시스템을 구성하고 참조 https://stdf.design/guide/theme',
	pcyt_vu: '팁: src/app.css 파일에서 초기 색상 시스템을 구성하고 참조 https://stdf.design/guide/theme',
	cferror: '파일 생성 실패',
	pectn: '올바른 템플릿 이름을 입력하십시오!',
};

// 西班牙语 spanish
export const es_ES = {
	sort: 5,
	name: 'Español',
	hnay: 'Aún no se ha adaptado',
	pn: 'Por favor ingrese el nombre del proyecto',
	pncbne: 'El nombre del proyecto no puede estar vacío',
	pane: 'El nombre del proyecto ya existe',
	psat: 'Por favor seleccione una plantilla',
	oc: 'Operación cancelada',
	pca: 'Por favor, elija de nuevo',
	pm: 'Por favor seleccione un administrador de paquetes',
	cfsing: 'Creando archivo...',
	pcsucc: 'Proyecto creado con éxito',
	tgs: 'Para empezar:',
	pcyt_vt: 'Consejo: configure su sistema de colores en reference https://stdf.design/guide/theme',
	pcyt_vu: 'Consejo: configure su sistema de colores en reference https://stdf.design/guide/theme',
	cferror: 'Error al crear archivo',
	pectn: '¡Por favor ingrese el nombre de la plantilla correcto!',
};

// 俄语 russian
export const ru_RU = {
	sort: 6,
	name: 'Русский',
	hnay: 'Еще не адаптировано',
	pn: 'Пожалуйста, введите название проекта',
	pncbne: 'Название проекта не может быть пустым',
	pane: 'Название проекта уже существует',
	psat: 'Пожалуйста, выберите шаблон',
	oc: 'Операция отменена',
	pca: 'Пожалуйста, выберите снова',
	pm: 'Пожалуйста, выберите пакетный менеджер',
	cfsing: 'Создание файла...',
	pcsucc: 'Проект успешно создан',
	tgs: 'Чтобы начать:',
	pcyt_vt: 'Совет: настройте свой цветовой систему в ссылке https://stdf.design/guide/theme',
	pcyt_vu: 'Совет: настройте свой цветовой систему в ссылке https://stdf.design/guide/theme',
	cferror: 'Не удалось создать файл',
	pectn: 'Пожалуйста, введите правильное название шаблона!',
};

// 法语 french
export const fr_FR = {
	sort: 7,
	name: 'Français',
	hnay: "N'a pas encore adapté",
	pn: 'Veuillez saisir le nom du projet',
	pncbne: 'Le nom du projet ne peut pas être vide',
	pane: 'Le nom du projet existe déjà',
	psat: 'Veuillez sélectionner un modèle',
	oc: 'Opération annulée',
	pca: 'Veuillez choisir à nouveau',
	pm: 'Veuillez sélectionner un gestionnaire de paquets',
	cfsing: 'Création de fichier...',
	pcsucc: 'Projet créé avec succès',
	tgs: 'Pour commencer:',
	pcyt_vt: 'Conseil: veuillez configurer votre système de couleurs dans reference https://stdf.design/guide/theme',
	pcyt_vu: 'Conseil: veuillez configurer votre système de couleurs dans reference https://stdf.design/guide/theme',
	cferror: 'Échec de la création du fichier',
	pectn: 'Veuillez saisir le nom du modèle correct!',
};

// 德语 german
export const de_DE = {
	sort: 8,
	name: 'Deutsch',
	hnay: 'Noch nicht angepasst',
	pn: 'Bitte geben Sie den Projektnamen ein',
	pncbne: 'Projektname darf nicht leer sein',
	pane: 'Projektname existiert bereits',
	psat: 'Bitte wählen Sie eine Vorlage aus',
	oc: 'Vorgang abgebrochen',
	pca: 'Bitte wählen Sie erneut',
	pm: 'Bitte wählen Sie einen Paketmanager aus',
	cfsing: 'Erstelle Datei...',
	pcsucc: 'Projekt erfolgreich erstellt',
	tgs: 'Um zu beginnen:',
	pcyt_vt: 'Tip: please configure your color system in reference https://stdf.design/guide/theme',
	pcyt_vu: 'Tip: please configure your color system in reference https://stdf.design/guide/theme',
	cferror: 'Fehler beim Erstellen der Datei',
	pectn: 'Bitte geben Sie den richtigen Vorlagennamen ein!',
};

// 意大利语 italian
export const it_IT = {
	sort: 9,
	name: 'Italiano',
	hnay: 'Non ancora adattato',
	pn: 'Inserisci il nome del progetto',
	pncbne: 'Il nome del progetto non può essere vuoto',
	pane: 'Il nome del progetto esiste già',
	psat: 'Seleziona un modello',
	oc: 'Operazione annullata',
	pca: 'Seleziona di nuovo',
	pm: 'Seleziona un gestore di pacchetti',
	cfsing: 'Creazione del file in corso...',
	pcsucc: 'Progetto creato con successo',
	tgs: 'Per iniziare:',
	pcyt_vt: 'Consiglio: configura il tuo sistema di colori in https://stdf.design/guide/theme',
	pcyt_vu: 'Consiglio: configura il tuo sistema di colori in https://stdf.design/guide/theme',
	cferror: 'Impossibile creare il file',
	pectn: 'Inserisci il nome del modello corretto!',
};



================================================
FILE: packages/create-stdf/templates/skt/README.md
================================================
# SvelteKit + Tailwind + STDF

This template should help get you started developing with Svelte + Tailwind + STDF in SvelteKit.

## Recommended IDE Setup

- [VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) + [Tailwind](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) + [STDF](https://stdf.design) .

- [WebStorm](https://www.jetbrains.com/webstorm/) + [Svelte](https://www.jetbrains.com/help/webstorm/svelte.html) + [Tailwind](https://www.jetbrains.com/help/webstorm/tailwind-css.html) + [STDF](https://stdf.design) .

## More Info

For more information about quickly create a new project, see the STDF [Quick start](https://stdf.design/guide) guide.



================================================
FILE: packages/create-stdf/templates/skt/eslint.config.js
================================================
import prettier from 'eslint-config-prettier';
import js from '@eslint/js';
import { includeIgnoreFile } from '@eslint/compat';
import svelte from 'eslint-plugin-svelte';
import globals from 'globals';
import { fileURLToPath } from 'node:url';
import svelteConfig from './svelte.config.js';

const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url));

export default [
	includeIgnoreFile(gitignorePath),
	js.configs.recommended,
	...svelte.configs.recommended,
	prettier,
	...svelte.configs.prettier,
	{
		languageOptions: {
			globals: { ...globals.browser, ...globals.node }
		}
	},
	{
		files: ['**/*.svelte', '**/*.svelte.js'],
		languageOptions: { parserOptions: { svelteConfig } }
	}
];



================================================
FILE: packages/create-stdf/templates/skt/jsconfig.json
================================================
{
	"extends": "./.svelte-kit/tsconfig.json",
	"compilerOptions": {
		"allowJs": true,
		"checkJs": true,
		"esModuleInterop": true,
		"forceConsistentCasingInFileNames": true,
		"resolveJsonModule": true,
		"skipLibCheck": true,
		"sourceMap": true,
		"strict": true,
		"moduleResolution": "bundler"
	}
	// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
	// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
	//
	// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
	// from the referenced tsconfig.json - TypeScript does not merge them in
}



================================================
FILE: packages/create-stdf/templates/skt/package.json
================================================
{
	"name": "skt",
	"private": true,
	"version": "0.0.1",
	"type": "module",
	"scripts": {
		"dev": "vite dev",
		"build": "vite build",
		"preview": "vite preview",
		"prepare": "svelte-kit sync || echo ''",
		"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
		"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
		"format": "prettier --write .",
		"lint": "prettier --check . && eslint ."
	},
	"devDependencies": {
		"@eslint/compat": "^1.2.5",
		"@eslint/js": "^9.18.0",
		"@sveltejs/adapter-auto": "^4.0.0",
		"@sveltejs/kit": "^2.16.0",
		"@sveltejs/vite-plugin-svelte": "^5.0.0",
		"@tailwindcss/vite": "^4.0.0",
		"eslint": "^9.18.0",
		"eslint-config-prettier": "^10.0.1",
		"eslint-plugin-svelte": "^3.0.0",
		"globals": "^16.0.0",
		"prettier": "^3.4.2",
		"prettier-plugin-svelte": "^3.3.3",
		"prettier-plugin-tailwindcss": "^0.6.11",
		"rollup-plugin-stdf-icon": "file:../../../rollup-plugin-stdf-icon",
		"svelte": "^5.0.0",
		"svelte-check": "^4.0.0",
		"stdf": "file:../../../stdf",
		"tailwindcss": "^4.0.0",
		"typescript": "^5.0.0",
		"vite": "^6.0.0"
	}
}



================================================
FILE: packages/create-stdf/templates/skt/svelte.config.js
================================================
import adapter from '@sveltejs/adapter-auto';

/** @type {import('@sveltejs/kit').Config} */
const config = {
	kit: {
		// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
		// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
		// See https://svelte.dev/docs/kit/adapters for more information about adapters.
		adapter: adapter()
	}
};

export default config;



================================================
FILE: packages/create-stdf/templates/skt/vite.config.js
================================================
import tailwindcss from '@tailwindcss/vite';
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import svgSprite from 'rollup-plugin-stdf-icon';

export default defineConfig({
	plugins: [
		tailwindcss(),
		sveltekit(),
		// 一般来说，一个应用的的 svg 不多时都放在一个文件夹下，合并为一个 symbol 即可。此处演示了不同文件夹下的图标如何合并为不同的 symbol。
		// Generally speaking, when the svg of an application is not much, it is placed in a folder and merged into one symbol. This example shows how the icons in different folders are merged into different symbols.
		svgSprite([
			{ inFile: 'src/lib/svgs/Heroicons', outFile: 'static/symbols' },
			{ inFile: 'src/lib/svgs/IconPark', outFile: 'static/symbols' },
			{ inFile: 'src/lib/svgs/Remix', outFile: 'static/symbols' },
			// 单独为 Cell 与 NavBar 用到的图标创建一个 symbol。详见：https://stdf.design/guide/icon
			// Create a symbol for the icons used by Cell and NavBar. See: https://stdf.design/guide/icon
			{ inFile: 'src/lib/symbol', outFile: 'static/fonts' }
		])
	]
});



================================================
FILE: packages/create-stdf/templates/skt/.npmrc
================================================
engine-strict=true



================================================
FILE: packages/create-stdf/templates/skt/.prettierignore
================================================
# Package Managers
package-lock.json
pnpm-lock.yaml
yarn.lock
bun.lock
bun.lockb



================================================
FILE: packages/create-stdf/templates/skt/.prettierrc
================================================
{
	"useTabs": true,
	"singleQuote": true,
	"trailingComma": "none",
	"printWidth": 140,
	"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
	"overrides": [
		{
			"files": "*.svelte",
			"options": {
				"parser": "svelte"
			}
		}
	]
}



================================================
FILE: packages/create-stdf/templates/skt/src/app.css
================================================
@import 'tailwindcss';

@custom-variant dark (&:where(.dark, .dark *));

@theme {
	--color-primary-50: oklch(0.979 0.01 267.36);
	--color-primary-100: oklch(0.95 0.024 270.343);
	--color-primary-200: oklch(0.847 0.074 271.188);
	--color-primary-300: oklch(0.741 0.13 272.232);
	--color-primary-400: oklch(0.634 0.193 271.595);
	--color-primary-500: oklch(0.536 0.252 268.66);
	--color-primary: oklch(0.467 0.296 264.886);
	--color-primary-700: oklch(0.397 0.26 264.877);
	--color-primary-800: oklch(0.331 0.221 264.833);
	--color-primary-900: oklch(0.26 0.178 264.428);
	--color-primary-950: oklch(0.192 0.13 266.64);

	--color-dark-50: oklch(0.995 0.012 101.474);
	--color-dark-100: oklch(0.986 0.025 97.107);
	--color-dark-200: oklch(0.965 0.059 95.884);
	--color-dark-300: oklch(0.938 0.089 92.952);
	--color-dark-400: oklch(0.91 0.114 89.711);
	--color-dark-500: oklch(0.88 0.136 86.375);
	--color-dark: oklch(0.845 0.153 80.597);
	--color-dark-700: oklch(0.71 0.137 75.734);
	--color-dark-800: oklch(0.58 0.118 70.166);
	--color-dark-900: oklch(0.449 0.097 65.209);
	--color-dark-950: oklch(0.321 0.074 62.379);

	--color-primaryBlack: oklch(0.116 0.054 267.087);
	--color-primaryWhite: oklch(0.961 0.001 286.375);
	--color-darkBlack: oklch(0.183 0.035 86.634);
	--color-darkWhite: oklch(0.962 0.001 17.178);

	--color-success: oklch(0.704 0.142 167.084);
	--color-warning: oklch(0.558 0.154 47.186);
	--color-error: oklch(0.564 0.223 28.46);
	--color-info: oklch(0.482 0.14 261.518);

	--color-extend0: oklch(0.703 0.149 235.059);
	--color-Twitter: oklch(0.703 0.149 235.059);
	--color-extend1: oklch(0.702 0.194 38.137);
	--color-Svelte: oklch(0.702 0.194 38.137);
	--color-extend2: oklch(0.482 0.107 161.212);
	--color-Starbucks: oklch(0.482 0.107 161.212);

	--color-black: oklch(0 0 0);
	--color-white: oklch(1 0 0);
	--color-gray-50: oklch(0.961 0 0);
	--color-gray-100: oklch(0.925 0 0);
	--color-gray-200: oklch(0.845 0 0);
	--color-gray-300: oklch(0.767 0 0);
	--color-gray-400: oklch(0.683 0 0);
	--color-gray-500: oklch(0.6 0 0);
	--color-gray-600: oklch(0.51 0 0);
	--color-gray-700: oklch(0.42 0 0);
	--color-gray-800: oklch(0.321 0 0);
	--color-gray-900: oklch(0.218 0 0);
	--color-gray-950: oklch(0.159 0 0);
	--color-transparent: transparent;
}


@source "../node_modules/stdf/**/*.svelte";

html {
	-webkit-tap-highlight-color: transparent;
}


================================================
FILE: packages/create-stdf/templates/skt/src/app.d.ts
================================================
// See https://svelte.dev/docs/kit/types#app.d.ts
// for information about these interfaces
declare global {
	namespace App {
		// interface Error {}
		// interface Locals {}
		// interface PageData {}
		// interface PageState {}
		// interface Platform {}
	}
}

export {};



================================================
FILE: packages/create-stdf/templates/skt/src/app.html
================================================
<!doctype html>
<html>
	<head>
		<meta charset="utf-8" />
		<link rel="icon" type="image/svg+xml" href="%sveltekit.assets%/stdf.svg" media="(prefers-color-scheme: light)" />
		<link rel="icon" type="image/svg+xml" href="%sveltekit.assets%/stdf_dark.svg" media="(prefers-color-scheme: dark)" />
		<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
		<title>SvelteKit + Tailwind + STDF</title>
		%sveltekit.head%
	</head>

	<body data-sveltekit-preload-data="hover" class="bg-primaryWhite dark:bg-darkBlack text-black dark:text-white">
		<div style="display: contents">%sveltekit.body%</div>
	</body>
</html>



================================================
FILE: packages/create-stdf/templates/skt/src/data/nintendo.ts
================================================
import type { ThemeProps } from 'stdf/theme';

const Nintendo: ThemeProps = {
	name: 'Nintendo',
	color: {
		primary: {
			50: 'oklch(0.98 0.01 25.073)', // #FFF6F5 hsl(6, 100%, 98%)
			100: 'oklch(0.953 0.023 24.126)', // #FFEAE8 hsl(5, 100%, 96%)
			200: 'oklch(0.845 0.076 21.796)', // #FAB9B6 hsl(3, 87%, 85%)
			300: 'oklch(0.745 0.133 21.872)', // #F58886 hsl(1, 85%, 74%)
			400: 'oklch(0.662 0.188 22.749)', // #F0575A hsl(359, 84%, 64%)
			500: 'oklch(0.609 0.224 25.256)', // #EB2B34 hsl(357, 83%, 55%)
			default: 'oklch(0.581 0.238 27.862)', // #E60012 hsl(355, 100%, 45%)
			700: 'oklch(0.508 0.207 26.549)', // #C00016 hsl(353, 100%, 38%)
			800: 'oklch(0.43 0.174 24.608)', // #990017 hsl(351, 100%, 30%)
			900: 'oklch(0.351 0.141 21.971)', // #730015 hsl(349, 100%, 23%)
			950: 'oklch(0.266 0.107 17.45)' // #4D0011 hsl(347, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.992 0.011 189.833)', // #F5FFFE hsl(174, 100%, 98%)
			100: 'oklch(0.983 0.024 193.6)', // #E8FFFE hsl(177, 100%, 96%)
			200: 'oklch(0.938 0.067 196.074)', // #B6F9F9 hsl(180, 85%, 85%)
			300: 'oklch(0.893 0.099 198.69)', // #85F0F4 hsl(182, 84%, 74%)
			400: 'oklch(0.847 0.12 201.806)', // #57E4EE hsl(184, 82%, 64%)
			500: 'oklch(0.803 0.131 206.757)', // #2AD6E9 hsl(186, 81%, 54%)
			default: 'oklch(0.752 0.133 215.123)', // #00C3E3 hsl(189, 100%, 45%)
			700: 'oklch(0.646 0.116 218.359)', // #009EBD hsl(190, 100%, 37%)
			800: 'oklch(0.535 0.1 223.819)', // #007998 hsl(192, 100%, 30%)
			900: 'oklch(0.426 0.083 227.589)', // #005772 hsl(194, 100%, 22%)
			950: 'oklch(0.319 0.064 230.58)' // #00384D hsl(196, 100%, 15%)
		},
		primaryBlack: 'oklch(0.139 0.05 18.003)', // #190103 hsl(355, 95%, 5%)
		primaryWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(355, 5%, 95%)
		darkBlack: 'oklch(0.184 0.03 206.812)', // #011619 hsl(188, 95%, 5%)
		darkWhite: 'oklch(0.963 0.001 197.138)', // #F2F3F3 hsl(188, 5%, 95%)
		functional: {
			success: 'oklch(0.669 0.214 144.385)', // #00b42a hsl(134, 100%, 35%)
			warning: 'oklch(0.865 0.176 95.103)', // #f7d00c hsl(50, 94%, 51%)
			error: 'oklch(0.642 0.218 25.88)', // #f53f3f hsl(0, 90%, 60%)
			info: 'oklch(0.549 0.249 263.048)' // #165dff hsl(222, 100%, 54%)
		},
		extend: [
			{
				color: 'oklch(0.492 0.217 261.351)', // #0052d9 hsl(217, 100%, 43%)
				alias: 'Tencent'
			},
			{
				color: 'oklch(0.651 0.212 142.608)', // #1aad19 hsl(120, 75%, 39%)
				alias: 'WeChat'
			},
			{
				color: 'oklch(0.692 0.181 46.213)', // #f37021 hsl(23, 90%, 54%)
				alias: 'Hermès'
			}
		]
	}
};

export default Nintendo;







================================================
FILE: packages/create-stdf/templates/skt/src/routes/+layout.js
================================================
// 修改 ssr 为 false，使其不再使用服务端渲染，而是使用客户端渲染
// Change ssr to false to use client-side rendering instead of server-side rendering
export const ssr = false;



================================================
FILE: packages/create-stdf/templates/skt/src/routes/+layout.svelte
================================================
<script>
	import '../app.css';

	let { children } = $props();
</script>

{@render children()}



================================================
FILE: packages/create-stdf/templates/skt/src/routes/+page.svelte
================================================
<script>
	import { setContext } from 'svelte';
	import { Button, Cell, Icon, Calendar } from 'stdf';
	import { STDFTheme, switchTheme, darkMode } from 'stdf/theme';
	import NintendoTheme from '../data/nintendo';
	import { en_US, zh_CN } from 'stdf/lang';
	import Counter from './Counter.svelte';

	import { browser } from '$app/environment';

	if (browser) {
		//解决 ios 不支持按钮:active 伪类
		// Solve the problem that ios does not support the button: active pseudo class
		document.body.addEventListener('touchstart', function () {
			//...空函数即可
			// ... Empty function is OK
		});
	}

	//切换亮暗模式 (toggle light or dark mode)
	let mode = $state(sessionStorage.getItem('mode') === 'dark' ? 'dark' : 'light');

	$effect(() => {
		if (mode === 'dark') {
			darkMode(true);
		} else {
			darkMode(false);
		}
	});
	const toggleModeFun = () => {
		if (mode === 'dark') {
			// 切换到 (light switch to light)
			mode = 'light';
			darkMode(false);
			sessionStorage.setItem('mode', 'light');
		} else {
			// 切换到 (dark switch to dark)
			mode = 'dark';
			darkMode(true);
			sessionStorage.setItem('mode', 'dark');
		}
	};

	// 设置语言 (setting language)
	let lang = $state(localStorage.getItem('lang') === 'en_US' ? 'en_US' : 'zh_CN');
	setContext('STDF_lang', localStorage.getItem('lang') === 'en_US' ? en_US : zh_CN);
	const toggleLangFun = () => {
		lang = lang === 'zh_CN' ? 'en_US' : 'zh_CN';
		localStorage.setItem('lang', lang);
		window.location.reload();
	};

	// 进度条 (percent)
	let percent = $state(20);
	const reduceFunc = () => {
		if (percent > 0) {
			percent -= 10;
		}
	};
	const increaseFunc = () => {
		if (percent < 100) {
			percent += 10;
		}
	};

	// 日历(calendar)
	let visible = $state(false);

	// 主题(theme)
	let theme = $state('STDF');
	const toggleThemeFun = () => {
		if (theme === 'STDF') {
			theme = 'Nintendo';
			switchTheme(NintendoTheme);
		} else {
			theme = 'STDF';
			switchTheme(STDFTheme);
		}
	};
</script>

<div class="flex items-center justify-center gap-2 pt-10 text-center">
	<a class="flex w-10 flex-col items-center" href="https://kit.svelte.dev" target="_blank" rel="noreferrer">
		<img src="/svelte.svg" alt="Svelte Logo" />
	</a>+
	<a class="flex w-10 flex-col items-center" href="https://tailwindcss.com" target="_blank" rel="noreferrer">
		<img src="/tailwindcss.svg" alt="Tailwind Logo" />
	</a>+
	<a class="flex w-8 flex-col items-center" href="https://stdf.design" target="_blank" rel="noreferrer" aria-label="STDF Logo">
		<svg viewBox="0 0 90 80" fill="currentColor">
			<path
				class="text-primary dark:text-dark"
				d="M0 0H20H40H50C64.8056 0 77.7325 8.04398 84.6487 20H50H40V22.6757V30H50C55.5229 30 60 34.4771 60 40C60 45.5229 55.5229 50 50 50H40V57.3243V78.7398V80H20V66.4583V20H15.3513H0V0ZM50 80C72.0914 80 90 62.0914 90 40C90 36.547 89.5625 33.1962 88.7398 30H67.3244C69.0261 32.9417 70 36.3571 70 40C70 51.0457 61.0457 60 50 60V80Z"
			/>
			<path class="text-dark dark:text-primary" d="M20 30V0L0 50H20V80L40 30H20Z" />
		</svg>
	</a>
</div>
<div class="my-6 text-center text-xs">
	{#if lang === 'zh_CN'}
		<p>这是 SvelteKit + Tailwind + STDF 构建的模板</p>
		<p class="mt-2">点击上方 LOGO 了解更多</p>
	{:else}
		<p>This is a template using SvelteKit + TailwindCSS + STDF</p>
		<p class="mt-2">Click the logo above to learn more</p>
	{/if}
</div>
<div class="my-6">
	<a href="about">
		<Cell title={lang === 'zh_CN' ? '跳转 ABOUT' : 'Go to ABOUT'} />
	</a>
</div>
<div class="my-6">
	<Cell
		title={lang === 'zh_CN' ? '暗模式' : 'Dark mode'}
		right={{ type: 'switch', switch: { active: mode === 'dark' } }}
		onclick={toggleModeFun}
	/>
</div>
<div class="mt-8">
	<Counter bind:percent />
</div>
<div class="mb-8">
	<Button heightIn="0" group fill="lineTheme">
		<div class="flex w-full">
			<button class="border-primary dark:border-dark flex-1 border-r py-2 active:opacity-80" onclick={reduceFunc}>-10</button>
			<button class="border-primary dark:border-dark flex-1 border-r py-2 active:opacity-80" onclick={increaseFunc}>+10</button>
			<button class="flex-1 py-2 active:opacity-80" onclick={() => (percent = 20)}>
				{lang === 'zh_CN' ? '重置' : 'Reset'}
			</button>
		</div>
	</Button>
</div>
<div class="my-6">
	<Button fill="lineTheme" onclick={() => (visible = true)}>{lang === 'zh_CN' ? '日历' : 'Calendar'}</Button>
</div>
<Calendar bind:visible />
<div class="my-6 flex justify-between px-8">
	<Icon name="cake" theme path="symbols/Heroicons.svg" />
	<Icon name="riding-line" path="symbols/Remix.svg" />
	<Icon name="spy-line" theme path="symbols/Remix.svg" />
	<Icon name="javascript-fill" injClass="text-[red] dark:text-green" path="symbols/Remix.svg" />
	<Icon name="cup" theme path="symbols/IconPark.svg" />
</div>
<div class="px-4 text-xs">
	{lang === 'zh_CN' ? '图标：第一个来自' : 'Icons: The first one comes from'}
	<a class="underline" href="https://heroicons.com">Heroicons</a>
	，{lang === 'zh_CN' ? '最后一个来自' : 'the last one comes from'}
	<a class="underline" href="https://iconpark.oceanengine.com">IconPark</a>
	，{lang === 'zh_CN' ? '其余来自' : 'the rest come from'}
	<a class="underline" href="https://remixicon.com">Remix Icon</a> 。
</div>
<div class="my-6">
	<Button onclick={toggleLangFun}>{lang === 'zh_CN' ? '切换语言' : 'Toggle language'}</Button>
	<Button fill="lineTheme" onclick={toggleThemeFun}>{lang === 'zh_CN' ? '切换主题' : 'Toggle theme'}</Button>
</div>



================================================
FILE: packages/create-stdf/templates/skt/src/routes/Counter.svelte
================================================
<script>
	import { Progress } from 'stdf';

	let { percent = $bindable(20) } = $props();
</script>

<div class="p-4">
	<Progress {percent} />
</div>



================================================
FILE: packages/create-stdf/templates/skt/src/routes/about/+page.svelte
================================================
<script>
	import { NavBar } from 'stdf';

	const lang = localStorage.getItem('lang') === 'en_US' ? 'en_US' : 'zh_CN';
</script>

<svelte:head>
	<title>About</title>
	<meta name="description" content="About this app" />
</svelte:head>

<div class="sticky top-0 z-10">
	<NavBar title={lang === 'zh_CN' ? '关于' : 'ABOUT'} onclickLeft={() => window.history.back()} />
</div>

<div class="space-y-10 px-2 py-20 text-center">
	<div class="text-primary dark:text-dark text-3xl">
		{lang === 'zh_CN' ? '这是一个关于页面' : 'This is a about page'}
	</div>
	<div class="text-sm">
		{lang === 'zh_CN'
			? '仅用于演示 SvelteKit 的路由功能'
			: "Only for demonstration of SvelteKit's routing functionality"}
	</div>
</div>




================================================
FILE: packages/create-stdf/templates/sktt/README.md
================================================
# SvelteKit + Tailwind + TypeScript + STDF

This template should help get you started developing with Svelte + Tailwind + TypeScript + STDF in SvelteKit.

## Recommended IDE Setup

- [VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) + [Tailwind](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) + [TypeScript](https://typescriptlang.org) + [STDF](https://stdf.design) .

- [WebStorm](https://www.jetbrains.com/webstorm/) + [Svelte](https://www.jetbrains.com/help/webstorm/svelte.html) + [Tailwind](https://www.jetbrains.com/help/webstorm/tailwind-css.html) + [TypeScript](https://typescriptlang.org) + [STDF](https://stdf.design) .

## More Info

For more information about quickly create a new project, see the STDF [Quick start](https://stdf.design/guide) guide.



================================================
FILE: packages/create-stdf/templates/sktt/eslint.config.js
================================================
import prettier from 'eslint-config-prettier';
import js from '@eslint/js';
import { includeIgnoreFile } from '@eslint/compat';
import svelte from 'eslint-plugin-svelte';
import globals from 'globals';
import { fileURLToPath } from 'node:url';
import ts from 'typescript-eslint';
import svelteConfig from './svelte.config.js';

const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url));

export default ts.config(
	includeIgnoreFile(gitignorePath),
	js.configs.recommended,
	...ts.configs.recommended,
	...svelte.configs.recommended,
	prettier,
	...svelte.configs.prettier,
	{
		languageOptions: {
			globals: { ...globals.browser, ...globals.node }
		},
		rules: { 'no-undef': 'off' }
	},
	{
		files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],
		ignores: ['eslint.config.js', 'svelte.config.js'],
		languageOptions: {
			parserOptions: {
				projectService: true,
				extraFileExtensions: ['.svelte'],
				parser: ts.parser,
				svelteConfig
			}
		}
	}
);



================================================
FILE: packages/create-stdf/templates/sktt/package.json
================================================
{
	"name": "sktt",
	"private": true,
	"version": "0.0.1",
	"type": "module",
	"scripts": {
		"dev": "vite dev",
		"build": "vite build",
		"preview": "vite preview",
		"prepare": "svelte-kit sync || echo ''",
		"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
		"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
		"format": "prettier --write .",
		"lint": "prettier --check . && eslint ."
	},
	"devDependencies": {
		"@eslint/compat": "^1.2.5",
		"@eslint/js": "^9.18.0",
		"@sveltejs/adapter-auto": "^4.0.0",
		"@sveltejs/kit": "^2.16.0",
		"@sveltejs/vite-plugin-svelte": "^5.0.0",
		"@tailwindcss/vite": "^4.0.0",
		"eslint": "^9.18.0",
		"eslint-config-prettier": "^10.0.1",
		"eslint-plugin-svelte": "^3.0.0",
		"globals": "^16.0.0",
		"prettier": "^3.4.2",
		"prettier-plugin-svelte": "^3.3.3",
		"prettier-plugin-tailwindcss": "^0.6.11",
		"rollup-plugin-stdf-icon": "file:../../../rollup-plugin-stdf-icon",
		"svelte": "^5.0.0",
		"svelte-check": "^4.0.0",
		"stdf": "file:../../../stdf",
		"tailwindcss": "^4.0.0",
		"typescript": "^5.0.0",
		"typescript-eslint": "^8.20.0",
		"vite": "^6.0.0"
	}
}



================================================
FILE: packages/create-stdf/templates/sktt/svelte.config.js
================================================
import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

const config = {
	preprocess: vitePreprocess(),
	kit: { adapter: adapter() }
};

export default config;



================================================
FILE: packages/create-stdf/templates/sktt/tsconfig.json
================================================
{
	"extends": "./.svelte-kit/tsconfig.json",
	"compilerOptions": {
		"allowJs": true,
		"checkJs": true,
		"esModuleInterop": true,
		"forceConsistentCasingInFileNames": true,
		"resolveJsonModule": true,
		"skipLibCheck": true,
		"sourceMap": true,
		"strict": true,
		"moduleResolution": "bundler"
	}
	// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
	// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
	//
	// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
	// from the referenced tsconfig.json - TypeScript does not merge them in
}



================================================
FILE: packages/create-stdf/templates/sktt/vite.config.ts
================================================
import tailwindcss from '@tailwindcss/vite';
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import svgSprite from 'rollup-plugin-stdf-icon';

export default defineConfig({
	plugins: [
		tailwindcss(),
		sveltekit(),
		// 一般来说，一个应用的的 svg 不多时都放在一个文件夹下，合并为一个 symbol 即可。此处演示了不同文件夹下的图标如何合并为不同的 symbol。
		// Generally speaking, when the svg of an application is not much, it is placed in a folder and merged into one symbol. This example shows how the icons in different folders are merged into different symbols.
		svgSprite([
			{ inFile: 'src/lib/svgs/Heroicons', outFile: 'static/symbols' },
			{ inFile: 'src/lib/svgs/IconPark', outFile: 'static/symbols' },
			{ inFile: 'src/lib/svgs/Remix', outFile: 'static/symbols' },
			// 单独为 Cell 与 NavBar 用到的图标创建一个 symbol。详见：https://stdf.design/guide/icon
			// Create a symbol for the icons used by Cell and NavBar. See: https://stdf.design/guide/icon
			{ inFile: 'src/lib/symbol', outFile: 'static/fonts' }
		])
	]
});



================================================
FILE: packages/create-stdf/templates/sktt/.npmrc
================================================
engine-strict=true



================================================
FILE: packages/create-stdf/templates/sktt/.prettierignore
================================================
# Package Managers
package-lock.json
pnpm-lock.yaml
yarn.lock
bun.lock
bun.lockb



================================================
FILE: packages/create-stdf/templates/sktt/.prettierrc
================================================
{
	"useTabs": true,
	"singleQuote": true,
	"trailingComma": "none",
	"printWidth": 140,
	"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
	"overrides": [
		{
			"files": "*.svelte",
			"options": {
				"parser": "svelte"
			}
		}
	]
}



================================================
FILE: packages/create-stdf/templates/sktt/src/app.css
================================================
@import 'tailwindcss';

@custom-variant dark (&:where(.dark, .dark *));

@theme {
	--color-primary-50: oklch(0.979 0.01 267.36);
	--color-primary-100: oklch(0.95 0.024 270.343);
	--color-primary-200: oklch(0.847 0.074 271.188);
	--color-primary-300: oklch(0.741 0.13 272.232);
	--color-primary-400: oklch(0.634 0.193 271.595);
	--color-primary-500: oklch(0.536 0.252 268.66);
	--color-primary: oklch(0.467 0.296 264.886);
	--color-primary-700: oklch(0.397 0.26 264.877);
	--color-primary-800: oklch(0.331 0.221 264.833);
	--color-primary-900: oklch(0.26 0.178 264.428);
	--color-primary-950: oklch(0.192 0.13 266.64);

	--color-dark-50: oklch(0.995 0.012 101.474);
	--color-dark-100: oklch(0.986 0.025 97.107);
	--color-dark-200: oklch(0.965 0.059 95.884);
	--color-dark-300: oklch(0.938 0.089 92.952);
	--color-dark-400: oklch(0.91 0.114 89.711);
	--color-dark-500: oklch(0.88 0.136 86.375);
	--color-dark: oklch(0.845 0.153 80.597);
	--color-dark-700: oklch(0.71 0.137 75.734);
	--color-dark-800: oklch(0.58 0.118 70.166);
	--color-dark-900: oklch(0.449 0.097 65.209);
	--color-dark-950: oklch(0.321 0.074 62.379);

	--color-primaryBlack: oklch(0.116 0.054 267.087);
	--color-primaryWhite: oklch(0.961 0.001 286.375);
	--color-darkBlack: oklch(0.183 0.035 86.634);
	--color-darkWhite: oklch(0.962 0.001 17.178);

	--color-success: oklch(0.704 0.142 167.084);
	--color-warning: oklch(0.558 0.154 47.186);
	--color-error: oklch(0.564 0.223 28.46);
	--color-info: oklch(0.482 0.14 261.518);

	--color-extend0: oklch(0.703 0.149 235.059);
	--color-Twitter: oklch(0.703 0.149 235.059);
	--color-extend1: oklch(0.702 0.194 38.137);
	--color-Svelte: oklch(0.702 0.194 38.137);
	--color-extend2: oklch(0.482 0.107 161.212);
	--color-Starbucks: oklch(0.482 0.107 161.212);

	--color-black: oklch(0 0 0);
	--color-white: oklch(1 0 0);
	--color-gray-50: oklch(0.961 0 0);
	--color-gray-100: oklch(0.925 0 0);
	--color-gray-200: oklch(0.845 0 0);
	--color-gray-300: oklch(0.767 0 0);
	--color-gray-400: oklch(0.683 0 0);
	--color-gray-500: oklch(0.6 0 0);
	--color-gray-600: oklch(0.51 0 0);
	--color-gray-700: oklch(0.42 0 0);
	--color-gray-800: oklch(0.321 0 0);
	--color-gray-900: oklch(0.218 0 0);
	--color-gray-950: oklch(0.159 0 0);
	--color-transparent: transparent;
}


@source "../node_modules/stdf/**/*.svelte";

html {
	-webkit-tap-highlight-color: transparent;
}


================================================
FILE: packages/create-stdf/templates/sktt/src/app.d.ts
================================================
// See https://svelte.dev/docs/kit/types#app.d.ts
// for information about these interfaces
declare global {
	namespace App {
		// interface Error {}
		// interface Locals {}
		// interface PageData {}
		// interface PageState {}
		// interface Platform {}
	}
}

export {};



================================================
FILE: packages/create-stdf/templates/sktt/src/app.html
================================================
<!doctype html>
<html>
	<head>
		<meta charset="utf-8" />
		<link rel="icon" type="image/svg+xml" href="%sveltekit.assets%/stdf.svg" media="(prefers-color-scheme: light)" />
		<link rel="icon" type="image/svg+xml" href="%sveltekit.assets%/stdf_dark.svg" media="(prefers-color-scheme: dark)" />
		<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
		<title>SvelteKit + Tailwind + TypeScript + STDF</title>
		%sveltekit.head%
	</head>

	<body data-sveltekit-preload-data="hover" class="bg-primaryWhite dark:bg-darkBlack text-black dark:text-white">
		<div style="display: contents">%sveltekit.body%</div>
	</body>
</html>



================================================
FILE: packages/create-stdf/templates/sktt/src/data/nintendo.ts
================================================
import type { ThemeProps } from 'stdf/theme';

const Nintendo: ThemeProps = {
	name: 'Nintendo',
	color: {
		primary: {
			50: 'oklch(0.98 0.01 25.073)', // #FFF6F5 hsl(6, 100%, 98%)
			100: 'oklch(0.953 0.023 24.126)', // #FFEAE8 hsl(5, 100%, 96%)
			200: 'oklch(0.845 0.076 21.796)', // #FAB9B6 hsl(3, 87%, 85%)
			300: 'oklch(0.745 0.133 21.872)', // #F58886 hsl(1, 85%, 74%)
			400: 'oklch(0.662 0.188 22.749)', // #F0575A hsl(359, 84%, 64%)
			500: 'oklch(0.609 0.224 25.256)', // #EB2B34 hsl(357, 83%, 55%)
			default: 'oklch(0.581 0.238 27.862)', // #E60012 hsl(355, 100%, 45%)
			700: 'oklch(0.508 0.207 26.549)', // #C00016 hsl(353, 100%, 38%)
			800: 'oklch(0.43 0.174 24.608)', // #990017 hsl(351, 100%, 30%)
			900: 'oklch(0.351 0.141 21.971)', // #730015 hsl(349, 100%, 23%)
			950: 'oklch(0.266 0.107 17.45)' // #4D0011 hsl(347, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.992 0.011 189.833)', // #F5FFFE hsl(174, 100%, 98%)
			100: 'oklch(0.983 0.024 193.6)', // #E8FFFE hsl(177, 100%, 96%)
			200: 'oklch(0.938 0.067 196.074)', // #B6F9F9 hsl(180, 85%, 85%)
			300: 'oklch(0.893 0.099 198.69)', // #85F0F4 hsl(182, 84%, 74%)
			400: 'oklch(0.847 0.12 201.806)', // #57E4EE hsl(184, 82%, 64%)
			500: 'oklch(0.803 0.131 206.757)', // #2AD6E9 hsl(186, 81%, 54%)
			default: 'oklch(0.752 0.133 215.123)', // #00C3E3 hsl(189, 100%, 45%)
			700: 'oklch(0.646 0.116 218.359)', // #009EBD hsl(190, 100%, 37%)
			800: 'oklch(0.535 0.1 223.819)', // #007998 hsl(192, 100%, 30%)
			900: 'oklch(0.426 0.083 227.589)', // #005772 hsl(194, 100%, 22%)
			950: 'oklch(0.319 0.064 230.58)' // #00384D hsl(196, 100%, 15%)
		},
		primaryBlack: 'oklch(0.139 0.05 18.003)', // #190103 hsl(355, 95%, 5%)
		primaryWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(355, 5%, 95%)
		darkBlack: 'oklch(0.184 0.03 206.812)', // #011619 hsl(188, 95%, 5%)
		darkWhite: 'oklch(0.963 0.001 197.138)', // #F2F3F3 hsl(188, 5%, 95%)
		functional: {
			success: 'oklch(0.669 0.214 144.385)', // #00b42a hsl(134, 100%, 35%)
			warning: 'oklch(0.865 0.176 95.103)', // #f7d00c hsl(50, 94%, 51%)
			error: 'oklch(0.642 0.218 25.88)', // #f53f3f hsl(0, 90%, 60%)
			info: 'oklch(0.549 0.249 263.048)' // #165dff hsl(222, 100%, 54%)
		},
		extend: [
			{
				color: 'oklch(0.492 0.217 261.351)', // #0052d9 hsl(217, 100%, 43%)
				alias: 'Tencent'
			},
			{
				color: 'oklch(0.651 0.212 142.608)', // #1aad19 hsl(120, 75%, 39%)
				alias: 'WeChat'
			},
			{
				color: 'oklch(0.692 0.181 46.213)', // #f37021 hsl(23, 90%, 54%)
				alias: 'Hermès'
			}
		]
	}
};

export default Nintendo;







================================================
FILE: packages/create-stdf/templates/sktt/src/routes/+layout.js
================================================
// 修改 ssr 为 false，使其不再使用服务端渲染，而是使用客户端渲染
// Change ssr to false to use client-side rendering instead of server-side rendering
export const ssr = false;



================================================
FILE: packages/create-stdf/templates/sktt/src/routes/+layout.svelte
================================================
<script lang="ts">
	import '../app.css';

	let { children } = $props();
</script>

{@render children()}



================================================
FILE: packages/create-stdf/templates/sktt/src/routes/+page.svelte
================================================
<script lang="ts">
	import { setContext } from 'svelte';
	import { Button, Cell, Icon, Calendar } from 'stdf';
	import { STDFTheme, switchTheme, darkMode } from 'stdf/theme';
	import NintendoTheme from '../data/nintendo';
	import { en_US, zh_CN } from 'stdf/lang';
	import Counter from './Counter.svelte';

	import { browser } from '$app/environment';

	if (browser) {
		//解决 ios 不支持按钮:active 伪类
		// Solve the problem that ios does not support the button: active pseudo class
		document.body.addEventListener('touchstart', function () {
			//...空函数即可
			// ... Empty function is OK
		});
	}

	//切换亮暗模式 (toggle light or dark mode)
	let mode = $state(sessionStorage.getItem('mode') === 'dark' ? 'dark' : 'light');

	$effect(() => {
		if (mode === 'dark') {
			darkMode(true);
		} else {
			darkMode(false);
		}
	});
	const toggleModeFun = () => {
		if (mode === 'dark') {
			// 切换到 (light switch to light)
			mode = 'light';
			darkMode(false);
			sessionStorage.setItem('mode', 'light');
		} else {
			// 切换到 (dark switch to dark)
			mode = 'dark';
			darkMode(true);
			sessionStorage.setItem('mode', 'dark');
		}
	};

	// 设置语言 (setting language)
	let lang = $state(localStorage.getItem('lang') === 'en_US' ? 'en_US' : 'zh_CN');
	setContext('STDF_lang', localStorage.getItem('lang') === 'en_US' ? en_US : zh_CN);
	const toggleLangFun = () => {
		lang = lang === 'zh_CN' ? 'en_US' : 'zh_CN';
		localStorage.setItem('lang', lang);
		window.location.reload();
	};

	// 进度条 (percent)
	let percent = $state(20);
	const reduceFunc = () => {
		if (percent > 0) {
			percent -= 10;
		}
	};
	const increaseFunc = () => {
		if (percent < 100) {
			percent += 10;
		}
	};

	// 日历(calendar)
	let visible = $state(false);

	// 主题(theme)
	let theme = $state('STDF');
	const toggleThemeFun = () => {
		if (theme === 'STDF') {
			theme = 'Nintendo';
			switchTheme(NintendoTheme);
		} else {
			theme = 'STDF';
			switchTheme(STDFTheme);
		}
	};
</script>

<div class="flex items-center justify-center gap-2 pt-10 text-center">
	<a class="flex w-10 flex-col items-center" href="https://kit.svelte.dev" target="_blank" rel="noreferrer">
		<img src="/svelte.svg" alt="Svelte Logo" />
	</a>+
	<a class="flex w-10 flex-col items-center" href="https://tailwindcss.com" target="_blank" rel="noreferrer">
		<img src="/tailwindcss.svg" alt="Tailwind Logo" />
	</a>+
	<a class="flex w-10 flex-col items-center" href="https://typescriptlang.org" target="_blank" rel="noreferrer">
		<img src="/typescript.svg" alt="Typescript Logo" />
	</a>+
	<a class="flex w-8 flex-col items-center" href="https://stdf.design" target="_blank" rel="noreferrer" aria-label="STDF Logo">
		<svg viewBox="0 0 90 80" fill="currentColor">
			<path
				class="text-primary dark:text-dark"
				d="M0 0H20H40H50C64.8056 0 77.7325 8.04398 84.6487 20H50H40V22.6757V30H50C55.5229 30 60 34.4771 60 40C60 45.5229 55.5229 50 50 50H40V57.3243V78.7398V80H20V66.4583V20H15.3513H0V0ZM50 80C72.0914 80 90 62.0914 90 40C90 36.547 89.5625 33.1962 88.7398 30H67.3244C69.0261 32.9417 70 36.3571 70 40C70 51.0457 61.0457 60 50 60V80Z"
			/>
			<path class="text-dark dark:text-primary" d="M20 30V0L0 50H20V80L40 30H20Z" />
		</svg>
	</a>
</div>
<div class="my-6 text-center text-xs">
	{#if lang === 'zh_CN'}
		<p>这是 SvelteKit + Tailwind + TypeScript + STDF 构建的模板</p>
		<p class="mt-2">点击上方 LOGO 了解更多</p>
	{:else}
		<p>This is a template using SvelteKit + TailwindCSS + TypeScript + STDF</p>
		<p class="mt-2">Click the logo above to learn more</p>
	{/if}
</div>
<div class="my-6">
	<a href="about">
		<Cell title={lang === 'zh_CN' ? '跳转 ABOUT' : 'Go to ABOUT'} />
	</a>
</div>
<div class="my-6">
	<Cell
		title={lang === 'zh_CN' ? '暗模式' : 'Dark mode'}
		right={{ type: 'switch', switch: { active: mode === 'dark' } }}
		onclick={toggleModeFun}
	/>
</div>
<div class="mt-8">
	<Counter bind:percent />
</div>
<div class="mb-8">
	<Button heightIn="0" group fill="lineTheme">
		<div class="flex w-full">
			<button class="border-primary dark:border-dark flex-1 border-r py-2 active:opacity-80" onclick={reduceFunc}>-10</button>
			<button class="border-primary dark:border-dark flex-1 border-r py-2 active:opacity-80" onclick={increaseFunc}>+10</button>
			<button class="flex-1 py-2 active:opacity-80" onclick={() => (percent = 20)}>
				{lang === 'zh_CN' ? '重置' : 'Reset'}
			</button>
		</div>
	</Button>
</div>
<div class="my-6">
	<Button fill="lineTheme" onclick={() => (visible = true)}>{lang === 'zh_CN' ? '日历' : 'Calendar'}</Button>
</div>
<Calendar bind:visible />
<div class="my-6 flex justify-between px-8">
	<Icon name="cake" theme path="symbols/Heroicons.svg" />
	<Icon name="riding-line" path="symbols/Remix.svg" />
	<Icon name="spy-line" theme path="symbols/Remix.svg" />
	<Icon name="javascript-fill" injClass="text-[red] dark:text-green" path="symbols/Remix.svg" />
	<Icon name="cup" theme path="symbols/IconPark.svg" />
</div>
<div class="px-4 text-xs">
	{lang === 'zh_CN' ? '图标：第一个来自' : 'Icons: The first one comes from'}
	<a class="underline" href="https://heroicons.com">Heroicons</a>
	，{lang === 'zh_CN' ? '最后一个来自' : 'the last one comes from'}
	<a class="underline" href="https://iconpark.oceanengine.com">IconPark</a>
	，{lang === 'zh_CN' ? '其余来自' : 'the rest come from'} <a class="underline" href="https://remixicon.com">Remix Icon</a> 。
</div>
<div class="my-6">
	<Button onclick={toggleLangFun}>{lang === 'zh_CN' ? '切换语言' : 'Toggle language'}</Button>
	<Button fill="lineTheme" onclick={toggleThemeFun}>{lang === 'zh_CN' ? '切换主题' : 'Toggle theme'}</Button>
</div>



================================================
FILE: packages/create-stdf/templates/sktt/src/routes/Counter.svelte
================================================
<script lang="ts">
	import { Progress } from 'stdf';

	let { percent = $bindable(20) } = $props();
</script>

<div class="p-4">
	<Progress {percent} />
</div>



================================================
FILE: packages/create-stdf/templates/sktt/src/routes/about/+page.svelte
================================================
<script lang="ts">
	import { NavBar } from 'stdf';

	const lang = localStorage.getItem('lang') === 'en_US' ? 'en_US' : 'zh_CN';
</script>

<svelte:head>
	<title>About</title>
	<meta name="description" content="About this app" />
</svelte:head>

<div class="sticky top-0 z-10">
	<NavBar title={lang === 'zh_CN' ? '关于' : 'ABOUT'} onclickLeft={() => window.history.back()} />
</div>

<div class="space-y-10 px-2 py-20 text-center">
	<div class="text-primary dark:text-dark text-3xl">{lang === 'zh_CN' ? '这是一个关于页面' : 'This is a about page'}</div>
	<div class="text-sm">
		{lang === 'zh_CN' ? '仅用于演示 SvelteKit 的路由功能' : "Only for demonstration of SvelteKit's routing functionality"}
	</div>
</div>




================================================
FILE: packages/rollup-plugin-md-ts/README.md
================================================
[简体中文](https://github.com/any-tdf/stdf/blob/main/packages/rollup-plugin-md-ts/README_CN.md)

## Introduction

This is a Rollup/Vite plugin that converts Markdown files to HTML strings, based on [marked](https://github.com/markedjs/marked).

The implementation idea is based on [rollup-plugin-md](https://github.com/xiaofuzi/rollup-plugin-md), adding TypeScript and compatible with Vite's plugin type.

The STDF doc site <https://stdf.design> uses this plugin.

## Parameters

| Parameter | Type | Default | Description                                                                           |
| --------- | ---- | -------- | ------------------------------------------------------------------------------ |
| marked    | `MarkedOptions` | `{}`   | [marked](https://github.com/markedjs/marked) options.                       |
| include  | `string[]`      | `['**/*.md']`      | The path of the Markdown file to include.                                                 |
| exclude  | `string[]`      | `[]`               | The path of the Markdown file to exclude.                                                 |

The `include` and `exclude` parameters are relative to the project root directory (usually the directory where vite.config.js or vite.config.ts is located).

## Installation

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm i rollup-plugin-md-ts -D
```
<!-- :: -->
<!-- npm -->
```sh
npm i rollup-plugin-md-ts -D
```
<!-- :: -->
<!-- bun -->
```sh
bun add rollup-plugin-md-ts -D
```
<!-- :: -->
<!-- yarn -->
```sh
yarn add rollup-plugin-md-ts -D
```
<!-- ::: -->

## Usage

Configure in vite.config.js or vite.config.ts:

```javascript
import md from 'rollup-plugin-md-ts';

export default defineConfig({
    // ...
	plugins: [
		// ...
		md({
			marked: {},
			include: [ './src/**/*.md']
		})
		// ...
	],
	// ...
});
```

## Why Create

There are already many plugins that can implement similar functions, such as [vite-plugin-markdown](https://www.npmjs.com/package/vite-plugin-markdown), which do not convert the following characters when converting to-do lists, which is exactly the function needed in [STDF](https://stdf.design).

```md
- [ ] TODO
- [x] DONE
```

## License

This project is licensed under the [MIT License](https://github.com/any-tdf/stdf/blob/main/LICENSE).



================================================
FILE: packages/rollup-plugin-md-ts/eslint.config.js
================================================
import prettier from 'eslint-config-prettier';
import js from '@eslint/js';
import globals from 'globals';
import ts from 'typescript-eslint';

export default ts.config(
	js.configs.recommended,
	...ts.configs.recommended,
	prettier,
	{
		languageOptions: {
			globals: {
				...globals.browser,
				...globals.node
			}
		}
	},
	{
		files: ['**/*.ts'],
		languageOptions: {
			parserOptions: {
				parser: ts.parser
			}
		}
	},
	{
		ignores: ['build/', 'dist/']
	}
);



================================================
FILE: packages/rollup-plugin-md-ts/package.json
================================================
{
	"name": "rollup-plugin-md-ts",
	"version": "0.0.3",
	"description": "a rollup plugin for markdown files",
	"type": "module",
	"types": "./dist/index.d.ts",
	"exports": {
		".": {
			"default": "./dist/index.js",
			"types": "./dist/index.d.ts"
		}
	},
	"files": [
		"dist/**"
	],
	"scripts": {
		"pretest": "npm run build",
		"build": "rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript",
		"prebuild": "rm -rf dist/*"
	},
	"keywords": [
		"rollup",
		"plugin",
		"md",
		"markdown",
		"typescript",
		"vite",
		"STDF"
	],
	"author": "any-tdf",
	"funding": "https://stdf.design?fund",
	"license": "MIT",
	"homepage": "https://github.com/any-tdf/stdf/blob/main/packages/rollup-plugin-md-ts/README.md",
	"repository": {
		"type": "git",
		"url": "https://github.com/any-tdf/stdf"
	},
	"bugs": {
		"url": "https://github.com/any-tdf/stdf/issues?q=is:issue+is:open+md"
	},
	"dependencies": {
		"marked": "^15.0.3",
		"rollup": "^4.28.1",
		"rollup-pluginutils": "^2.8.2"
	},
	"devDependencies": {
		"@eslint/js": "^9.16.0",
		"@rollup/plugin-json": "^6.1.0",
		"@rollup/plugin-node-resolve": "^15.3.0",
		"@rollup/plugin-terser": "^0.4.4",
		"@rollup/plugin-typescript": "^12.1.1",
		"assert": "^2.1.0",
		"eslint": "^9.16.0",
		"eslint-config-prettier": "^9.1.0",
		"fs": "^0.0.1-security",
		"globals": "^15.13.0",
		"mocha": "^11.0.1",
		"source-map-support": "^0.5.21",
		"tslib": "^2.8.1",
		"typescript": "^5.7.2",
		"typescript-eslint": "^8.18.0"
	}
}



================================================
FILE: packages/rollup-plugin-md-ts/README_CN.md
================================================
[English](https://github.com/any-tdf/stdf/blob/main/packages/rollup-plugin-md-ts/README.md)

## 介绍

一款 Rollup/Vite 插件，功能是将 Markdown 文件转换为 HTML 字符串，基于 [marked](https://github.com/markedjs/marked) 。

实现思路参考 [rollup-plugin-md](https://github.com/xiaofuzi/rollup-plugin-md) ，增加了 TypeScript 并兼容 Vite 的插件类型。

STDF 文档站点 <https://stdf.design> 使用了此插件。

## 参数

| 参数     | 类型 | 默认             | 描述                                                                           |
| -------- | ---- | ---------------- | ------------------------------------------------------------------------------ |
| marked   | `MarkedOptions` | `{}`   | [marked](https://github.com/markedjs/marked) 的配置。                       |
| include  | `string[]`      | `['**/*.md']`      | 要包含的 Markdown 文件路径。                                                 |
| exclude  | `string[]`      | `[]`               | 要排除的 Markdown 文件路径。                                                 |

其中 include 和 exclude 是相对项目根目录（一般就是 vite.config.js 或 vite.config.ts 所在目录）的相对路径。

## 安装

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm i rollup-plugin-md-ts -D
```
<!-- :: -->
<!-- npm -->
```sh
npm i rollup-plugin-md-ts -D
```
<!-- :: -->
<!-- bun -->
```sh
bun add rollup-plugin-md-ts -D
```
<!-- :: -->
<!-- yarn -->
```sh
yarn add rollup-plugin-md-ts -D
```
<!-- ::: -->

## 使用

在 vite.config.js 或 vite.config.ts 中配置：

```javascript
import md from 'rollup-plugin-md-ts';

export default defineConfig({
    // ...
	plugins: [
		// ...
		md({
			marked: {},
			include: [ './src/**/*.md']
		})
		// ...
	],
	// ...
});
```

## 为何创建

其实市面上已经有很多能实现类似功能的插件，比如 [vite-plugin-markdown](https://www.npmjs.com/package/vite-plugin-markdown) ，这些基于 [markdown-it](https://www.npmjs.com/package/markdown-it) 的插件在转换待办事项列表时，并不会转换以下字符，而这个正好是 [STDF](https://stdf.design) 中需要用到的功能。

```md
- [ ] 待办事项
- [x] 已完成事项
```

## 许可证

本项目基于 [MIT 许可证](https://github.com/any-tdf/stdf/blob/main/LICENSE)。



================================================
FILE: packages/rollup-plugin-md-ts/rollup.config.ts
================================================
import json from '@rollup/plugin-json';
import typescript from '@rollup/plugin-typescript';
import terser from '@rollup/plugin-terser';
import { readFileSync } from 'fs';
const pkg = JSON.parse(readFileSync('./package.json', 'utf8'));
const external = Object.keys(pkg.dependencies);

export default {
	input: 'src/index.ts',
	output: [
		{
			dir: 'dist',
			format: 'es',
			file: pkg['main'],
			sourcemap: true,
			compact: true
		}
	],
	external: external,
	plugins: [
		typescript({
			declaration: true,
			declarationDir: 'dist',
			rootDir: 'src',
			tsconfig: './tsconfig.json'
		}),
		json(),
		terser()
	]
};



================================================
FILE: packages/rollup-plugin-md-ts/tsconfig.json
================================================
{
  "compilerOptions": {
    "target": "ES2018",
    "module": "ESNext",
    "moduleResolution": "node",
    "declaration": true,
    "outDir": "./dist",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
} 


================================================
FILE: packages/rollup-plugin-md-ts/.prettierrc
================================================
{
	"useTabs": true,
	"singleQuote": true,
	"trailingComma": "none",
	"printWidth": 140,
	"plugins": [],
	"overrides": [
		
	]
}



================================================
FILE: packages/rollup-plugin-md-ts/src/index.ts
================================================
import { marked, MarkedOptions } from 'marked';
import { createFilter } from 'rollup-pluginutils';

const ext = /\.md$/;

export type MDOptions = {
	include?: string[];
	exclude?: string[];
	marked?: MarkedOptions;
};

export default function md(options: MDOptions = {}) {
	const filter = createFilter(options.include || ['**/*.md'], options.exclude);
	if (options.marked) {
		marked.setOptions(options.marked);
	}
	return {
		name: 'md',
		// transform 是 rollup 插件必需的方法
		// 用于转换源文件内容
		transform(md: string, id: string) {
			// 检查文件是否是 .md 文件
			if (!ext.test(id)) return null;
			// 检查文件是否匹配 include/exclude 配置
			if (!filter(id)) return null;

			// 使用 marked 解析 markdown，如果没有配置 marked 则返回原始内容
			const data = options.marked ? marked.parse(md, options.marked) : md;
			return {
				// 导出解析后的内容为默认导出
				code: `export default ${JSON.stringify(data.toString())};`,
				// sourcemap 相关
				map: {
					version: 3,
					sources: [id],
					names: [],
					mappings: ''
				}
			};
		}
	};
}



================================================
FILE: packages/rollup-plugin-stdf-icon/README.md
================================================
[简体中文](https://github.com/any-tdf/stdf/blob/main/packages/rollup-plugin-stdf-icon/README_CN.md)

# Introduction

This is a Rollup plugin that combines all SVG files in specified folders (supports multiple) into a single [SVG symbol](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/symbol) for use in [STDF](https://stdf.design) projects. It is compatible with Vite and can be used in other projects created with Vite.

For more information about the STDF Icon component, please refer to the [Icon Guide](https://stdf.design/components?nav=icon&tab=2).

# Installation

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm i rollup-plugin-stdf-icon -D
```
<!-- :: -->
<!-- npm -->
```sh
npm i rollup-plugin-stdf-icon -D
```
<!-- :: -->
<!-- bun -->
```sh
bun add rollup-plugin-stdf-icon -D
```
<!-- :: -->
<!-- yarn -->
```sh
yarn add rollup-plugin-stdf-icon -D
```
<!-- ::: -->

# Usage

Configure the plugin in vite.config.js or vite.config.ts:

```js
// ...
import svgSprite from 'rollup-plugin-stdf-icon';

export default defineConfig({
	// ...
	plugins: [
		// ...
		svgSprite(),
		// ...
	],
	// ...
});
```

During development, simply place the SVG files you need in the specified input folder (default: `src/lib/symbol`). The plugin will automatically combine them into a single SVG symbol file and output it to the specified output folder (default: `static/fonts`). After building with Vite, the files in the public folder will be copied to the dist folder. Therefore, after building, the combined SVG symbol file will be located in the dist/fonts folder. Please refer to the [Vite Asset Handling](https://vitejs.dev/guide/assets.html#the-public-directory) documentation.

> Default parameters are optimized for SvelteKit projects. If you need to adapt it for non-SvelteKit projects created with Vite, please modify the configuration in vite.config.js or vite.config.ts.

Generally, you can simply place the SVG files in the default input folder without the need for additional configuration.

If you need to modify the input/output folders and the filename of the combined file, or if you need to combine multiple folders, you can customize the configuration in vite.config.js or vite.config.ts:

```javascript
// ...
    svgSprite([
        { inFile: 'src/lib/svgs', outFile: 'static/fonts', fileName: 'symbol' },
        { inFile: 'src/lib/icons', outFile: 'static/fonts', fileName: 'icon' },
    ]),
// ...
```

This configuration will combine two symbols. **When using the STDF Icon component, please update the path to the corresponding `fonts/symbol.svg` or `fonts/icon.svg`**.

Note: **The parameter should be an array** representing the configuration for multiple folders. **Each folder configuration should be an object** with `inFile` as the folder where the SVG files to be combined are located, `outFile` as the output path for the combined SVG symbol file, and `fileName` as the filename of the combined SVG symbol file (if not passed, the last folder name of `inFile` will be used). Please ensure the correctness and avoid conflicts in paths and filenames.

In general, the use of symbols is to combine a series of small, single-color SVG files into one symbol. This allows for easy modification of attributes such as color, size, and opacity when using SVG in a project. Therefore, when default configuring rollup-plugin-stdf-icon, the color attributes of the SVG files themselves are removed. If you need to use multi-color SVG files and want to preserve the colors in the generated symbol, you just need to set the `simple` parameter to `false`.

# Array Configuration

| Parameter | Type   | Default          | Description                                                                                                   |
| --------- | ------ | ---------------- | ------------------------------------------------------------------------------------------------------------- |
| inFile    | `string` | `'src/lib/symbol'` | The folder where all the SVG files to be merged are located.                                                  |
| outFile   | `string` | `'static/fonts'`   | The output path for the merged SVG symbol file.                                                               |
| fileName  | `string` | `'symbol'`               | The filename of the merged SVG symbol file (if not passed, the last folder name of `inFile` will be used).    |
| simple    | `boolean` | `true`             | Whether to use the simple mode, the simple mode will remove the color attributes of the SVG files themselves. |

# License

This project is licensed under the [MIT License](https://github.com/any-tdf/stdf/blob/main/LICENSE).



================================================
FILE: packages/rollup-plugin-stdf-icon/package.json
================================================
{
	"name": "rollup-plugin-stdf-icon",
	"version": "0.1.2",
	"description": "A Rollup plugin that combines a series of svg into one symbol for use in the STDF project",
	"main": "dist/index.js",
	"types": "dist/index.d.ts",
	"scripts": {
		"build": "rollup -c",
		"test": "node test/index.js"
	},
	"type": "module",
	"author": "any-tdf",
	"funding": "https://stdf.design?fund",
	"license": "MIT",
	"homepage": "https://github.com/any-tdf/stdf/blob/main/packages/rollup-plugin-stdf-icon/README.md",
	"repository": {
		"type": "git",
		"url": "https://github.com/any-tdf/stdf"
	},
	"bugs": {
		"url": "https://github.com/any-tdf/stdf/issues?q=is:issue+is:open+icon"
	},
	"files": [
		"dist/**"
	],
	"engines": {
		"node": ">=14.14"
	},
	"dependencies": {
		"fs-extra": "^11.2.0",
		"svgo": "^3.3.2",
		"svgstore": "^3.0.1"
	},
	"devDependencies": {
		"@rollup/plugin-terser": "^0.4.4",
		"@rollup/plugin-typescript": "^12.1.1",
		"@types/fs-extra": "^11.0.4",
		"@types/node": "^22.10.2",
		"rollup": "^4.28.1",
		"typescript": "^5.7.2"
	},
	"keywords": [
		"stdf",
		"rollup",
		"symbol",
		"sprite",
		"vite",
		"svg",
		"icon"
	]
}



================================================
FILE: packages/rollup-plugin-stdf-icon/README_CN.md
================================================
[English](https://github.com/any-tdf/stdf/blob/main/packages/rollup-plugin-stdf-icon/README.md)

# 介绍

一个 Rolup 插件，将指定文件夹（支持多个）内的所有 SVG 组合为一个 [SVG symbol](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/symbol)，以在 [STDF](https://stdf.design) 项目中使用。兼容 Vite，也可用于 Vite 创建的其他项目。

关于 STDF 的 Icon 组件，请参考 [Icon 指南](https://stdf.design/components?nav=icon&tab=2)。

# 安装

<!-- :::code-groups -->
<!-- pnpm -->
```sh
pnpm i rollup-plugin-stdf-icon -D
```
<!-- :: -->
<!-- npm -->
```sh
npm i rollup-plugin-stdf-icon -D
```
<!-- :: -->
<!-- bun -->
```sh
bun add rollup-plugin-stdf-icon -D
```
<!-- :: -->
<!-- yarn -->
```sh
yarn add rollup-plugin-stdf-icon -D
```
<!-- ::: -->

# 使用

在 vite.config.js 或 vite.config.ts 中配置：

```js
// ...
import svgSprite from 'rollup-plugin-stdf-icon';

export default defineConfig({
	// ...
	plugins: [
		// ...
		svgSprite(),
		// ...
	],
	// ...
});
```

开发过程中只需要将用到的 svg 文件放到指定的入口文件夹（默认 `src/lib/symbol`），插件会自动将其合并为一个 SVG symbol 文件，输出到指定的输出文件夹（默认 `static/fonts`）。Vite 构建之后 public 文件夹下的文件会被复制到 dist 文件夹下，所以在构建之后，合并的 SVG symbol 文件会出现在 dist/fonts 文件夹下。请参考 [Vite 配置](https://cn.vitejs.dev/guide/assets.html#the-public-directory)。

> 默认参数优先适配 SvelteKit 项目，如果需要适配 Vite 创建的非 SvelteKit 项目，请修改 vite.config.js 或 vite.config.ts 中的配置。

一般来说，按照默认配置将 svg 文件放到入口文件夹即可，无需过多配置。

如果需要修改输入输出文件夹以及合并的文件名，或者同时需要合并多个文件夹，可以在 vite.config.js 或 vite.config.ts 中修改配置：

```javascript
// ...
    svgSprite([
        { inFile: 'src/lib/svgs', outFile: 'static/fonts', fileName: 'symbol' },
        { inFile: 'src/lib/icons', outFile: 'static/fonts', fileName: 'icon' },
    ]),
// ...
```

此配置会合并两个 symbol。**此时使用 STDF 的 Icon 组件时，请配合修改 path 为对应的 `fonts/symbol.svg` 或 `fonts/icon.svg`**

注意：**传入参数为数组**，表示多个文件夹的配置。**每个文件夹的配置为一个对象**，对象中的 inFile 为将要被合并的 SVG 文件所在的文件夹，outFile 为合并后的 SVG symbol 文件的输出路径，fileName 为合并后的 SVG symbol 文件的文件名（如果不传则取 inFile 的最后一个文件夹名称）。请注意路径与文件名的正确性与冲突。

一般来说，使用 symbol 的场景是将一系列小的单色 svg 合并为一个 symbol，可以方便项目使用 svg 时修改颜色、大小、透明度等属性，所以默认配置下 rollup-plugin-stdf-icon 会去除掉 svg 本身的颜色属性。如果需要使用多色 svg，合成的 symbol 需要保留 svg 本身的颜色，只需要将 `simple` 参数设置为 `false`。

# 数组配置

| 参数     | 类型   | 默认             | 描述                                                                           |
| -------- | ------ | ---------------- | ------------------------------------------------------------------------------ |
| inFile   | `string` | `'src/lib/symbol'` | 将要被合并的所有 SVG 文件所在的文件夹。                                        |
| outFile  | `string` | `'static/fonts'`   | 合并后的 SVG symbol 文件的输出路径。                                           |
| fileName | `string` | `'symbol'`               | 合并后的 SVG symbol 文件的文件名（如果不传则取 inFile 的最后一个文件夹名称）。 |
| simple   | `boolean` | `true`             | 是否使用简单模式，简单模式会将 svg 自带的颜色去除。                            |

# 许可证

本项目基于 [MIT 许可证](https://github.com/any-tdf/stdf/blob/main/LICENSE)。



================================================
FILE: packages/rollup-plugin-stdf-icon/rollup.config.js
================================================
import typescript from '@rollup/plugin-typescript';
import terser from '@rollup/plugin-terser';

export default {
    input: 'src/index.ts',
    output: {
        file: 'dist/index.js',
        format: 'esm',
        sourcemap: true,
    },
    plugins: [typescript(), terser()],
    external: ['fs-extra', 'svgo', 'svgstore'],
};



================================================
FILE: packages/rollup-plugin-stdf-icon/tsconfig.json
================================================
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "strict": true,
    "skipLibCheck": true,
    "declaration": true,
    "declarationDir": "dist",
    "outDir": "dist",
    "rootDir": "src"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist", "test"]
} 


================================================
FILE: packages/rollup-plugin-stdf-icon/src/index.ts
================================================
import fs from 'fs-extra';
import { optimize } from 'svgo';
// @ts-expect-error svgstore no declaration file
import svgstore from 'svgstore';

interface StdfIconOptions {
	inFile?: string;
	outFile?: string;
	fileName?: string;
	simple?: boolean;
}

export default function svgSprite(datas: StdfIconOptions[] = []) {
	// 可接收多组参数，处理多个文件夹内的文件
	// Multiple parameters can be accepted to process files in multiple folders
	const data = datas ? datas : [{ inFile: 'src/lib/symbol', outFile: 'static/fonts', fileName: 'symbol', simple: true }];

	// 循环处理每一组参数
	// Loop through each set of parameters
	if (Array.isArray(data)) {
		// 给出提示，开始处理几个文件夹
		// Give a prompt, how many folders are being processed
		console.log(`[rollup-plugin-stdf-icon]: ⌛ Start processing ${data.length} folders...`);

		for (const item of data) {
			const { inFile, outFile, fileName, simple = true } = item;
			// 如果 fileName 为默认 '',则将 inFile 的最后一个文件夹作为 fileName，注意不同操作系统的路径分隔符
			// If fileName is the default '', then the last folder of inFile is used as fileName, pay attention to the path separator of different operating systems
			const fileNameInner = fileName ? fileName : inFile ? inFile.split('/').pop() : 'symbol';
			if (fileNameInner) {
				handleFile(inFile, outFile, fileNameInner, simple);
			}
		}
	}

	return { name: 'rollup-plugin-stdf-icon' };
}

// 处理一个文件夹内的文件
// Process files in a folder
function handleFile(inFile: string | undefined, outFile: string | undefined, fileName: string, simple = true) {
	if (!inFile || !outFile) return;
	// 如果 outFile 不存在，则创建
	// If outFile does not exist, create it
	if (!fs.existsSync(outFile)) {
		fs.mkdirSync(outFile);
	}

	// 创建一个空的 svgstore
	// Create an empty svgstore
	const sprites = svgstore({ cleanDefs: true });

	// 循环 icons 目录下的所有 svg 文件
	// Loop through all svg files in the icons directory
	const svgs = fs.readdirSync(inFile);

	for (const svg of svgs) {
		if (!svg.endsWith('.svg')) {
			// 读取 svg 文件内容，如果文件不是 svg 文件，则给出提示并跳过
			// Read the contents of the svg file, if the file is not an svg file, give a prompt and skip
			console.warn(`[rollup-plugin-stdf-icon]: ⏭️  ${inFile}/${svg} is not a svg file, skip it!`);
		} else {
			const code = fs.readFileSync(`${inFile}/${svg}`, 'utf8');

			// 使用 SVGO 进行优化
			// Use SVGO for optimization
			const result = optimize(code);

			// 删除 result 中的 p-id class 等属性
			// Delete p-id class and other attributes in result
			result.data = result.data.replace(/p-id="[^"]*"/g, '').replace(/class="[^"]*"/g, '');

			// 如果 result 中有 fill 属性，属性值不为 none, 则将 fill 属性值设置为 currentColor
			// If there is a fill attribute in result, the attribute value is not none, then set the fill attribute value to currentColor
			if (simple && result.data.indexOf('fill=') > -1 && result.data.indexOf('fill="none"') === -1) {
				result.data = result.data.replace(/fill="[^"]*"/g, 'fill="currentColor"');
			}

			// 如果 result 中有 stroke 属性，属性值不为 none, 则将 stroke 属性值设置为 currentColor
			// If there is a stroke attribute in result, the attribute value is not none, then set the stroke attribute value to currentColor
			if (simple && result.data.indexOf('stroke=') > -1 && result.data.indexOf('stroke="none"') === -1) {
				result.data = result.data.replace(/stroke="[^"]*"/g, 'stroke="currentColor"');
			}

			// 将优化后的 svg 添加到 sprites 中
			// Add the optimized svg to sprites
			sprites.add(svg.replace('.svg', ''), result.data, { copyAttrs: ['fill', 'stroke'] });
		}
	}

	// 已完成合并（inFile）中的多少个 svg 文件至 outFile/fileName.svg
	// Have merged how many svg files in (inFile) to outFile/fileName.svg
	console.log(`[rollup-plugin-stdf-icon]: ✅ ${inFile} has merged ${svgs.length} svg files to ${outFile}/${fileName}.svg`);

	// 删除 sprites 的 <?xml...?> 标签和 <!DOCTYPE...> 标签 和 <defs/> 标签
	// Delete the <?xml...?> tag and <!DOCTYPE...> tag of sprites
	const spritesStr = sprites
		.toString()
		.replace(/<\?xml[^>]*>/g, '')
		.replace(/<!DOCTYPE[^>]*>/g, '')
		.replace(/<defs\/>/g, '');

	// 写入到指定的文件中
	// Write to the specified file
	fs.writeFileSync(`${outFile}/${fileName}.svg`, spritesStr);
}



================================================
FILE: packages/rollup-plugin-stdf-icon/test/index.js
================================================
import svgSprite from '../dist/index.js';

// 将会在 test 目录下生成 symbol.svg 文件，内容为 test/icons 目录下所有 svg 文件的 symbol
// Let the symbol.svg file be generated in the test directory, and the content is the symbol of all svg files in the test/icons directory
svgSprite([{ inFile: 'test/icons', outFile: 'test', fileName: 'symbol', simple: true }]);




================================================
FILE: packages/stdf/eslint.config.js
================================================
import prettier from 'eslint-config-prettier';
import js from '@eslint/js';
import svelte from 'eslint-plugin-svelte';
import globals from 'globals';
import ts from 'typescript-eslint';

export default ts.config(
	js.configs.recommended,
	...ts.configs.recommended,
	...svelte.configs['flat/recommended'],
	prettier,
	...svelte.configs['flat/prettier'],
	{
		languageOptions: {
			globals: {
				...globals.browser,
				...globals.node
			}
		}
	},
	{
		files: ['**/*.svelte'],

		languageOptions: {
			parserOptions: {
				parser: ts.parser
			}
		}
	},
	{
		ignores: ['build/', '.svelte-kit/', 'dist/']
	}
);



================================================
FILE: packages/stdf/package.json
================================================
{
	"name": "stdf",
	"version": "1.0.8",
	"description": "Mobile web component library based on Svelte and Tailwind",
	"author": "any-tdf",
	"funding": "https://stdf.design?fund",
	"license": "MIT",
	"homepage": "https://stdf.design",
	"repository": {
		"type": "git",
		"url": "https://github.com/any-tdf/stdf"
	},
	"keywords": [
		"svelte",
		"tailwind",
		"ui framework",
		"ui 组件库",
		"移动组件库",
		"moblie ui",
		"web component",
		"svelte v5",
		"tailwind v4"
	],
	"scripts": {
		"dev": "vite dev",
		"build": "vite build",
		"preview": "vite preview",
		"package": "svelte-kit sync && svelte-package && publint",
		"prepublishOnly": "npm run package",
		"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
		"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
		"format": "prettier --write .",
		"lint": "prettier --check . && eslint .",
		"dev_en": "vite --mode english",
		"button": "vite --mode button",
		"icon": "vite --mode icon",
		"navBar": "vite --mode navBar",
		"divider": "vite --mode divider",
		"cell": "vite --mode cell",
		"switch": "vite --mode switch",
		"avatar": "vite --mode avatar",
		"tabs": "vite --mode tabs",
		"tabBar": "vite --mode tabBar",
		"steps": "vite --mode steps",
		"indexBar": "vite --mode indexBar",
		"radio": "vite --mode radio",
		"checkbox": "vite --mode checkbox",
		"input": "vite --mode input",
		"grids": "vite --mode grids",
		"swiper": "vite --mode swiper",
		"placeholder": "vite --mode placeholder",
		"skeleton": "vite --mode skeleton",
		"rate": "vite --mode rate",
		"slider": "vite --mode slider",
		"badge": "vite --mode badge",
		"noticeBar": "vite --mode noticeBar",
		"progress": "vite --mode progress",
		"progressLoop": "vite --mode progressLoop",
		"mask": "vite --mode mask",
		"toast": "vite --mode toast",
		"loading": "vite --mode loading",
		"popup": "vite --mode popup",
		"bottomSheet": "vite --mode bottomSheet",
		"modal": "vite --mode modal",
		"dialog": "vite --mode dialog",
		"actionSheet": "vite --mode actionSheet",
		"picker": "vite --mode picker",
		"asyncPicker": "vite --mode asyncPicker",
		"timePicker": "vite --mode timePicker",
		"calendar": "vite --mode calendar",
		"pagination": "vite --mode pagination",
		"numKeyboard": "vite --mode numKeyboard",
		"button_en": "vite --mode button_en",
		"icon_en": "vite --mode icon_en",
		"navBar_en": "vite --mode navBar_en",
		"divider_en": "vite --mode divider_en",
		"cell_en": "vite --mode cell_en",
		"switch_en": "vite --mode switch_en",
		"avatar_en": "vite --mode avatar_en",
		"tabs_en": "vite --mode tabs_en",
		"tabBar_en": "vite --mode tabBar_en",
		"steps_en": "vite --mode steps_en",
		"indexBar_en": "vite --mode indexBar_en",
		"radio_en": "vite --mode radio_en",
		"checkbox_en": "vite --mode checkbox_en",
		"input_en": "vite --mode input_en",
		"grids_en": "vite --mode grids_en",
		"swiper_en": "vite --mode swiper_en",
		"placeholder_en": "vite --mode placeholder_en",
		"skeleton_en": "vite --mode skeleton_en",
		"rate_en": "vite --mode rate_en",
		"slider_en": "vite --mode slider_en",
		"badge_en": "vite --mode badge_en",
		"noticeBar_en": "vite --mode noticeBar_en",
		"progress_en": "vite --mode progress_en",
		"progressLoop_en": "vite --mode progressLoop_en",
		"mask_en": "vite --mode mask_en",
		"toast_en": "vite --mode toast_en",
		"loading_en": "vite --mode loading_en",
		"popup_en": "vite --mode popup_en",
		"bottomSheet_en": "vite --mode bottomSheet_en",
		"modal_en": "vite --mode modal_en",
		"dialog_en": "vite --mode dialog_en",
		"actionSheet_en": "vite --mode actionSheet_en",
		"picker_en": "vite --mode picker_en",
		"asyncPicker_en": "vite --mode asyncPicker_en",
		"timePicker_en": "vite --mode timePicker_en",
		"calendar_en": "vite --mode calendar_en",
		"pagination_en": "vite --mode pagination_en",
		"numKeyboard_en": "vite --mode numKeyboard_en"
	},
	"files": [
		"dist",
		"!dist/**/*.test.*",
		"!dist/**/*.spec.*"
	],
	"sideEffects": [
		"**/*.css"
	],
	"svelte": "./dist/index.js",
	"types": "./dist/index.d.ts",
	"type": "module",
	"exports": {
		".": {
			"types": "./dist/index.d.ts",
			"svelte": "./dist/index.js"
		},
		"./types": {
			"types": "./dist/types/index.d.ts",
			"svelte": "./dist/types/index.js"
		},
		"./theme": {
			"types": "./dist/theme/index.d.ts",
			"svelte": "./dist/theme/index.js"
		},
		"./lang": {
			"types": "./dist/lang/index.d.ts",
			"svelte": "./dist/lang/index.js"
		},
		"./utils": {
			"types": "./dist/components/utils/index.d.ts",
			"svelte": "./dist/components/utils/index.js"
		}
	},
	"peerDependencies": {
		"svelte": "^5.0.0",
		"tailwindcss": "^4.0.0"
	},
	"devDependencies": {
		"@sveltejs/adapter-static": "^3.0.8",
		"@sveltejs/kit": "^2.19.0",
		"@sveltejs/package": "^2.3.10",
		"@sveltejs/vite-plugin-svelte": "^5.0.3",
		"@tailwindcss/vite": "^4.0.12",
		"eslint": "^9.22.0",
		"eslint-config-prettier": "^10.1.1",
		"eslint-plugin-svelte": "^3.1.0",
		"globals": "^16.0.0",
		"prettier": "^3.5.3",
		"prettier-plugin-svelte": "^3.3.3",
		"prettier-plugin-tailwindcss": "^0.6.11",
		"publint": "^0.3.9",
		"rollup-plugin-stdf-icon": "file:../rollup-plugin-stdf-icon",
		"svelte": "^5.22.6",
		"svelte-check": "^4.1.5",
		"svelte-confetti": "^2.3.1",
		"tailwindcss": "^4.0.12",
		"typescript": "^5.8.2",
		"typescript-eslint": "^8.26.1",
		"vite": "^6.2.1"
	}
}



================================================
FILE: packages/stdf/svelte.config.js
================================================
import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

/** @type {import('@sveltejs/kit').Config} */
const config = {
	// Consult https://svelte.dev/docs/kit/integrations
	// for more information about preprocessors
	preprocess: vitePreprocess(),

	kit: {
		adapter: adapter({ pages: 'build', assets: 'build', fallback: '404.html', precompress: false, strict: true }),
		paths: {
			base: process.argv.includes('dev') ? '' : process.env.BASE_PATH
		}
	}
};

export default config;



================================================
FILE: packages/stdf/tsconfig.json
================================================
{
	"extends": "./.svelte-kit/tsconfig.json",
	"compilerOptions": {
		"allowJs": true,
		"checkJs": true,
		"esModuleInterop": true,
		"forceConsistentCasingInFileNames": true,
		"resolveJsonModule": true,
		"skipLibCheck": true,
		"sourceMap": true,
		"strict": true,
		"module": "NodeNext",
		"moduleResolution": "NodeNext"
	}
}



================================================
FILE: packages/stdf/vite.config.ts
================================================
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import tailwindcss from '@tailwindcss/vite';
import svgSprite from 'rollup-plugin-stdf-icon';

export default defineConfig({
	plugins: [sveltekit(), tailwindcss(), svgSprite([{ inFile: 'src/assets/svgs', outFile: 'static/fonts', fileName: 'symbol' }])],
	server: { hmr: true, host: '0.0.0.0', port: 8888 }
});



================================================
FILE: packages/stdf/.prettierignore
================================================
# Package Managers
package-lock.json
pnpm-lock.yaml
yarn.lock



================================================
FILE: packages/stdf/.prettierrc
================================================
{
	"useTabs": true,
	"singleQuote": true,
	"trailingComma": "none",
	"printWidth": 140,
	"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
	"overrides": [
		{
			"files": "*.svelte",
			"options": {
				"parser": "svelte"
			}
		}
	]
}



================================================
FILE: packages/stdf/src/app.css
================================================
@import 'tailwindcss';

@custom-variant dark (&:where(.dark, .dark *));

@theme {
	--color-primary-50: oklch(0.979 0.01 267.36);
	--color-primary-100: oklch(0.95 0.024 270.343);
	--color-primary-200: oklch(0.847 0.074 271.188);
	--color-primary-300: oklch(0.741 0.13 272.232);
	--color-primary-400: oklch(0.634 0.193 271.595);
	--color-primary-500: oklch(0.536 0.252 268.66);
	--color-primary: oklch(0.467 0.296 264.886);
	--color-primary-700: oklch(0.397 0.26 264.877);
	--color-primary-800: oklch(0.331 0.221 264.833);
	--color-primary-900: oklch(0.26 0.178 264.428);
	--color-primary-950: oklch(0.192 0.13 266.64);

	--color-dark-50: oklch(0.995 0.012 101.474);
	--color-dark-100: oklch(0.986 0.025 97.107);
	--color-dark-200: oklch(0.965 0.059 95.884);
	--color-dark-300: oklch(0.938 0.089 92.952);
	--color-dark-400: oklch(0.91 0.114 89.711);
	--color-dark-500: oklch(0.88 0.136 86.375);
	--color-dark: oklch(0.845 0.153 80.597);
	--color-dark-700: oklch(0.71 0.137 75.734);
	--color-dark-800: oklch(0.58 0.118 70.166);
	--color-dark-900: oklch(0.449 0.097 65.209);
	--color-dark-950: oklch(0.321 0.074 62.379);

	--color-primaryBlack: oklch(0.116 0.054 267.087);
	--color-primaryWhite: oklch(0.961 0.001 286.375);
	--color-darkBlack: oklch(0.183 0.035 86.634);
	--color-darkWhite: oklch(0.962 0.001 17.178);

	--color-success: oklch(0.704 0.142 167.084);
	--color-warning: oklch(0.558 0.154 47.186);
	--color-error: oklch(0.564 0.223 28.46);
	--color-info: oklch(0.482 0.14 261.518);

	--color-extend0: oklch(0.703 0.149 235.059);
	--color-Twitter: oklch(0.703 0.149 235.059);
	--color-extend1: oklch(0.702 0.194 38.137);
	--color-Svelte: oklch(0.702 0.194 38.137);
	--color-extend2: oklch(0.482 0.107 161.212);
	--color-Starbucks: oklch(0.482 0.107 161.212);

	--color-black: oklch(0 0 0);
	--color-white: oklch(1 0 0);
	--color-gray-50: oklch(0.961 0 0);
	--color-gray-100: oklch(0.925 0 0);
	--color-gray-200: oklch(0.845 0 0);
	--color-gray-300: oklch(0.767 0 0);
	--color-gray-400: oklch(0.683 0 0);
	--color-gray-500: oklch(0.6 0 0);
	--color-gray-600: oklch(0.51 0 0);
	--color-gray-700: oklch(0.42 0 0);
	--color-gray-800: oklch(0.321 0 0);
	--color-gray-900: oklch(0.218 0 0);
	--color-gray-950: oklch(0.159 0 0);
	--color-transparent: transparent;

	--font-Trueno: 'Trueno', Trueno;
}
@font-face {
	font-family: Trueno;
	src: url('/fonts/Trueno.otf') format('opentype');
}
*::-webkit-scrollbar {
	width: 6px;
}
*::-webkit-scrollbar-thumb {
	border-radius: 3px;
	background-color: oklch(0.6167 0 0 / 30%);
}
*::-webkit-scrollbar-track {
	background-color: oklch(0.6167 0 0 / 10%);
}
html {
	overflow-y: overlay;
	-webkit-tap-highlight-color: transparent;
	scrollbar-width: none; /* Firefox */
}
body::-webkit-scrollbar {
	display: none;
}
body {
	-ms-overflow-style: none;
}
* {
	-webkit-overflow-scrolling: touch;
}
button:focus {
	outline: none;
}



================================================
FILE: packages/stdf/src/app.d.ts
================================================
// See https://svelte.dev/docs/kit/types#app.d.ts
// for information about these interfaces
declare global {
	namespace App {
		// interface Error {}
		// interface Locals {}
		// interface PageData {}
		// interface PageState {}
		// interface Platform {}
	}
}

export {};



================================================
FILE: packages/stdf/src/app.html
================================================
<!doctype html>
<html>
	<head>
		<meta charset="UTF-8" />
		<link rel="icon" type="image/svg+xml" href="%sveltekit.assets%/stdf_dark.svg" media="(prefers-color-scheme: dark)" />
		<link rel="icon" type="image/svg+xml" href="%sveltekit.assets%/stdf.svg" media="(prefers-color-scheme: light)" />
		<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
		<title>STDF Demo</title>
		%sveltekit.head%
	</head>

	<body
		data-sveltekit-preload-data="hover"
		class="bg-primaryWhite dark:bg-darkBlack relative min-h-screen w-screen text-justify text-black antialiased dark:text-white"
	>
		<main style="display: contents">%sveltekit.body%</main>
	</body>
</html>




================================================
FILE: packages/stdf/src/data/aphorisms.ts
================================================
export default [
	// 中文
	{ text: '爱是永恒不变的力量，能够超越所有维度，当我归来，你已垂暮，我一次呼吸划过了你一辈子的岁月。', from: '—— 《星际穿越》' },
	{ text: '爱一朵花不猜它能开多久，放宽了心情，把什么都变美了。', from: '—— 郭静《在树上唱歌》' },
	{ text: '不是所有的坚持都有结果，但是总有一些坚持，能从一寸冰封的土地里，培育出十万朵怒放的蔷薇。', from: '—— 八月长安《最好的我们》' },
	{ text: '当没有任何一个人信任你的时候，沉默和坚持就是最好的反击和证明。', from: '—— 《沉默的羔羊》' },
	{ text: '既不回头，何必不忘。既然无缘，何需誓言。今日种种，似水无痕。明夕何夕，君已陌路。', from: '—— 《仙剑奇侠传一》' },
	{ text: '记忆是相见的另一种方式。', from: '—— 纪伯伦​​​​' },
	{ text: '没有值得不值得，只有愿意不愿意。', from: '—— 彩衣' },
	{ text: '每朵云都下落不明，每盏月亮都不知所踪。', from: '—— 八月长安《暗恋》' },
	{ text: '让人类永远保持理智，是一种奢求。', from: '—— MOSS' },
	{ text: '生命的闪耀不坚持到底怎能看到，与其苟延残喘不如纵情燃烧。', from: '—— 《追梦赤子心》' },
	{ text: '生活坏到一定程度就会好起来，因为它无法更坏，努力过后，才知道许多事情，坚持坚持，就过来了。', from: '—— 宫崎骏《千与千寻》' },
	{
		text: '我每天醒在鸟声里。我从梦里就听到鸟叫，直到我醒来。我听得出几种极熟悉的叫声，那是每天都叫的，似乎每天都在那个固定的枝头。',
		from: '—— 汪曾祺'
	},
	{ text: '我相信人类的勇气可以跨越时间，跨越当下，跨越未来。', from: '—— 《流浪地球 2》' },
	{
		text: '于千万人之中遇见你所要遇见的人，于千万年之中，时间的无涯的荒野里，没有早一步，也没有晚一步，刚巧赶上了，那也没有别的话可说，惟有轻轻地问一声：“噢，你也在这里吗？”',
		from: '—— 张爱玲《爱》'
	},
	{ text: '御剑乘风来，除魔天地间，有酒乐逍遥，无酒我亦癫。一饮尽江河，再饮吞日月，千杯醉不倒，唯我酒剑仙。', from: '—— 酒剑仙' },
	{ text: '最美的不是下雨天，是曾与你躲过雨的屋檐。', from: '—— 周杰伦《不能说的秘密》' },

	// English
	{ text: 'All the splendor in the world is not worth a good friend.', from: '— Voltaire' },
	{ text: 'Continuous labor is the life of the iron law, also the art of iron.', from: '— Balzac' },
	{
		text: 'Do not go gentle into that good night; Old age should burn and rave at close of day. Rage, rage against the dying of the light.',
		from: '— Dylan Thomas'
	},
	{
		text: 'Hope is a good thing, maybe the best of things and no good thing ever dies.',
		from: '— The Shawshank Redemption',
		fromItalic: true
	},
	{ text: 'Honesty and diligence should be your eternal mates.', from: '— Franklin' },
	{ text: 'If a man deceives me once, shame on him; if twice,shame on me.', from: '— John Ray' },
	{ text: 'Life is a kind of endless yearning, eager to continue to rise, become more great and noble.', from: '— Du Charm' },
	{ text: 'The best way to find yourself is to lose yourself in the service of others.', from: '— Gandhi' },
	{ text: 'The best way to cheer yourself up is to try to cheer somebody else up.', from: '— Mark Twain' },
	{
		text: 'The body is always in the end. In addition to thinking, there is no beautiful and interesting things to stay, because thought is life.',
		from: '— Bernard Shaw'
	},
	{
		text: "We should not be at any price to keep our friendship, so that it is defiled. If you have to sacrifice friendship for that great love, that's no way to do it; but if you can keep it, it will be a perfect state.",
		from: '— Tagore'
	}
];



================================================
FILE: packages/stdf/src/data/menuList.ts
================================================
export type MenuListChild = {
	title: string;
	title_zh: string;
	title_en: string;
	nav: string;
	tip: string;
	tip_en: string;
	alias: string;
};
export type MenuList = { class: string; class_en: string; childs: MenuListChild[] };

export const menuList: MenuList[] = [
	{
		class: '通用',
		class_en: 'Universal',
		childs: [
			{
				title: '按钮 Button',
				title_zh: '按钮',
				title_en: 'Button',
				nav: 'button',
				tip: '按下它，让世界变得更美好吧。',
				tip_en: 'Press it and make the world a better place.',
				alias: 'button|按钮'
			},
			{
				title: '底部浮窗 BottomSheet',
				title_zh: '底部浮窗',
				title_en: 'BottomSheet',
				nav: 'bottomSheet',
				tip: '浮窗犹如小偷，突然出现让你焦灼，却也能唤起你的警觉。',
				tip_en: 'The floating window is like a thief, suddenly appearing to make you anxious, but it can also arouse your alertness.',
				alias:
					'bottomSheet|底部浮窗 | 底部 | 底|部 | 浮窗|bottomSheet 底部浮窗|bottomSheet 底部浮窗 | 底部弹窗|bottomSheet 底部弹窗|bottomSheet 底部弹窗 | 底部弹出框|bottomSheet 底部弹出框|bottomSheet 底部弹出框 | 底部弹出层|bottomSheet 底部弹出层|bottomSheet 底部弹出层'
			},
			{
				title: '图标 Icon',
				title_zh: '图标',
				title_en: 'Icon',
				nav: 'icon',
				tip: '使用 SVG Sprites，请参照指南引入与使用。',
				tip_en: 'Use SVG Sprites, please refer to the guide to import and use.',
				alias: 'icon|图标|svg'
			},
			{
				title: '遮罩 Mask',
				title_zh: '遮罩',
				title_en: 'Mask',
				nav: 'mask',
				tip: '遮罩虽能掩盖身形，却无法掩藏内心。',
				tip_en: 'Although the mask can cover the figure, it cannot hide the heart.',
				alias: 'mask|遮罩 | 遮|罩|mask 遮罩|mask 遮罩 | 遮罩层|mask 遮罩层|mask 遮罩层|Overlay|maskOverlay|mask Overlay'
			},
			{
				title: '弹出层 Popup',
				title_zh: '弹出层',
				title_en: 'Popup',
				nav: 'popup',
				tip: '机会就像弹珠，只有你努力地推它，它才会弹出来。',
				tip_en: 'Opportunity is like a marble, only if you push it hard, it will pop out.',
				alias:
					'popup|弹出层 | 弹出 | 弹|出 | 层|popup 弹出层|popup 弹出层 | 弹窗|popup 弹窗|popup 弹窗 | 弹出框|popup 弹出框|popup 弹出框 | 弹出层|popup 弹出层|popup 弹出层'
			}
		]
	},
	{
		class: '布局',
		class_en: 'Layout',
		childs: [
			{
				title: '分割线 Divider',
				title_zh: '分割线',
				title_en: 'Divider',
				nav: 'divider',
				tip: '分开的日子越久，最初的喜悦越发淡薄。',
				tip_en: 'The longer the days are separated, the more the initial joy fades.',
				alias: 'divider|分割线 | 分割|line'
			},
			{
				title: '网格 Grids',
				title_zh: '网格',
				title_en: 'Grids',
				nav: 'grids',
				tip: '可是怎么说，总觉得，我们之间留了太多空白格。',
				tip_en: 'How can I say, I always feel that there are too many blank grids between us.',
				alias: 'grids|网格|grid|row|col|column'
			},
			{
				title: '占位符 Placeholder',
				title_zh: '占位符',
				title_en: 'Placeholder',
				nav: 'placeholder',
				tip: '人生重要的不是所站的位置，而是所朝的方向。',
				tip_en: 'What is important in life is not the position you stand, but the direction you face.',
				alias: 'placeholder|占位符 | 占位'
			},
			{
				title: '骨架屏 Skeleton',
				title_zh: '骨架屏',
				title_en: 'Skeleton',
				nav: 'skeleton',
				tip: '骨架是支撑身体的关键，而人生信念则是支撑生命的骨架。',
				tip_en: 'The skeleton is the key to supporting the body, and the belief in life is the skeleton that supports life.',
				alias: 'skeleton|骨架屏 | 骨架'
			}
		]
	},
	{
		class: '导航',
		class_en: 'Navigation',
		childs: [
			{
				title: '索引栏 IndexBar',
				title_zh: '索引栏',
				title_en: 'IndexBar',
				nav: 'indexBar',
				tip: '你不迷途知返，我怎么给你以索引？',
				tip_en: "If you don't know the way back, how can I give you an index?",
				alias: 'indexBar|索引栏|indexbar|index|bar|索引|index 栏 | 索引条|index 条|index 条'
			},
			{
				title: '导航栏 NavBar',
				title_zh: '导航栏',
				title_en: 'NavBar',
				nav: 'navBar',
				tip: '没有指引，在黑暗中只能乱撞。',
				tip_en: 'Without guidance, you can only bump in the dark.',
				alias: 'navBar|导航栏|navbar|nav|bar|导航|nav-bar|nav bar'
			},
			{
				title: '分页 Pagination',
				title_zh: '分页',
				title_en: 'Pagination',
				nav: 'pagination',
				tip: '人生就像一部电影，不论多么精彩，也有谢幕的时候。',
				tip_en: 'Life is like a movie, no matter how wonderful it is, there is a curtain call.',
				alias: 'pagination|分页|page|分 | 页|pagination 分页|pagination 分页|page 分页|page 分页'
			},
			{
				title: '步骤条 Steps',
				title_zh: '步骤条',
				title_en: 'Steps',
				nav: 'steps',
				tip: '人生没有白走的路，每一步都算数。',
				tip_en: 'Life has no wasted steps, every step counts.',
				alias: 'steps|step|步骤条 | 步骤|step 条|step 条 | 步骤栏|step 栏|step 栏'
			},
			{
				title: '标签栏 TabBar',
				title_zh: '标签栏',
				title_en: 'TabBar',
				nav: 'tabBar',
				tip: '看脚下一片黑暗，望头顶星光璀璨。',
				tip_en: "Looking down, it's all darkness; looking up, the stars are shining brightly.",
				alias: 'tabBar|标签栏|tabbar|tab|bar|标签|tab 栏'
			},
			{
				title: '标签页 Tabs',
				title_zh: '标签页',
				title_en: 'Tabs',
				nav: 'tabs',
				tip: '偶尔隐藏，是为了在合适的时候更好地绽放。',
				tip_en: 'Occasionally hide, it is to bloom better at the right time.',
				alias: 'tabs|tab|标签页 | 标签|tab 页'
			}
		]
	},
	{
		class: '数据输入',
		class_en: 'Data entry',
		childs: [
			{
				title: '动作面板 ActionSheet',
				title_zh: '动作面板',
				title_en: 'ActionSheet',
				nav: 'actionSheet',
				tip: '我的世界只有一个选项，就是你。',
				tip_en: 'There is only one option in my world, and that is you.',
				alias:
					'actionSheet|动作面板 | 动作 | 动|作 | 面板|actionSheet 动作面板|actionSheet 动作面板 | 动作面板|actionSheet 动作面板|actionSheet 动作面板 | 动作面板|actionSheet 动作面板|actionSheet 动作面板'
			},
			{
				title: '异步选择器 AsyncPicker',
				title_zh: '异步选择器',
				title_en: 'AsyncPicker',
				nav: 'asyncPicker',
				tip: '错过的话，就请错过一辈子吧！',
				tip_en: 'If you miss it, please miss it for a lifetime!',
				alias: 'asyncPicker|异步选择器 | 异步|asyncPicker 异步选择器|asyncPicker 异步选择器|async picker|asyncpicker|异步 picker|异步 picker'
			},
			{
				title: '日历 Calendar',
				title_zh: '日历',
				title_en: 'Calendar',
				nav: 'calendar',
				tip: '在无人问津日子里，正是登峰造极的好时机。',
				tip_en: 'In the days when no one cares, it is a good time to reach the peak.',
				alias:
					'calendar|日历 | 日|历|calendar 日历|calendar 日历 | 日期|calendar 日期|calendar 日期 | 周选择|calendar 周选择|calendar 周选择 | 周|calendar 周|calendar 周 | 日期区间 | 月选择 | 日期范围选择'
			},
			{
				title: '复选框 Checkbox',
				title_zh: '复选框',
				title_en: 'Checkbox',
				nav: 'checkbox',
				tip: '要么全不，要么全部。',
				tip_en: 'Either all or none.',
				alias:
					'checkbox|复选框 | 复选|checkbox 复选框|checkbox 复选框 | 复选按钮|checkbox 复选按钮|checkbox 复选按钮 | 多选框 | 多选|checkbox 多选框|checkbox 多选框 | 多选按钮|checkbox 多选按钮|checkbox 多选按钮'
			},
			{
				title: '输入框 Input',
				title_zh: '输入框',
				title_en: 'Input',
				nav: 'input',
				tip: '对方正在输入......',
				tip_en: 'The other party is typing...',
				alias:
					'input|输入框 | 输入|input 输入框|input 输入框|Textarea|textarea|文本域 | 文本框 | 文本|textarea 文本域|textarea 文本域 | 多行输入框 | 多行输入 | 多行|textarea 多行输入框|textarea 多行输入框'
			},
			{
				title: '数字键盘 NumKeyboard',
				title_zh: '数字键盘',
				title_en: 'NumKeyboard',
				nav: 'numKeyboard',
				tip: '3 0624700 | 3 0624770 | 5 34202 13942 | 4314 0624',
				tip_en: '3 0624700 | 3 0624770 | 5 34202 13942 | 4314 0624',
				alias:
					'numKeyboard|数字键盘 | 数字 | 键盘|numKeyboard 数字键盘|numKeyboard 数字键盘 | 金额键盘|numKeyboard 金额键盘|numKeyboard 金额键盘|number|keyboard|amount|money|'
			},
			{
				title: '选择器 Picker',
				title_zh: '选择器',
				title_en: 'Picker',
				nav: 'picker',
				tip: '采摘花瓣时，你得不到花的美丽。',
				tip_en: 'When you pick petals, you don’t get the beauty of the flower.',
				alias: 'picker|选择器 | 选择|picker 选择器|picker 选择器'
			},
			{
				title: '单选框 Radio',
				title_zh: '单选框',
				title_en: 'Radio',
				nav: 'radio',
				tip: '如果要在正确和善良中选择一个，请选择善良。',
				tip_en: 'If you have to choose between right and good, choose good.',
				alias: 'radio|单选框 | 单选|radio 单选框|radio 单选框 | 单选按钮|radio 单选按钮|radio 单选按钮'
			},
			{
				title: '评分 Rate',
				title_zh: '评分',
				title_en: 'Rate',
				nav: 'rate',
				tip: '散场时，对方剩余的手机电量，就是这场约会的评分。',
				tip_en: 'At the end of the game, the remaining battery power of the other party is the score of this date.',
				alias: 'rate|评分 | 评|分|rate 评分|rate 评分'
			},
			{
				title: '滑块 Slider',
				title_zh: '滑块',
				title_en: 'Slider',
				nav: 'slider',
				tip: '请滑动解锁您的烦恼。',
				tip_en: 'Please slide to unlock your troubles.',
				alias: 'slider|滑块 | 滑|块|slider 滑块|slider 滑块'
			},
			{
				title: '开关 Switch',
				title_zh: '开关',
				title_en: 'Switch',
				nav: 'switch',
				tip: '死亡是一个开关，活着却是一根绳索。',
				tip_en: 'Death is a switch, but life is a rope.',
				alias: 'switch|开关 | 开|关|switch 开关|switch 开关'
			},
			{
				title: '步进器 Stepper',
				title_zh: '步进器',
				title_en: 'Stepper',
				nav: 'stepper',
				tip: '人生如同诗行，或进或退皆成章。保持心灵节奏，生命之诗韵味悠长。',
				tip_en:
					'Life is like a poem, advancing or retreating all form chapters. Maintain the rhythm of the soul, and the poetic flavor of life will last long.',
				alias: 'stepper|步进器 | 步|进 | 器|stepper 步进器|stepper 步进器'
			},
			{
				title: '时间选择器 TimePicker',
				title_zh: '时间选择器',
				title_en: 'TimePicker',
				nav: 'timePicker',
				tip: '死亡不是失去生命，而是走出了时间的枷锁。',
				tip_en: 'Death is not the loss of life, but the release of the shackles of time.',
				alias:
					'timePicker|时间选择器 | 时间|timePicker 时间选择器|timePicker 时间选择器|time picker|timepicker|时间 picker|时间 picker|日期选择器 | 日期|datePicker 日期选择器|datePicker 日期选择器|date picker|datepicker|日期 picker|日期 picker'
			}
		]
	},
	{
		class: '信息展示',
		class_en: 'Info display',
		childs: [
			{
				title: '头像 Avatar',
				title_zh: '头像',
				title_en: 'Avatar',
				nav: 'avatar',
				tip: '其实我发给您的头像，是情侣头像...',
				tip_en: 'Actually, the avatar I sent to you is a couple avatar...',
				alias: 'avatar|头像 | 头|像|avatar 头像|avatar 头像'
			},
			{
				title: '徽标 Badge',
				title_zh: '徽标',
				title_en: 'Badge',
				nav: 'badge',
				tip: '在标记消失之前，回到我身边。',
				tip_en: 'Before the mark disappears, come back to me.',
				alias: 'badge|徽标 | 徽|标|badge 徽标|badge 徽标 | 标记|badge 标记|badge 标记'
			},
			{
				title: '单元格 Cell',
				title_zh: '单元格',
				title_en: 'Cell',
				nav: 'cell',
				tip: '当全世界抛弃您的时候请记住，您身上有几亿细胞都在为你而活。',
				tip_en: 'When the whole world abandons you, remember that there are billions of cells on your body that are living for you.',
				alias: 'cell|单元格 | 单元|cell 单元格|cell 单元格'
			},
			{
				title: '通告栏 NoticeBar',
				title_zh: '通告栏',
				title_en: 'NoticeBar',
				nav: 'noticeBar',
				tip: '我方开放地下城，这是告知，不是商量。',
				tip_en: 'Our side opens the dungeon, this is to inform, not to discuss.',
				alias:
					'noticeBar|通告栏 | 通告 | 通|栏|noticeBar 通告栏|noticeBar 通告栏 | 通知栏|noticeBar 通知栏|noticeBar 通知栏 | 公告栏|noticeBar 公告栏|noticeBar 公告栏'
			},
			{
				title: '进度条 Progress',
				title_zh: '进度条',
				title_en: 'Progress',
				nav: 'progress',
				tip: '好运进度：▓▓▓▓▓▓▓▓▓▓▓▓ 100%',
				tip_en: 'Good luck progr: ▓▓▓▓▓▓▓▓▓▓▓▓ 100%',
				alias: 'progress|进度条 | 进度 | 进|度|progress 进度条|progress 进度条'
			},
			{
				title: '进度环 ProgressLoop',
				title_zh: '进度环',
				title_en: 'ProgressLoop',
				nav: 'progressLoop',
				tip: '人生不是一个完美的圆环，一旦完美，你就再没有任何可能性。',
				tip_en: 'Life is not a perfect circle. Once perfect, you have no possibility.',
				alias:
					'progressLoop|进度环 | 进度 | 进|度|progressLoop 进度环|progressLoop 进度环 | 环形进度条|progressLoop 环形进度条|progressLoop 环形进度条|progress loop|progress-loop'
			},
			{
				title: '轮播 Swiper',
				title_zh: '轮播',
				title_en: 'Swiper',
				nav: 'swiper',
				tip: '人世间悲喜烂剧，昼夜轮播不停。',
				tip_en: 'The ups and downs of life, day and night, are not stopping.',
				alias: 'swiper|轮播 | 轮|播|swiper 轮播|swiper 轮播 | 轮播图|swiper 轮播图|swiper 轮播图 | 走马灯|swiper 走马灯|swiper 走马灯|carousel'
			}
		]
	},
	{
		class: '反馈',
		class_en: 'Feedback',
		childs: [
			{
				title: '对话框 Dialog',
				title_zh: '对话框',
				title_en: 'Dialog',
				nav: 'dialog',
				tip: '无法确定任何事情，尤其是按下“确定”键的那一刻，我最不确定。',
				tip_en: 'Nothing can be determined, especially at the moment when the "OK" button is pressed, I am the most uncertain.',
				alias:
					'dialog|对话框 | 对话 | 对|话 | 框|dialog 对话框|dialog 对话框 | 对话框|dialog 对话框|dialog 对话框 | 对话框|dialog 对话框|dialog 对话框 | 对话框|dialog 对话框|dialog 对话框'
			},
			{
				title: '加载 Loading',
				title_zh: '加载',
				title_en: 'Loading',
				nav: 'loading',
				tip: '不要再苦苦等待答案了，没有回复已是答案。',
				tip_en: "Don't wait for the answer, no reply is the answer.",
				alias: 'loading|加载 | 加载中|loading 加载|loading 加载|loading 加载中|loading 加载中|loading 加载中...|loading 加载中...'
			},
			{
				title: '弹框 Modal',
				title_zh: '弹框',
				title_en: 'Modal',
				nav: 'modal',
				tip: '弹框即人生，要么选择关闭，要么选择继续。',
				tip_en: 'The modal is life, either choose to close or choose to continue.',
				alias:
					'modal|弹框 | 弹|框|modal 弹框|modal 弹框 | 弹窗|modal 弹窗|modal 弹窗 | 弹出框|modal 弹出框|modal 弹出框 | 弹框|modal 弹框|modal 弹框 | 模态框|modal 模态框|modal 模态框'
			},
			{
				title: '轻提示 Toast',
				title_zh: '轻提示',
				title_en: 'Toast',
				nav: 'toast',
				tip: '总有一些东西，要用消失来证明它的珍贵。',
				tip_en: 'There are always some things that have to disappear to prove their value.',
				alias:
					'toast|轻提示 | 轻|提示|toast 轻提示|toast 轻提示 | 轻弹窗|toast 轻弹窗|toast 轻弹窗 | 轻提示框|toast 轻提示框|toast 轻提示框 | 吐司|toast 吐司|toast 吐司'
			}
		]
	}
];



================================================
FILE: packages/stdf/src/data/themes/aqua.ts
================================================
import type { ThemeProps } from '$lib/theme/types.js';

const Aqua: ThemeProps = {
	name: 'Aqua',
	color: {
		primary: {
			50: 'oklch(0.987 0.008 225.079)', // #F5FCFF hsl(198, 100%, 98%)
			100: 'oklch(0.969 0.019 225.712)', // #E8F8FF hsl(198, 100%, 96%)
			200: 'oklch(0.832 0.048 227.654)', // #A8CFE1 hsl(199, 49%, 77%)
			300: 'oklch(0.699 0.07 233.534)', // #72A6C3 hsl(202, 40%, 61%)
			400: 'oklch(0.575 0.083 237.386)', // #4580A4 hsl(203, 41%, 46%)
			500: 'oklch(0.46 0.09 243.106)', // #235D86 hsl(205, 59%, 33%)
			default: 'oklch(0.355 0.089 248.677)', // #0A3E68 hsl(207, 83%, 22%)
			700: 'oklch(0.329 0.09 251.443)', // #073661 hsl(209, 87%, 20%)
			800: 'oklch(0.302 0.09 253.945)', // #042E5A hsl(211, 92%, 18%)
			900: 'oklch(0.277 0.09 255.696)', // #022753 hsl(213, 95%, 17%)
			950: 'oklch(0.253 0.091 257.423)' // #00204D hsl(215, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.997 0.013 111.26)', // #FEFFF5 hsl(66, 100%, 98%)
			100: 'oklch(0.992 0.03 110.976)', // #FDFFE8 hsl(65, 100%, 96%)
			200: 'oklch(0.946 0.068 113.937)', // #ECF3BF hsl(68, 68%, 85%)
			300: 'oklch(0.9 0.101 116.179)', // #DAE799 hsl(70, 62%, 75%)
			400: 'oklch(0.857 0.13 118.796)', // #C7DC76 hsl(72, 59%, 66%)
			500: 'oklch(0.812 0.152 121.068)', // #B3D055 hsl(74, 57%, 58%)
			default: 'oklch(0.767 0.167 123.364)', // #9FC438 hsl(76, 56%, 49%)
			700: 'oklch(0.673 0.157 125.534)', // #7FA624 hsl(78, 64%, 40%)
			800: 'oklch(0.577 0.143 127.636)', // #618813 hsl(80, 76%, 30%)
			900: 'oklch(0.479 0.124 129.495)', // #466A08 hsl(82, 86%, 22%)
			950: 'oklch(0.381 0.104 130.976)' // #2E4D00 hsl(84, 100%, 15%)
		},
		primaryBlack: 'oklch(0.156 0.033 240.386)', // #010E19 hsl(207, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(207, 5%, 95%)
		darkBlack: 'oklch(0.199 0.046 122.93)', // #121901 hsl(76, 95%, 5%)
		darkWhite: 'oklch(0.964 0.001 106.424)', // #F3F3F2 hsl(76, 5%, 95%)
		functional: {
			success: 'oklch(0.577 0.18 144.916)', // #069327 hsl(134, 92%, 30%)
			warning: 'oklch(0.615 0.147 54.981)', // #c66810 hsl(29, 85%, 42%)
			error: 'oklch(0.559 0.203 26.879)', // #d12929 hsl(0, 67%, 49%)
			info: 'oklch(0.455 0.194 263.236)' // #1649c0 hsl(222, 79%, 42%)
		},
		extend: [
			{
				color: 'oklch(0.345 0.194 290.65)', // #410093 hsl(267, 100%, 29%)
				alias: 'Yahoo!'
			},
			{
				color: 'oklch(0.651 0.212 142.608)', // oklch(0.651 0.212 142.608) hsl(120, 75%, 39%)
				alias: 'WeChat'
			},
			{
				color: 'oklch(0.689 0.196 21.407)', // #fd5c63 hsl(357, 98%, 68%)
				alias: 'Airbnb'
			}
		]
	}
};

export default Aqua;



================================================
FILE: packages/stdf/src/data/themes/azuper.ts
================================================
import type { ThemeProps } from '$lib/theme/types.js';

const Azuper: ThemeProps = {
	name: 'Azuper',
	color: {
		primary: {
			50: 'oklch(0.987 0.008 225.079)', // #F5FCFF hsl(198, 100%, 98%)
			100: 'oklch(0.967 0.019 230.689)', // #E8F7FF hsl(201, 100%, 96%)
			200: 'oklch(0.827 0.048 234.484)', // #A9CCE1 hsl(203, 48%, 77%)
			300: 'oklch(0.692 0.069 240.216)', // #74A2C3 hsl(205, 40%, 61%)
			400: 'oklch(0.565 0.085 244.974)', // #487BA5 hsl(207, 39%, 47%)
			500: 'oklch(0.45 0.094 249.497)', // #265887 hsl(209, 56%, 34%)
			default: 'oklch(0.347 0.095 253.302)', // #0D3A69 hsl(211, 78%, 23%)
			700: 'oklch(0.317 0.097 256.274)', // #093162 hsl(213, 83%, 21%)
			800: 'oklch(0.291 0.098 258.443)', // #06295B hsl(215, 88%, 19%)
			900: 'oklch(0.266 0.098 259.566)', // #032254 hsl(217, 93%, 17%)
			950: 'oklch(0.241 0.099 260.073)' // #001B4D hsl(219, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.984 0.009 44.894)', // #FFF8F5 hsl(18, 100%, 98%)
			100: 'oklch(0.963 0.02 45.262)', // #FFEFE8 hsl(18, 100%, 96%)
			200: 'oklch(0.889 0.047 41.262)', // #F7D1C3 hsl(16, 77%, 87%)
			300: 'oklch(0.817 0.075 38.298)', // #EFB3A0 hsl(14, 71%, 78%)
			400: 'oklch(0.747 0.107 34.759)', // #E8947F hsl(12, 70%, 70%)
			500: 'oklch(0.68 0.138 32.855)', // #E0755F hsl(10, 68%, 63%)
			default: 'oklch(0.621 0.167 31.47)', // #D85742 hsl(8, 66%, 55%)
			700: 'oklch(0.522 0.165 29.582)', // #B5372A hsl(6, 62%, 44%)
			800: 'oklch(0.433 0.152 29.344)', // #921F16 hsl(4, 74%, 33%)
			900: 'oklch(0.348 0.132 28.566)', // #6F0C09 hsl(2, 85%, 24%)
			950: 'oklch(0.264 0.108 29.234)' // #4D0000 hsl(0, 100%, 15%)
		},
		primaryBlack: 'oklch(0.15 0.035 247.014)', // #010C19 hsl(211, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(211, 5%, 95%)
		darkBlack: 'oklch(0.148 0.043 37.362)', // #190401 hsl(8, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(8, 5%, 95%)
		functional: {
			success: 'oklch(0.663 0.189 146.376)', // #21b043 hsl(134, 68%, 41%)
			warning: 'oklch(0.652 0.163 41.893)', // #df6734 hsl(18, 73%, 54%)
			error: 'oklch(0.616 0.196 13.669)', // #e14161 hsl(348, 73%, 57%)
			info: 'oklch(0.523 0.229 273.504)' // #484eea hsl(238, 79%, 60%)
		},
		extend: [
			{
				color: 'oklch(0.492 0.217 261.351)', // oklch(0.492 0.217 261.351) hsl(217, 100%, 43%)
				alias: 'Tencent'
			},
			{
				color: 'oklch(0.654 0.154 241.655)', // #0099e5 hsl(200, 100%, 45%)
				alias: '500px'
			},
			{
				color: 'oklch(0.571 0.235 261.561)', // #1769ff hsl(219, 100%, 55%)
				alias: 'Behance'
			}
		]
	}
};

export default Azuper;



================================================
FILE: packages/stdf/src/data/themes/azurePink.ts
================================================
import type { ThemeProps } from '$lib/theme/types.js';

const AzurePink: ThemeProps = {
	name: 'AzurePink',
	color: {
		primary: {
			50: 'oklch(0.977 0.011 274.897)', // #F5F7FF hsl(228, 100%, 98%)
			100: 'oklch(0.948 0.025 273.503)', // #E8EDFF hsl(227, 100%, 96%)
			200: 'oklch(0.799 0.073 275.979)', // #B0BAED hsl(230, 63%, 81%)
			300: 'oklch(0.66 0.12 275.608)', // #7E8BDB hsl(232, 56%, 68%)
			400: 'oklch(0.531 0.164 274.903)', // #535EC9 hsl(234, 52%, 56%)
			500: 'oklch(0.421 0.199 271.236)', // #2D36B7 hsl(236, 61%, 45%)
			default: 'oklch(0.341 0.216 266.286)', // #0D12A5 hsl(238, 85%, 35%)
			700: 'oklch(0.302 0.198 265.961)', // #08088F hsl(240, 89%, 30%)
			800: 'oklch(0.269 0.175 267.031)', // #090579 hsl(242, 92%, 25%)
			900: 'oklch(0.233 0.152 268.05)', // #080263 hsl(244, 96%, 20%)
			950: 'oklch(0.196 0.128 270.599)' // #08004D hsl(246, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.979 0.011 356.992)', // #FFF5F8 hsl(342, 100%, 98%)
			100: 'oklch(0.952 0.027 354.511)', // #FFE8F0 hsl(339, 100%, 96%)
			200: 'oklch(0.863 0.076 354.34)', // #FBBED5 hsl(337, 88%, 87%)
			300: 'oklch(0.783 0.127 353.824)', // #F795BE hsl(335, 86%, 78%)
			400: 'oklch(0.713 0.175 354.443)', // #F36DA9 hsl(333, 85%, 69%)
			500: 'oklch(0.658 0.216 355.121)', // #EF4698 hsl(331, 84%, 61%)
			default: 'oklch(0.621 0.239 357.218)', // #EB2188 hsl(329, 84%, 53%)
			700: 'oklch(0.54 0.212 354.913)', // #C31575 hsl(327, 81%, 42%)
			800: 'oklch(0.458 0.183 353.544)', // #9C0B5F hsl(325, 87%, 33%)
			900: 'oklch(0.37 0.15 351.13)', // #740449 hsl(323, 93%, 24%)
			950: 'oklch(0.278 0.117 348.207)' // #4D0032 hsl(321, 100%, 15%)
		},
		primaryBlack: 'oklch(0.106 0.061 269.597)', // #010119 hsl(238, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(238, 5%, 95%)
		darkBlack: 'oklch(0.144 0.055 350.158)', // #19010D hsl(329, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(329, 5%, 95%)
		functional: {
			success: 'oklch(0.629 0.199 141.373)', // #2ba417 hsl(112, 75%, 37%)
			warning: 'oklch(0.674 0.166 52.005)', // #e37318 hsl(27, 81%, 49%)
			error: 'oklch(0.599 0.177 27.079)', // #d54941 hsl(3, 64%, 55%)
			info: 'oklch(0.492 0.217 261.351)' // #0052d9 hsl(217, 100%, 43%)
		},
		extend: [
			{
				color: 'oklch(0.364 0.191 266.82)', // #1428a0 hsl(231, 78%, 35%)
				alias: 'Samsung'
			},
			{
				color: 'oklch(0.66 0.225 36.296)', // #fd4900 hsl(17, 100%, 50%)
				alias: 'Xiaomi'
			},
			{
				color: 'oklch(0.461 0.116 153.579)', // #046a38 hsl(151, 93%, 22%)
				alias: 'OPPO'
			}
		]
	}
};

export default AzurePink;



================================================
FILE: packages/stdf/src/data/themes/camelliaRed.ts
================================================
import type { ThemeProps } from '$lib/theme/types.js';

const CamelliaRed: ThemeProps = {
	name: 'CamelliaRed',
	color: {
		primary: {
			50: 'oklch(0.98 0.01 25.073)', // #FFF6F5 hsl(6, 100%, 98%)
			100: 'oklch(0.953 0.023 24.126)', // #FFEAE8 hsl(5, 100%, 96%)
			200: 'oklch(0.876 0.061 22.144)', // #FCC7C4 hsl(3, 90%, 88%)
			300: 'oklch(0.799 0.101 20.296)', // #F8A3A2 hsl(1, 86%, 80%)
			400: 'oklch(0.732 0.143 20.141)', // #F58082 hsl(359, 85%, 73%)
			500: 'oklch(0.675 0.18 20.489)', // #F15F66 hsl(357, 84%, 66%)
			default: 'oklch(0.632 0.21 21.584)', // #EE3F4D hsl(355, 84%, 59%)
			700: 'oklch(0.54 0.193 20.999)', // #C6273A hsl(353, 67%, 47%)
			800: 'oklch(0.449 0.168 20.933)', // #9D1529 hsl(351, 76%, 35%)
			900: 'oklch(0.36 0.138 20.161)', // #75081C hsl(349, 87%, 25%)
			950: 'oklch(0.266 0.107 17.45)' // #4D0011 hsl(347, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.99 0.008 319.447)', // #FEFAFF hsl(288, 100%, 99%)
			100: 'oklch(0.953 0.037 320.346)', // #FBE8FF hsl(290, 100%, 96%)
			200: 'oklch(0.915 0.065 318.761)', // #F6D6FF hsl(287, 100%, 92%)
			300: 'oklch(0.877 0.092 317.423)', // #F0C4FF hsl(285, 100%, 88%)
			400: 'oklch(0.841 0.118 315.933)', // #E9B3FF hsl(283, 100%, 85%)
			500: 'oklch(0.803 0.145 314.514)', // #E1A1FF hsl(281, 100%, 82%)
			default: 'oklch(0.765 0.171 312.957)', // #D88FFF hsl(279, 100%, 78%)
			700: 'oklch(0.602 0.188 310.729)', // #A458D2 hsl(277, 58%, 58%)
			800: 'oklch(0.461 0.184 307.198)', // #742EA6 hsl(275, 57%, 42%)
			900: 'oklch(0.339 0.159 303.074)', // #4A1179 hsl(273, 75%, 27%)
			950: 'oklch(0.231 0.124 299.616)' // #28004D hsl(271, 100%, 15%)
		},
		primaryBlack: 'oklch(0.139 0.05 18.003)', // #190103 hsl(355, 95%, 5%)
		primaryWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(355, 5%, 95%)
		darkBlack: 'oklch(0.134 0.06 312.473)', // #100119 hsl(279, 95%, 5%)
		darkWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(279, 5%, 95%)
		functional: {
			success: 'oklch(0.726 0.218 138.487)', // #52c41a hsl(100, 77%, 44%)
			warning: 'oklch(0.802 0.165 76.001)', // #faad14 hsl(40, 96%, 53%)
			error: 'oklch(0.673 0.214 24.465)', // #ff4d4f hsl(359, 100%, 65%)
			info: 'oklch(0.599 0.219 259.04)' // #1677ff hsl(215, 100%, 54%)
		},
		extend: [
			{
				color: 'oklch(0.472 0.108 263.58)', // #3b5998 hsl(221, 44%, 41%)
				alias: 'Facebook'
			},
			{
				color: 'oklch(0.602 0.236 28.928)', // #ed1c16 hsl(2, 86%, 51%)
				alias: 'CocaCola'
			},
			{
				color: 'oklch(0.51 0.145 250.251)', // #0068b5 hsl(206, 100%, 36%)
				alias: 'Intel'
			}
		]
	}
};

export default CamelliaRed;



================================================
FILE: packages/stdf/src/data/themes/chameleon.ts
================================================
import type { ThemeProps } from '$lib/theme/types.js';

const Chameleon: ThemeProps = {
	name: 'Chameleon',
	color: {
		primary: {
			50: 'oklch(0.991 0.014 155.599)', // #F5FFF8 hsl(138, 100%, 98%)
			100: 'oklch(0.979 0.032 155.407)', // #E8FFEF hsl(138, 100%, 96%)
			200: 'oklch(0.89 0.085 155.743)', // #ADECC3 hsl(141, 62%, 80%)
			300: 'oklch(0.812 0.128 154.98)', // #78DA9D hsl(143, 57%, 66%)
			400: 'oklch(0.742 0.153 154.251)', // #4AC77E hsl(145, 53%, 54%)
			500: 'oklch(0.682 0.167 152.73)', // #23B564 hsl(147, 68%, 42%)
			default: 'oklch(0.623 0.168 150.91)', // #02A24E hsl(149, 98%, 32%)
			700: 'oklch(0.564 0.146 152.693)', // #018D49 hsl(151, 99%, 28%)
			800: 'oklch(0.5 0.124 154.785)', // #017742 hsl(153, 98%, 24%)
			900: 'oklch(0.437 0.104 156.756)', // #006239 hsl(155, 100%, 19%)
			950: 'oklch(0.371 0.085 159.162)' // #004D2F hsl(157, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.98 0.014 336.137)', // #FFF5FC hsl(318, 100%, 98%)
			100: 'oklch(0.955 0.034 333.19)', // #FFE8FA hsl(313, 100%, 96%)
			200: 'oklch(0.896 0.07 332.956)', // #FACCF1 hsl(312, 82%, 89%)
			300: 'oklch(0.842 0.108 332.745)', // #F6B1EA hsl(310, 79%, 83%)
			400: 'oklch(0.793 0.145 331.761)', // #F197E5 hsl(308, 76%, 77%)
			500: 'oklch(0.75 0.181 330.986)', // #ED7EE2 hsl(306, 76%, 71%)
			default: 'oklch(0.711 0.213 330.284)', // #E866DF hsl(304, 74%, 66%)
			700: 'oklch(0.6 0.215 329.149)', // #C140BD hsl(302, 51%, 50%)
			800: 'oklch(0.496 0.202 328.098)', // #9A229A hsl(300, 64%, 37%)
			900: 'oklch(0.391 0.17 326.834)', // #700D73 hsl(298, 80%, 25%)
			950: 'oklch(0.284 0.133 324.454)' // #47004D hsl(295, 100%, 15%)
		},
		primaryBlack: 'oklch(0.189 0.042 157.928)', // #01190C hsl(149, 95%, 5%)
		primaryWhite: 'oklch(0.963 0.002 145.562)', // #F2F3F2 hsl(149, 5%, 95%)
		darkBlack: 'oklch(0.151 0.063 331.348)', // #190117 hsl(304, 95%, 5%)
		darkWhite: 'oklch(0.962 0.002 325.59)', // #F3F2F3 hsl(304, 5%, 95%)
		functional: {
			success: 'oklch(0.731 0.191 137.226)', // #67c23a hsl(100, 54%, 49%)
			warning: 'oklch(0.761 0.139 73.316)', // #e6a23c hsl(36, 77%, 57%)
			error: 'oklch(0.699 0.169 22.456)', // #f56c6c hsl(0, 87%, 69%)
			info: 'oklch(0.663 0.01 264.502)' // #909399 hsl(220, 4%, 58%)
		},
		extend: [
			{
				color: 'oklch(0.746 0.16 232.661)', // #00bcff hsl(194, 100%, 44%)
				alias: 'Tailwind'
			},
			{
				color: 'oklch(0.515 0.206 28.695)', // #c20c0c hsl(0, 88%, 40%)
				alias: 'NetEaseCloudMusic'
			},
			{
				color: 'oklch(0.566 0.238 268.917)', // #415fff hsl(231, 100%, 63%)
				alias: 'vivo'
			}
		]
	}
};

export default Chameleon;



================================================
FILE: packages/stdf/src/data/themes/citrus.ts
================================================
import type { ThemeProps } from '$lib/theme/types.js';

const Citrus: ThemeProps = {
	name: 'Citrus',
	color: {
		primary: {
			50: 'oklch(0.985 0.008 236.556)', // #F5FBFF hsl(204, 100%, 98%)
			100: 'oklch(0.963 0.019 240.727)', // #E8F5FF hsl(206, 100%, 96%)
			200: 'oklch(0.818 0.048 241.473)', // #A9C8E0 hsl(206, 47%, 77%)
			300: 'oklch(0.677 0.07 246.931)', // #749CC1 hsl(209, 38%, 61%)
			400: 'oklch(0.548 0.088 251.698)', // #4974A3 hsl(211, 38%, 46%)
			500: 'oklch(0.431 0.097 254.641)', // #275184 hsl(213, 54%, 34%)
			default: 'oklch(0.324 0.099 258.036)', // #0E3265 hsl(215, 76%, 23%)
			700: 'oklch(0.298 0.102 260.178)', // #0A2A5F hsl(217, 81%, 21%)
			800: 'oklch(0.274 0.103 261.304)', // #062359 hsl(219, 87%, 19%)
			900: 'oklch(0.251 0.105 262.192)', // #031C53 hsl(221, 93%, 17%)
			950: 'oklch(0.229 0.106 261.947)' // #00164D hsl(223, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.997 0.013 106.635)', // #FFFFF5 hsl(60, 100%, 98%)
			100: 'oklch(0.994 0.03 106.933)', // #FFFFE8 hsl(60, 100%, 96%)
			200: 'oklch(0.967 0.08 105.52)', // #FBF8B9 hsl(57, 89%, 86%)
			300: 'oklch(0.937 0.122 105)', // #F6EF8B hsl(56, 86%, 76%)
			400: 'oklch(0.903 0.152 102.892)', // #F2E35E hsl(54, 85%, 66%)
			500: 'oklch(0.867 0.168 100.267)', // #EDD533 hsl(52, 84%, 57%)
			default: 'oklch(0.826 0.168 94.589)', // #E9C30A hsl(50, 92%, 48%)
			700: 'oklch(0.707 0.144 91.085)', // #C29C06 hsl(48, 94%, 39%)
			800: 'oklch(0.588 0.12 87.218)', // #9B7703 hsl(46, 96%, 31%)
			900: 'oklch(0.47 0.096 83.886)', // #745501 hsl(44, 98%, 23%)
			950: 'oklch(0.35 0.072 82.069)' // #4D3600 hsl(42, 100%, 15%)
		},
		primaryBlack: 'oklch(0.147 0.037 249.929)', // #010B19 hsl(215, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(215, 5%, 95%)
		darkBlack: 'oklch(0.195 0.038 99.68)', // #191501 hsl(50, 95%, 5%)
		darkWhite: 'oklch(0.964 0.001 106.424)', // #F3F3F2 hsl(50, 5%, 95%)
		functional: {
			success: 'oklch(0.637 0.184 146.403)', // #1ba73e hsl(135, 72%, 38%)
			warning: 'oklch(0.495 0.128 47.783)', // #9a460e hsl(24, 83%, 33%)
			error: 'oklch(0.504 0.203 28.76)', // #bd0a0a hsl(0, 90%, 39%)
			info: 'oklch(0.466 0.24 284.096)' // #5628d7 hsl(256, 69%, 50%)
		},
		extend: [
			{
				color: 'oklch(0.703 0.149 235.113)', // oklch(0.703 0.149 235.059) hsl(197, 98%, 47%)
				alias: 'Twitter'
			},
			{
				color: 'oklch(0.702 0.194 38.137)', // oklch(0.702 0.194 38.137) hsl(15, 100%, 61%)
				alias: 'Svelte'
			},
			{
				color: 'oklch(0.716 0.171 53.446)', // #f38020 hsl(27, 90%, 54%)
				alias: 'Cloudflare'
			}
		]
	}
};

export default Citrus;



================================================
FILE: packages/stdf/src/data/themes/greenJade.ts
================================================
import type { ThemeProps } from '$lib/theme/types.js';

const GreenJade: ThemeProps = {
	name: 'GreenJade',
	color: {
		primary: {
			50: 'oklch(0.992 0.011 176.326)', // #F5FFFC hsl(162, 100%, 98%)
			100: 'oklch(0.982 0.025 181.302)', // #E8FFFA hsl(167, 100%, 96%)
			200: 'oklch(0.871 0.05 182.107)', // #B1E0D7 hsl(169, 43%, 79%)
			300: 'oklch(0.765 0.067 183.674)', // #81C1B7 hsl(171, 34%, 63%)
			400: 'oklch(0.662 0.075 185.315)', // #59A299 hsl(173, 29%, 49%)
			500: 'oklch(0.561 0.075 188.146)', // #38837D hsl(175, 40%, 37%)
			default: 'oklch(0.46 0.067 190.938)', // #1F6461 hsl(177, 53%, 26%)
			700: 'oklch(0.44 0.068 193.584)', // #165E5D hsl(179, 62%, 23%)
			800: 'oklch(0.416 0.066 196.348)', // #0E5758 hsl(181, 73%, 20%)
			900: 'oklch(0.389 0.064 199.408)', // #064F52 hsl(182, 86%, 17%)
			950: 'oklch(0.36 0.062 206.153)' // #00464D hsl(186, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.993 0.011 95.159)', // #FFFDF5 hsl(48, 100%, 98%)
			100: 'oklch(0.984 0.024 94.062)', // #FFFAE8 hsl(47, 100%, 96%)
			200: 'oklch(0.963 0.055 93.624)', // #FFF3CA hsl(46, 100%, 90%)
			300: 'oklch(0.938 0.081 90.541)', // #FFE9AC hsl(44, 100%, 84%)
			400: 'oklch(0.909 0.106 87.283)', // #FFDD8D hsl(42, 100%, 78%)
			500: 'oklch(0.877 0.126 83.083)', // #FFCF6F hsl(40, 100%, 72%)
			default: 'oklch(0.844 0.144 77.934)', // #FFBF51 hsl(38, 100%, 66%)
			700: 'oklch(0.707 0.132 72.908)', // #D29232 hsl(36, 64%, 51%)
			800: 'oklch(0.574 0.117 66.999)', // #A6691A hsl(34, 73%, 38%)
			900: 'oklch(0.444 0.097 61.688)', // #79450A hsl(32, 85%, 26%)
			950: 'oklch(0.315 0.075 58.16)' // #4D2600 hsl(30, 100%, 15%)
		},
		primaryBlack: 'oklch(0.193 0.032 191.218)', // #011918 hsl(177, 95%, 5%)
		primaryWhite: 'oklch(0.963 0.001 197.138)', // #F2F3F3 hsl(177, 5%, 95%)
		darkBlack: 'oklch(0.18 0.034 82.944)', // #191001 hsl(38, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(38, 5%, 95%)
		functional: {
			success: 'oklch(0.618 0.208 142.486)', // #09a207 hsl(119, 92%, 33%)
			warning: 'oklch(0.677 0.149 65.479)', // #d4810c hsl(35, 89%, 44%)
			error: 'oklch(0.554 0.224 28.911)', // #d70909 hsl(0, 92%, 44%)
			info: 'oklch(0.419 0.238 264.463)' // #062ecb hsl(228, 94%, 41%)
		},
		extend: [
			{
				color: 'oklch(0.492 0.217 261.351)', // oklch(0.492 0.217 261.351) hsl(217, 100%, 43%)
				alias: 'Tencent'
			},
			{
				color: 'oklch(0.606 0.23 11.741)', // #ea1d5d hsl(341, 83%, 52%)
				alias: 'Aparat'
			},
			{
				color: 'oklch(0.588 0.134 239.667)', // #0085c3 hsl(199, 100%, 38%)
				alias: 'Dell'
			}
		]
	}
};

export default GreenJade;



================================================
FILE: packages/stdf/src/data/themes/index.ts
================================================
import { STDFTheme } from '$lib/theme/index.js';
import Chameleon from './chameleon.js';
import AzurePink from './azurePink.js';
import SmartLive from './smartLive.js';
import CamelliaRed from './camelliaRed.js';
import Nintendo from './nintendo.js';
import Skybloom from './skybloom.js';
import Aqua from './aqua.js';
import KleinH from './kleinH.js';
import Azuper from './azuper.js';
import Citrus from './citrus.js';
import Lavender from './lavender.js';
import TealMedley from './tealMedley.js';
import GreenJade from './greenJade.js';

export default [
	{ name_CN: 'STDF', name: STDFTheme.name, theme: STDFTheme },
	{ name_CN: '任天堂', name: Nintendo.name, theme: Nintendo },
	{ name_CN: '蔚蓝粉', name: AzurePink.name, theme: AzurePink },
	{ name_CN: '变色龙', name: Chameleon.name, theme: Chameleon },
	{ name_CN: '慧活力', name: SmartLive.name, theme: SmartLive },
	{ name_CN: '蓝采绿', name: Aqua.name, theme: Aqua },
	{ name_CN: '山茶红', name: CamelliaRed.name, theme: CamelliaRed },
	{ name_CN: '蓝粉梦', name: Skybloom.name, theme: Skybloom },
	{ name_CN: '克莱仕', name: KleinH.name, theme: KleinH },
	{ name_CN: '石青柿', name: Azuper.name, theme: Azuper },
	{ name_CN: '青佛手', name: Citrus.name, theme: Citrus },
	{ name_CN: '以初紫', name: Lavender.name, theme: Lavender },
	{ name_CN: '青什锦', name: TealMedley.name, theme: TealMedley },
	{ name_CN: '绿玉子', name: GreenJade.name, theme: GreenJade }
];



================================================
FILE: packages/stdf/src/data/themes/kleinH.ts
================================================
import type { ThemeProps } from '$lib/theme/types.js';

const KleinH: ThemeProps = {
	name: 'KleinH',
	color: {
		primary: {
			50: 'oklch(0.983 0.009 247.912)', // #F5FAFF hsl(210, 100%, 98%)
			100: 'oklch(0.957 0.021 254.913)', // #E8F2FF hsl(214, 100%, 96%)
			200: 'oklch(0.817 0.061 257.788)', // #ABC5EB hsl(216, 62%, 80%)
			300: 'oklch(0.681 0.099 261.163)', // #7699D6 hsl(218, 54%, 65%)
			400: 'oklch(0.559 0.134 262.606)', // #4871C2 hsl(220, 50%, 52%)
			500: 'oklch(0.446 0.164 263.584)', // #214BAD hsl(222, 68%, 40%)
			default: 'oklch(0.355 0.183 263.561)', // #022A99 hsl(224, 97%, 30%)
			700: 'oklch(0.316 0.17 263.812)', // #012086 hsl(226, 99%, 27%)
			800: 'oklch(0.28 0.155 264.078)', // #011873 hsl(228, 98%, 23%)
			900: 'oklch(0.242 0.139 263.958)', // #001060 hsl(230, 100%, 19%)
			950: 'oklch(0.207 0.12 264.016)' // #000A4D hsl(232, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.991 0.01 87.47)', // #FFFCF5 hsl(42, 100%, 98%)
			100: 'oklch(0.978 0.022 83.264)', // #FFF7E8 hsl(39, 100%, 96%)
			200: 'oklch(0.935 0.058 80.464)', // #FEE6BE hsl(38, 97%, 87%)
			300: 'oklch(0.886 0.094 74.988)', // #FED193 hsl(35, 98%, 79%)
			400: 'oklch(0.837 0.125 70.641)', // #FDBB69 hsl(33, 97%, 70%)
			500: 'oklch(0.786 0.153 63.13)', // #FDA140 hsl(31, 98%, 62%)
			default: 'oklch(0.734 0.178 54.177)', // #FC8416 hsl(29, 98%, 54%)
			700: 'oklch(0.625 0.159 50.796)', // #D0650E hsl(27, 87%, 44%)
			800: 'oklch(0.515 0.137 47.874)', // #A44907 hsl(25, 92%, 34%)
			900: 'oklch(0.405 0.113 45.466)', // #783003 hsl(23, 95%, 24%)
			950: 'oklch(0.295 0.084 45.171)' // #4D1B00 hsl(21, 100%, 15%)
		},
		primaryBlack: 'oklch(0.133 0.043 259.636)', // #010719 hsl(224, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(224, 5%, 95%)
		darkBlack: 'oklch(0.17 0.034 67.389)', // #190C01 hsl(29, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(29, 5%, 95%)
		functional: {
			success: 'oklch(0.439 0.132 145.643)', // #07641d hsl(134, 87%, 21%)
			warning: 'oklch(0.566 0.171 39.514)', // #c54711 hsl(18, 84%, 42%)
			error: 'oklch(0.497 0.177 16.155)', // #b0213e hsl(348, 68%, 41%)
			info: 'oklch(0.573 0.096 219.542)' // #1d859f hsl(192, 69%, 37%)
		},
		extend: [
			{
				color: 'oklch(0.686 0.139 231.254)', // #00a8e0 hsl(195, 100%, 44%)
				alias: 'AT&T'
			},
			{
				color: 'oklch(0.651 0.212 142.608)', // oklch(0.651 0.212 142.608) hsl(120, 75%, 39%)
				alias: 'WeChat'
			},
			{
				color: 'oklch(0.652 0.199 0.712)', // #ea4c89 hsl(337, 79%, 61%)
				alias: 'Dribbble'
			}
		]
	}
};

export default KleinH;



================================================
FILE: packages/stdf/src/data/themes/lavender.ts
================================================
import type { ThemeProps } from '$lib/theme/types.js';

const Lavender: ThemeProps = {
	name: 'Lavender',
	color: {
		primary: {
			50: 'oklch(0.978 0.015 315.966)', // #FCF5FF hsl(282, 100%, 98%)
			100: 'oklch(0.95 0.035 315.73)', // #F8E8FF hsl(282, 100%, 96%)
			200: 'oklch(0.842 0.065 314.453)', // #DBBFE9 hsl(280, 49%, 83%)
			300: 'oklch(0.739 0.091 312.314)', // #BE9AD4 hsl(277, 40%, 72%)
			400: 'oklch(0.641 0.109 310.145)', // #A179BE hsl(275, 35%, 61%)
			500: 'oklch(0.551 0.124 307.99)', // #865CA9 hsl(273, 31%, 51%)
			default: 'oklch(0.467 0.13 305.627)', // #6C4393 hsl(271, 37%, 42%)
			700: 'oklch(0.392 0.138 302.664)', // #552C81 hsl(269, 49%, 34%)
			800: 'oklch(0.326 0.14 298.682)', // #401970 hsl(267, 64%, 27%)
			900: 'oklch(0.269 0.132 293.856)', // #2D0B5E hsl(265, 79%, 21%)
			950: 'oklch(0.216 0.123 289.042)' // #1D004D hsl(263, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.971 0.017 349.48)', // #FFF1F7 hsl(334, 100%, 97%)
			100: 'oklch(0.953 0.029 347.076)', // #FFE8F3 hsl(331, 100%, 96%)
			200: 'oklch(0.926 0.042 344.642)', // #FCDCED hsl(328, 84%, 93%)
			300: 'oklch(0.901 0.053 344.002)', // #F9D1E7 hsl(327, 77%, 90%)
			400: 'oklch(0.874 0.065 342.674)', // #F5C5E1 hsl(325, 71%, 87%)
			500: 'oklch(0.85 0.078 340.995)', // #F2BADD hsl(323, 68%, 84%)
			default: 'oklch(0.826 0.092 339.861)', // #EFAFD9 hsl(321, 67%, 81%)
			700: 'oklch(0.654 0.135 340.177)', // #C66DAA hsl(319, 44%, 60%)
			800: 'oklch(0.512 0.156 340.793)', // #9E3A81 hsl(317, 46%, 42%)
			900: 'oklch(0.391 0.15 340.551)', // #75155D hsl(315, 70%, 27%)
			950: 'oklch(0.284 0.123 340.171)' // #4D003C hsl(313, 100%, 15%)
		},
		primaryBlack: 'oklch(0.129 0.059 306.37)', // #0D0119 hsl(271, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(271, 5%, 95%)
		darkBlack: 'oklch(0.146 0.057 343.966)', // #190110 hsl(321, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(321, 5%, 95%)
		functional: {
			success: 'oklch(0.784 0.194 147.722)', // #4ad96b hsl(134, 65%, 57%)
			warning: 'oklch(0.693 0.147 42.888)', // #e67a4c hsl(18, 76%, 60%)
			error: 'oklch(0.639 0.192 24.341)', // #e94e4e hsl(0, 78%, 61%)
			info: 'oklch(0.613 0.168 270.082)' // #5e7ae8 hsl(228, 75%, 64%)
		},
		extend: [
			{
				color: 'oklch(0.492 0.217 261.351)', // oklch(0.492 0.217 261.351) hsl(217, 100%, 43%)
				alias: 'Tencent'
			},
			{
				color: 'oklch(0.651 0.212 142.608)', // oklch(0.651 0.212 142.608) hsl(120, 75%, 39%)
				alias: 'WeChat'
			},
			{
				color: 'oklch(0.343 0.077 256.446)', // #1c3960 hsl(214, 55%, 24%)
				alias: 'Ford'
			}
		]
	}
};

export default Lavender;



================================================
FILE: packages/stdf/src/data/themes/nintendo.ts
================================================
import type { ThemeProps } from '$lib/theme/types.js';

const Nintendo: ThemeProps = {
	name: 'Nintendo',
	color: {
		primary: {
			50: 'oklch(0.98 0.01 25.073)', // #FFF6F5 hsl(6, 100%, 98%)
			100: 'oklch(0.953 0.023 24.126)', // #FFEAE8 hsl(5, 100%, 96%)
			200: 'oklch(0.845 0.076 21.796)', // #FAB9B6 hsl(3, 87%, 85%)
			300: 'oklch(0.745 0.133 21.872)', // #F58886 hsl(1, 85%, 74%)
			400: 'oklch(0.662 0.188 22.749)', // #F0575A hsl(359, 84%, 64%)
			500: 'oklch(0.609 0.224 25.256)', // #EB2B34 hsl(357, 83%, 55%)
			default: 'oklch(0.581 0.238 27.862)', // #E60012 hsl(355, 100%, 45%)
			700: 'oklch(0.508 0.207 26.549)', // #C00016 hsl(353, 100%, 38%)
			800: 'oklch(0.43 0.174 24.608)', // #990017 hsl(351, 100%, 30%)
			900: 'oklch(0.351 0.141 21.971)', // #730015 hsl(349, 100%, 23%)
			950: 'oklch(0.266 0.107 17.45)' // #4D0011 hsl(347, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.992 0.011 189.833)', // #F5FFFE hsl(174, 100%, 98%)
			100: 'oklch(0.983 0.024 193.6)', // #E8FFFE hsl(177, 100%, 96%)
			200: 'oklch(0.938 0.067 196.074)', // #B6F9F9 hsl(180, 85%, 85%)
			300: 'oklch(0.893 0.099 198.69)', // #85F0F4 hsl(182, 84%, 74%)
			400: 'oklch(0.847 0.12 201.806)', // #57E4EE hsl(184, 82%, 64%)
			500: 'oklch(0.803 0.131 206.757)', // #2AD6E9 hsl(186, 81%, 54%)
			default: 'oklch(0.752 0.133 215.123)', // #00C3E3 hsl(189, 100%, 45%)
			700: 'oklch(0.646 0.116 218.359)', // #009EBD hsl(190, 100%, 37%)
			800: 'oklch(0.535 0.1 223.819)', // #007998 hsl(192, 100%, 30%)
			900: 'oklch(0.426 0.083 227.589)', // #005772 hsl(194, 100%, 22%)
			950: 'oklch(0.319 0.064 230.58)' // #00384D hsl(196, 100%, 15%)
		},
		primaryBlack: 'oklch(0.139 0.05 18.003)', // #190103 hsl(355, 95%, 5%)
		primaryWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(355, 5%, 95%)
		darkBlack: 'oklch(0.184 0.03 206.812)', // #011619 hsl(188, 95%, 5%)
		darkWhite: 'oklch(0.963 0.001 197.138)', // #F2F3F3 hsl(188, 5%, 95%)
		functional: {
			success: 'oklch(0.669 0.214 144.385)', // #00b42a hsl(134, 100%, 35%)
			warning: 'oklch(0.865 0.176 95.103)', // #f7d00c hsl(50, 94%, 51%)
			error: 'oklch(0.642 0.218 25.88)', // #f53f3f hsl(0, 90%, 60%)
			info: 'oklch(0.549 0.249 263.048)' // #165dff hsl(222, 100%, 54%)
		},
		extend: [
			{
				color: 'oklch(0.492 0.217 261.351)', // #0052d9 hsl(217, 100%, 43%)
				alias: 'Tencent'
			},
			{
				color: 'oklch(0.651 0.212 142.608)', // #1aad19 hsl(120, 75%, 39%)
				alias: 'WeChat'
			},
			{
				color: 'oklch(0.692 0.181 46.213)', // #f37021 hsl(23, 90%, 54%)
				alias: 'Hermès'
			}
		]
	}
};

export default Nintendo;



================================================
FILE: packages/stdf/src/data/themes/skybloom.ts
================================================
import type { ThemeProps } from '$lib/theme/types.js';

const Skybloom: ThemeProps = {
	name: 'Skybloom',
	color: {
		primary: {
			50: 'oklch(0.987 0.008 225.079)', // #F5FCFF hsl(198, 100%, 98%)
			100: 'oklch(0.969 0.019 225.712)', // #E8F8FF hsl(198, 100%, 96%)
			200: 'oklch(0.863 0.05 229.685)', // #B1D9ED hsl(200, 63%, 81%)
			300: 'oklch(0.759 0.075 234.966)', // #81B9DA hsl(202, 55%, 68%)
			400: 'oklch(0.66 0.098 240.067)', // #569AC8 hsl(204, 51%, 56%)
			500: 'oklch(0.566 0.115 244.99)', // #317CB5 hsl(206, 57%, 45%)
			default: 'oklch(0.479 0.13 251.007)', // #125FA3 hsl(208, 80%, 36%)
			700: 'oklch(0.42 0.122 253.316)', // #0C4D8D hsl(210, 84%, 30%)
			800: 'oklch(0.359 0.116 256.313)', // #073B78 hsl(212, 89%, 25%)
			900: 'oklch(0.303 0.105 257.617)', // #032C62 hsl(214, 94%, 20%)
			950: 'oklch(0.251 0.093 258.021)' // #001F4D hsl(216, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.975 0.012 23.703)', // #FFF4F3 hsl(5, 100%, 98%)
			100: 'oklch(0.949 0.025 17.604)', // #FFE8E8 hsl(0, 100%, 96%)
			200: 'oklch(0.92 0.038 17.861)', // #FDDBDB hsl(0, 90%, 93%)
			300: 'oklch(0.89 0.05 15.051)', // #FACED0 hsl(357, 82%, 89%)
			400: 'oklch(0.861 0.063 12.376)', // #F8C1C6 hsl(355, 80%, 87%)
			500: 'oklch(0.832 0.076 10.667)', // #F5B4BC hsl(353, 77%, 83%)
			default: 'oklch(0.807 0.089 9.599)', // #F3A8B3 hsl(351, 76%, 81%)
			700: 'oklch(0.635 0.124 9.491)', // #C9687A hsl(349, 47%, 60%)
			800: 'oklch(0.493 0.139 10.638)', // #A0374E hsl(347, 49%, 42%)
			900: 'oklch(0.374 0.131 12.448)', // #76142D hsl(345, 71%, 27%)
			950: 'oklch(0.268 0.107 13.338)' // #4D0016 hsl(343, 100%, 15%)
		},
		primaryBlack: 'oklch(0.156 0.033 240.386)', // #010E19 hsl(208, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(208, 5%, 95%)
		darkBlack: 'oklch(0.14 0.05 14.109)', // #190104 hsl(351, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(351, 5%, 95%)
		functional: {
			success: 'oklch(0.7 0.181 152.201)', // #0fbd63 hsl(149, 85%, 40%)
			warning: 'oklch(0.534 0.132 51.034)', // #a75211 hsl(26, 82%, 36%)
			error: 'oklch(0.58 0.211 10.496)', // #d9265c hsl(342, 70%, 50%)
			info: 'oklch(0.458 0.218 283.692)' // #5231c9 hsl(253, 61%, 49%)
		},
		extend: [
			{
				color: 'oklch(0.703 0.149 235.113)', // oklch(0.703 0.149 235.059) hsl(197, 98%, 47%)
				alias: 'Twitter'
			},
			{
				color: 'oklch(0.702 0.194 38.137)', // oklch(0.702 0.194 38.137) hsl(15, 100%, 61%)
				alias: 'Svelte'
			},
			{
				color: 'oklch(0.518 0.199 259.881)', // #0e5fd8 hsl(216, 88%, 45%)
				alias: 'Philips'
			}
		]
	}
};

export default Skybloom;



================================================
FILE: packages/stdf/src/data/themes/smartLive.ts
================================================
import type { ThemeProps } from '$lib/theme/types.js';

const SmartLive: ThemeProps = {
	name: 'SmartLive',
	color: {
		primary: {
			50: 'oklch(0.978 0.015 315.966)', // #FCF5FF hsl(282, 100%, 98%)
			100: 'oklch(0.95 0.035 315.73)', // #F8E8FF hsl(282, 100%, 96%)
			200: 'oklch(0.794 0.075 313.533)', // #CDAEDE hsl(279, 42%, 78%)
			300: 'oklch(0.652 0.103 312.25)', // #A57DBD hsl(278, 33%, 62%)
			400: 'oklch(0.522 0.119 309.358)', // #7E549D hsl(275, 30%, 47%)
			500: 'oklch(0.406 0.122 307.073)', // #5B337C hsl(273, 42%, 34%)
			default: 'oklch(0.304 0.112 304.532)', // #3C1A5B hsl(271, 56%, 23%)
			700: 'oklch(0.28 0.115 301.336)', // #341357 hsl(269, 64%, 21%)
			800: 'oklch(0.258 0.119 297.251)', // #2C0C54 hsl(267, 75%, 19%)
			900: 'oklch(0.238 0.12 293.937)', // #250650 hsl(265, 86%, 17%)
			950: 'oklch(0.216 0.123 289.042)' // #1D004D hsl(263, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.98 0.01 25.073)', // #FFF6F5 hsl(6, 100%, 98%)
			100: 'oklch(0.953 0.023 24.126)', // #FFEAE8 hsl(5, 100%, 96%)
			200: 'oklch(0.902 0.051 19.634)', // #FFD2D1 hsl(1, 100%, 91%)
			300: 'oklch(0.853 0.08 18.86)', // #FFBABA hsl(0, 100%, 87%)
			400: 'oklch(0.806 0.111 17.023)', // #FFA2A6 hsl(357, 100%, 82%)
			500: 'oklch(0.765 0.14 16.578)', // #FF8B93 hsl(356, 100%, 77%)
			default: 'oklch(0.728 0.169 15.672)', // #FF7483 hsl(354, 100%, 73%)
			700: 'oklch(0.597 0.173 16.54)', // #D2485A hsl(352, 61%, 55%)
			800: 'oklch(0.482 0.163 17.177)', // #A6263B hsl(350, 63%, 40%)
			900: 'oklch(0.373 0.138 17.973)', // #790E23 hsl(348, 79%, 27%)
			950: 'oklch(0.267 0.107 16.66)' // #4D0012 hsl(346, 100%, 15%)
		},
		primaryBlack: 'oklch(0.129 0.059 306.37)', // #0D0119 hsl(271, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(271, 5%, 95%)
		darkBlack: 'oklch(0.139 0.05 18.003)', // #190103 hsl(354, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(354, 5%, 95%)
		functional: {
			success: 'oklch(0.419 0.092 155.284)', // #155b36 hsl(148, 63%, 22%)
			warning: 'oklch(0.666 0.147 65.222)', // #d07e0b hsl(35, 90%, 43%)
			error: 'oklch(0.564 0.223 28.46)', // #da1414 hsl(0, 83%, 47%)
			info: 'oklch(0.728 0.107 239.498)' // #63b0e3 hsl(204, 70%, 64%)
		},
		extend: [
			{
				color: 'oklch(0.713 0.194 130.802)', // #76b900 hsl(82, 100%, 36%)
				alias: 'NVIDIA'
			},
			{
				color: 'oklch(0.726 0.171 4.454)', // #fb7299 hsl(343, 95%, 72%)
				alias: 'bilibili'
			},
			{
				color: 'oklch(0.599 0.219 259.04)', // #1677ff hsl(215, 100%, 54%)
				alias: 'AliPay'
			}
		]
	}
};

export default SmartLive;



================================================
FILE: packages/stdf/src/data/themes/tealMedley.ts
================================================
import type { ThemeProps } from '$lib/theme/types.js';

const TealMedley: ThemeProps = {
	name: 'TealMedley',
	color: {
		primary: {
			50: 'oklch(0.991 0.01 204.917)', // #F5FEFF hsl(186, 100%, 98%)
			100: 'oklch(0.977 0.021 207.588)', // #E8FCFF hsl(188, 100%, 96%)
			200: 'oklch(0.877 0.046 213.81)', // #B5DFE9 hsl(192, 54%, 81%)
			300: 'oklch(0.78 0.063 217.138)', // #89C2D2 hsl(193, 45%, 68%)
			400: 'oklch(0.686 0.076 222.122)', // #62A5BC hsl(195, 40%, 56%)
			500: 'oklch(0.595 0.084 226.019)', // #4089A5 hsl(197, 44%, 45%)
			default: 'oklch(0.509 0.088 231.916)', // #256E8F hsl(199, 59%, 35%)
			700: 'oklch(0.448 0.086 236.944)', // #195B7E hsl(201, 67%, 30%)
			800: 'oklch(0.389 0.085 242.356)', // #0E496E hsl(203, 77%, 24%)
			900: 'oklch(0.334 0.081 245.985)', // #06395D hsl(205, 88%, 19%)
			950: 'oklch(0.28 0.078 249.311)' // #002A4D hsl(207, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.971 0.015 33.071)', // #FFF2EF hsl(11, 100%, 97%)
			100: 'oklch(0.957 0.021 31.78)', // #FFECE8 hsl(10, 100%, 96%)
			200: 'oklch(0.932 0.028 28.52)', // #FBE2DE hsl(8, 78%, 93%)
			300: 'oklch(0.905 0.036 24.203)', // #F7D7D4 hsl(5, 69%, 90%)
			400: 'oklch(0.879 0.042 23.456)', // #F2CDCA hsl(5, 61%, 87%)
			500: 'oklch(0.852 0.051 21.242)', // #EEC2C0 hsl(3, 58%, 84%)
			default: 'oklch(0.825 0.059 18.425)', // #EAB7B7 hsl(0, 55%, 82%)
			700: 'oklch(0.642 0.102 17.954)', // #C37275 hsl(358, 40%, 61%)
			800: 'oklch(0.49 0.126 19.197)', // #9B3D43 hsl(356, 44%, 42%)
			900: 'oklch(0.369 0.126 21.232)', // #741720 hsl(354, 67%, 27%)
			950: 'oklch(0.265 0.107 22.403)' // #4D000A hsl(352, 100%, 15%)
		},
		primaryBlack: 'oklch(0.167 0.03 228.62)', // #011119 hsl(199, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(199, 5%, 95%)
		darkBlack: 'oklch(0.138 0.051 27.08)', // #190101 hsl(0, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(0, 5%, 95%)
		functional: {
			success: 'oklch(0.608 0.142 148.314)', // #38994f hsl(134, 46%, 41%)
			warning: 'oklch(0.776 0.119 100.626)', // #c7b857 hsl(52, 50%, 56%)
			error: 'oklch(0.66 0.146 21.85)', // #dd6969 hsl(0, 63%, 64%)
			info: 'oklch(0.559 0.131 271.419)' // #596dc0 hsl(228, 45%, 55%)
		},
		extend: [
			{
				color: 'oklch(0.492 0.217 261.351)', // oklch(0.492 0.217 261.351) hsl(217, 100%, 43%)
				alias: 'Tencent'
			},
			{
				color: 'oklch(0.424 0.097 251.575)', // #205081 hsl(210, 60%, 32%)
				alias: 'Bitbucket'
			},
			{
				color: 'oklch(0.364 0.191 266.82)', // #1428a0 hsl(231, 78%, 35%)
				alias: 'Samsung'
			}
		]
	}
};

export default TealMedley;



================================================
FILE: packages/stdf/src/lib/index.ts
================================================
export { default as ActionSheet } from './components/actionSheet/ActionSheet.svelte';
export { default as AsyncPicker } from './components/asyncPicker/AsyncPicker.svelte';
export { default as Avatar } from './components/avatar/Avatar.svelte';
export { default as Avatars } from './components/avatar/Avatars.svelte';
export { default as Badge } from './components/badge/Badge.svelte';
export { default as BottomSheet } from './components/bottomSheet/BottomSheet.svelte';
export { default as Button } from './components/button/Button.svelte';
export { default as Calendar } from './components/calendar/Calendar.svelte';
export { default as Cell } from './components/cell/Cell.svelte';
export { default as CellGroup } from './components/cell/CellGroup.svelte';
export { default as CheckboxItem } from './components/checkbox/CheckboxItem.svelte';
export { default as Checkbox } from './components/checkbox/Checkbox.svelte';
export { default as Dialog } from './components/dialog/Dialog.svelte';
export { default as Divider } from './components/divider/Divider.svelte';
export { default as Grid } from './components/grids/Grid.svelte';
export { default as Grids } from './components/grids/Grids.svelte';
export { default as Icon } from './components/icon/Icon.svelte';
export { default as IndexBar } from './components/indexBar/IndexBar.svelte';
export { default as Input } from './components/input/Input.svelte';
export { default as Loading } from './components/loading/Loading.svelte';
export { default as Mask } from './components/mask/Mask.svelte';
export { default as Modal } from './components/modal/Modal.svelte';
export { default as NavBar } from './components/navBar/NavBar.svelte';
export { default as NoticeBar } from './components/noticeBar/NoticeBar.svelte';
export { default as NumKeyboard } from './components/numKeyboard/NumKeyboard.svelte';
export { default as Pagination } from './components/pagination/Pagination.svelte';
export { default as Picker } from './components/picker/Picker.svelte';
export { default as Placeholder } from './components/placeholder/Placeholder.svelte';
export { default as Popup } from './components/popup/Popup.svelte';
export { default as Progress } from './components/progress/Progress.svelte';
export { default as ProgressLoop } from './components/progressLoop/ProgressLoop.svelte';
export { default as RadioItem } from './components/radio/RadioItem.svelte';
export { default as Radio } from './components/radio/Radio.svelte';
export { default as Rate } from './components/rate/Rate.svelte';
export { default as Skeleton } from './components/skeleton/Skeleton.svelte';
export { default as Slider } from './components/slider/Slider.svelte';
export { default as Stepper } from './components/stepper/Stepper.svelte';
export { default as Steps } from './components/steps/Steps.svelte';
export { default as Switch } from './components/switch/Switch.svelte';
export { default as Swiper } from './components/swiper/Swiper.svelte';
export { default as Tab } from './components/tabs/Tab.svelte';
export { default as TabBar } from './components/tabBar/TabBar.svelte';
export { default as TabContent } from './components/tabs/TabContent.svelte';
export { default as Tabs } from './components/tabs/Tabs.svelte';
export { default as TimePicker } from './components/timePicker/TimePicker.svelte';
export { default as Toast } from './components/toast/Toast.svelte';




================================================
FILE: packages/stdf/src/lib/components/actionSheet/ActionSheet.svelte
================================================
<script lang="ts">
	import { getContext } from 'svelte';
	import Popup from '../popup/Popup.svelte';
	import type { ActionSheetProps, ActionProps } from '../../types/index.js';
	import { zh_CN, type LangProps } from '../../lang/index.js';

	// 当前语言
	// current language
	const currentLang = (getContext('STDF_lang') || zh_CN) as LangProps;
	const actionSheetLang: LangProps['actionSheet'] = currentLang.actionSheet;

	let {
		visible = $bindable(false),
		title = '',
		titleAlign = 'center',
		actions = [],
		popup = {},
		showCancel = false,
		cancelText = actionSheetLang.cancelText,
		actionClosable = true,
		align = 'center',
		oncancel,
		onclickAction,
		onclose
	}: ActionSheetProps = $props();

	// 静态样式类定义移到组件外部
	// static style class definition moved to component outside
	const STYLE_MAPS = {
		titleAlign: { left: 'text-left', center: 'text-center', right: 'text-right' },
		state: {
			normal: ' ',
			theme: ' text-primary dark:text-dark ',
			danger: ' text-error ',
			disabled: ' text-black/20 dark:text-white/20 '
		},
		imgRadius: { none: 'rounded-none', sm: 'rounded-sm', full: 'rounded-full', lg: 'rounded-lg' },
		align: { left: 'justify-start pl-4', center: 'justify-center', right: 'justify-end pr-4' }
	};

	// 优化高度计算函数
	// optimize height calculation function
	const getTransitionDistance = (title: string, showCancel: boolean, actions: ActionProps[]): number => {
		const BASE_HEIGHTS = { title: 40, cancel: 56, action: 56, actionWithDesc: 60, divider: 1 };
		return (
			(title ? BASE_HEIGHTS.title : 0) +
			(showCancel ? BASE_HEIGHTS.cancel : 0) +
			actions.reduce((total: number, item: ActionProps) => total + (item.desc ? BASE_HEIGHTS.actionWithDesc : BASE_HEIGHTS.action), 0) +
			(actions.length - 1) * BASE_HEIGHTS.divider
		);
	};

	// 优化事件处理函数
	// optimize event handling function
	const handleCancel = () => {
		visible = false;
		oncancel?.();
		onclose?.();
	};

	// 处理选项点击事件
	// handle option click event
	const handleActionClick = (index: number, item: ActionProps) => {
		if (item.style === 'disabled') return;
		onclickAction?.(index, item);
		if (actionClosable) {
			visible = false;
			onclose?.();
		}
	};
</script>

<Popup bind:visible size={0} transitionDistance={getTransitionDistance(title, showCancel, actions)} {onclose} {...popup}>
	{#if title}
		<div
			class="flex h-10 flex-col justify-center truncate border-b border-black/5 text-xs text-black/50 dark:border-white/5 dark:text-white/50 {STYLE_MAPS
				.titleAlign[titleAlign] || STYLE_MAPS.titleAlign['left']}"
		>
			{title}
		</div>
	{/if}
	<div>
		{#each actions as item, index}
			<button
				class="{item.style !== 'disabled'
					? 'active:scale-90 '
					: 'cursor-not-allowed '}transition-all flex w-full items-center gap-2 {STYLE_MAPS.align[align] || STYLE_MAPS.align['center']}"
				disabled={item.style === 'disabled'}
				onclick={() => handleActionClick(index, item)}
			>
				{#if item.showImg}
					<div class="h-6 w-6 overflow-hidden {(item.imgRadius && STYLE_MAPS.imgRadius[item.imgRadius]) || 'rounded-full'}">
						<img class="h-full w-full object-cover" src={item.imgSrc} alt="" />
					</div>
				{/if}
				<div>
					<div
						class="truncate text-center font-bold {(item.style && STYLE_MAPS.state[item.style]) ||
							STYLE_MAPS.state.normal} flex flex-col justify-center {item.desc ? ' h-10' : ' h-14'}"
					>
						{item.content}
					</div>
					{#if item.desc}
						<div class="truncate pb-1 text-center text-xs text-black/50 dark:text-white/40">
							{item.desc}
						</div>
					{/if}
				</div>
			</button>
			{#if index !== actions.length - 1}
				<div class="h-px w-full bg-black/5 dark:bg-white/5"></div>
			{/if}
		{/each}
	</div>
	{#if showCancel}
		<div class="h-2 bg-black/5 dark:bg-white/5"></div>
		<button
			class="flex h-12 w-full items-center transition-all active:scale-90 {STYLE_MAPS.align[align] || STYLE_MAPS.align['center']}"
			onclick={handleCancel}
		>
			<div>
				{cancelText}
			</div>
		</button>
	{/if}
</Popup>



================================================
FILE: packages/stdf/src/lib/components/asyncPicker/AsyncPicker.svelte
================================================
<script lang="ts">
	import { getContext } from 'svelte';
	import { fly } from 'svelte/transition';
	import Popup from '../popup/Popup.svelte';
	import Loading from '../loading/Loading.svelte';
	import ScrollRadio from '../scrollRadio/ScrollRadio.svelte';
	import type { AsyncPickerProps } from '../../types/index.js';
	import { zh_CN, type LangProps } from '../../lang/index.js';

	// 当前语言
	// current language
	const currentLang = (getContext('STDF_lang') || zh_CN) as LangProps;
	const asyncPickerLang: LangProps['asyncPicker'] = currentLang.asyncPicker;

	let {
		visible = $bindable(false),
		data = $bindable([]),
		lastLevel = $bindable(false),
		firstLevel = $bindable(true),
		showRow = 5,
		labelKey = $bindable('label'),
		align = 'center',
		cancelText = asyncPickerLang.defaultCancel,
		confirmText = asyncPickerLang.defaultConfirm,
		title = $bindable(asyncPickerLang.defaultTitle),
		nextText = asyncPickerLang.defaultNext,
		prevText = asyncPickerLang.defaultPrev,
		showSelected = false,
		selectedText = asyncPickerLang.defaultSelected,
		popup = {},
		loading = {},
		oncancel,
		onprev,
		onconfirm,
		onnext,
		onclose
	}: AsyncPickerProps = $props();

	// 用于存储当前选定的所有项和索引
	// Used to store all selected items and indexes
	let items: Record<string, unknown>[] = $state([]);
	let indexs: number[] = $state([]);

	// 当前选中项索引
	// Current selected item index
	let currentIndex = $state(0);

	// 点击左侧按钮
	// Click left button
	const clickLeftFunc = () => {
		if (firstLevel) {
			visible = false;
			oncancel?.();
		} else {
			items = items.slice(0, items.length - 1);
			indexs.pop();
			data = [];
			setTimeout(() => {
				onprev?.();
				currentIndex = 0;
			});
		}
	};

	// 点击右侧按钮，如果是最后一列，则触发 confirm 事件，否则触发 next 事件
	// Click the right button, if it is the last column, trigger the confirm event, otherwise trigger the next event
	const clickRightFunc = () => {
		if (lastLevel) {
			items.push(data[currentIndex]);
			indexs.push(currentIndex);
			data = [];
			visible = false;
			onclose?.();
			currentIndex = 0;
			onconfirm?.(items as [], indexs);
		} else {
			items = [...items, data[currentIndex]];
			indexs.push(currentIndex);
			indexs = indexs;
			data = [];
			setTimeout(() => {
				onnext?.(currentIndex);
				currentIndex = 0;
			});
		}
	};

	// 滚动结束
	// Scroll end
	const scrollEndFunc = (index: number) => {
		currentIndex = index;
	};
	let isLoading = $derived(data.length === 0);
</script>

<Popup
	bind:visible
	size={0}
	maskClosable
	transitionDistance={(showRow === 3 ? 64 : showRow === 5 ? 48 : 32) * showRow + 41 + (showSelected ? 32 : 0)}
	{...popup}
>
	<div class="flex items-center justify-between border-b border-black/10 bg-white dark:border-white/20 dark:bg-black">
		<button
			class="h-10 px-4 leading-10 text-black/60 dark:text-white/60"
			onclick={() => {
				if (!isLoading) clickLeftFunc();
			}}
		>
			{#if isLoading}
				<div class="p-3">
					<Loading width="4" height="4" customColor={['#666']} />
				</div>
			{:else}
				{firstLevel ? cancelText : prevText}
			{/if}
		</button>
		<div>{title}</div>
		<button
			class="text-primary dark:text-dark h-10 px-4 leading-10"
			onclick={() => {
				if (!isLoading) clickRightFunc();
			}}
		>
			{#if isLoading}
				<div class="p-3">
					<Loading width="4" height="4" theme />
				</div>
			{:else}
				{lastLevel ? confirmText : nextText}
			{/if}
		</button>
	</div>
	{#if showSelected}
		<div class="flex w-full gap-3 overflow-x-hidden bg-white px-4 dark:bg-black">
			<div class="h-8 flex-none text-center text-sm leading-8 text-black/60 dark:text-white/60">
				{selectedText}
			</div>
			{#each items as item}
				{#if !isLoading}
					<div
						in:fly|global={{ x: document.documentElement.clientWidth, duration: 500 }}
						out:fly|global={{ x: document.documentElement.clientWidth, duration: 300 }}
						class="h-8 flex-1 truncate px-1 text-center text-sm leading-8"
					>
						{item[labelKey]}
					</div>
				{/if}
			{/each}
		</div>
	{/if}
	<div class="bg-white dark:bg-black">
		<div class="truncate">
			{#if isLoading}
				<div class="flex items-center justify-center" style="height:{(showRow === 3 ? 64 : showRow === 5 ? 48 : 32) * showRow}px">
					<Loading width="28" height="8" type="1_16" theme {...loading} />
				</div>
			{:else}
				<div>
					<ScrollRadio
						data={data as Record<string, string>[]}
						{showRow}
						{labelKey}
						{align}
						autoScrollToLast={false}
						onscrollEnd={scrollEndFunc}
					/>
				</div>
			{/if}
		</div>
	</div>
</Popup>



================================================
FILE: packages/stdf/src/lib/components/avatar/Avatar.svelte
================================================
<script lang="ts">
	import Icon from '../icon/Icon.svelte';
	import type { AvatarProps } from '../../types/index.js';

	let {
		image = '',
		alt = '',
		icon = {},
		altSize = 'md',
		radius = 'sm',
		size = 'base',
		imgSize = 'l',
		line = 'none',
		injClass = '',
		onclick
	}: AvatarProps = $props();

	// 圆角风格样式
	// radius style
	const radiusObj = {
		none: 'rounded-none',
		sm: 'rounded-sm',
		xl: 'rounded-xl',
		'2xl': 'rounded-2xl',
		'3xl': 'rounded-3xl',
		full: 'rounded-full'
	};

	// 头像框大小样式
	// avatar size style
	const sizeObj = {
		xs: 'w-6 h-6',
		sm: 'w-10 h-10',
		base: 'w-12 h-12',
		md: 'w-16 h-16',
		lg: 'w-20 h-20',
		xl: 'w-28 h-28',
		'2xl': 'w-32 h-32'
	};

	// 头像图片大小样式
	// avatar image size style
	const imgSizeObj = { s: 'h-1/3 w-1/3', m: 'h-2/3 w-2/3', l: 'h-full w-full' };

	// 边框风格样式
	// border style
	const lineObj = {
		none: ' ',
		solid: ' border border-solid border-primary dark:border-dark',
		dashed: ' border border-dashed border-primary dark:border-dark',
		dotted: ' border border-dotted border-primary dark:border-dark'
	};

	// 替换文本大小样式
	// replace text size style
	const altSizeObj = {
		xs: 'text-base',
		sm: 'text-2xl',
		md: 'text-4xl',
		lg: 'text-6xl',
		xl: 'text-8xl'
	};

	// 当默认情况时根据 size 计算 Icon 大小
	// when default, calculate Icon size by size
	const iconSizeObj = { xs: 12, sm: 20, base: 24, md: 32, lg: 40, xl: 56, '2xl': 64 };
</script>

<button
	class="bg-primary-200 dark:bg-dark-200 flex justify-center overflow-hidden relative{lineObj[line] || ''} {sizeObj[size] ||
		sizeObj.md} {radiusObj[radius] || radiusObj.sm} {injClass}"
	onclick={() => onclick && onclick()}
>
	{#if image === '' && alt === ''}
		<div class="m-auto">
			<Icon
				size={iconSizeObj[size] || iconSizeObj.base}
				name="ri-user-3-line"
				theme
				{...icon}
				injClass="text-primary-950 dark:text-dark-950"
			/>
		</div>
	{:else if image === '' && alt !== ''}
		<div
			class="text-primary-950 dark:text-dark-950 text-center {altSizeObj[altSize] || altSizeObj.md}"
			style="position: absolute;top: 50%;left:50%;transform: translate(-50%, -50%);"
		>
			{alt}
		</div>
	{:else}
		<div class="m-auto text-center">
			<img
				src={image}
				class="inline-block object-cover {imgSizeObj[imgSize] || imgSizeObj.l}"
				alt=""
				style="position: absolute;top: 50%;left:50%;transform: translate(-50%, -50%);"
			/>
		</div>
	{/if}
</button>



================================================
FILE: packages/stdf/src/lib/components/avatar/Avatars.svelte
================================================
<script lang="ts">
	import Avatar from './Avatar.svelte';
	import Icon from '../icon/Icon.svelte';
	import type { AvatarsProps } from '../../types/index.js';

	let {
		data = [],
		radius = 'full',
		size = 'base',
		compact = 5,
		lineWidth = '3',
		reverse = false,
		max = 10,
		top = 'totle',
		injClass = '',
		onclick
	}: AvatarsProps = $props();

	// 圆角风格样式
	// radius style
	const radiusObj = {
		none: 'rounded-none',
		sm: 'rounded-sm',
		xl: 'rounded-xl',
		'2xl': 'rounded-2xl',
		'3xl': 'rounded-3xl',
		full: 'rounded-full'
	};
	// 边框粗细样式
	// border width style
	const lineWidthClass = {
		0: 'ring-0',
		1: 'ring-1',
		2: 'ring-2',
		3: 'ring',
		4: 'ring-4',
		8: 'ring-8'
	};

	// 头像框大小样式
	// avatar size style
	const sizeObj = {
		xs: 'w-6 h-6',
		sm: 'w-10 h-10',
		base: 'w-12 h-12',
		md: 'w-16 h-16',
		lg: 'w-20 h-20',
		xl: 'w-28 h-28',
		'2xl': 'w-32 h-32'
	};

	// 替换文本大小样式
	// replace text size style
	const textSizeObj = {
		xs: 'text-xs',
		sm: 'text-sm',
		base: 'text-lg',
		md: 'text-3xl',
		lg: 'text-4xl',
		xl: 'text-6xl',
		'2xl': 'text-8xl'
	};

	const dataInner = data.slice(0, max);
</script>

<button class="flex" onclick={() => onclick && onclick()}>
	{#if reverse}
		<div
			class="relative {lineWidthClass[lineWidth] || lineWidthClass[2]} ring-primaryWhite dark:ring-darkBlack {radiusObj[radius] ||
				radiusObj.sm} {injClass}"
			style="z-index:{dataInner.length}"
		>
			{#if top === 'totle'}
				<div
					class="bg-primary-200 dark:bg-dark-200 text-primary-950 dark:text-dark-950 flex flex-col justify-center overflow-hidden text-center {radiusObj[
						radius
					] || radiusObj.sm} {sizeObj[size] || sizeObj.md} {textSizeObj[size] || textSizeObj.base}"
				>
					+{data.length}
				</div>
			{:else if top === 'add'}
				<div
					class="bg-primary-200 dark:bg-dark-200 flex flex-col justify-center overflow-hidden text-center {radiusObj[radius] ||
						radiusObj.sm} {sizeObj[size] || sizeObj.md} {textSizeObj[size] || textSizeObj.base}"
				>
					<Icon name="ri-user-add-line" injClass="text-primary-950 dark:text-dark-950" />
				</div>
			{:else if top === null}{:else}
				{@render top?.()}
			{/if}
		</div>
	{/if}
	{#each dataInner as item, i}
		<div
			class="relative {lineWidthClass[lineWidth] || lineWidthClass[2]} ring-primaryWhite dark:ring-darkBlack {radiusObj[radius] ||
				radiusObj.sm} {injClass}"
			style="transform: translateX({-compact * 10 * i - (reverse ? 50 : 0)}%);z-index:{reverse ? dataInner.length - 1 - i : i}"
		>
			<Avatar {radius} {size} {...item} />
		</div>
	{/each}
	{#if !reverse}
		<div
			class="relative {lineWidthClass[lineWidth] || lineWidthClass[2]} ring-primaryWhite dark:ring-darkBlack {radiusObj[radius] ||
				radiusObj.sm} {injClass}"
			style="transform: translateX(-{compact * 10 * dataInner.length}%);z-index:{dataInner.length}"
		>
			{#if top === 'totle'}
				<div
					class="bg-primary-200 dark:bg-dark-200 text-primary-950 dark:text-dark-950 flex flex-col justify-center overflow-hidden text-center {radiusObj[
						radius
					] || radiusObj.sm} {sizeObj[size] || sizeObj.md} {textSizeObj[size] || textSizeObj.base}"
				>
					+{data.length}
				</div>
			{:else if top === 'add'}
				<div
					class="bg-primary-200 dark:bg-dark-200 flex flex-col justify-center overflow-hidden text-center {radiusObj[radius] ||
						radiusObj.sm} {sizeObj[size] || sizeObj.md} {textSizeObj[size] || textSizeObj.base}"
				>
					<Icon name="ri-user-add-line" injClass="text-primary-950 dark:text-dark-950" />
				</div>
			{:else if top === null}{:else}
				{@render top?.()}
			{/if}
		</div>
	{/if}
</button>



================================================
FILE: packages/stdf/src/lib/components/badge/Badge.svelte
================================================
<script lang="ts">
	import type { BadgeProps } from '../../types/index.js';
	let {
		text = '',
		radius = 'full',
		isLeft = false,
		isShow = true,
		offsetY = 0,
		offsetX = 0,
		isInner = false,
		injClass = '',
		children
	}: BadgeProps = $props();

	// 圆角风格样式
	// radius style
	const radiusObj = {
		full: ' rounded-full',
		sm: ' rounded-sm',
		none: ' rounded-none',
		leftLeaf: ' rounded-full rounded-br-none',
		rightLeaf: ' rounded-full rounded-bl-none'
	};

	// 通过 radius 配置圆角风格或叶形
	// set radius style or leaf style by radius
	const radiusClass = radius === 'leaf' ? (isLeft ? radiusObj.leftLeaf : radiusObj.rightLeaf) : radiusObj[radius] || radiusObj.full;
</script>

{#if isInner}
	<div
		class="px-1 text-xs text-white whitespace-nowrap{radiusClass}{text === ''
			? ' h-3 w-3'
			: ' '} text-center leading-4 transition-all bg-[red]{injClass === '' ? '' : ` ${injClass}`}"
		style="transform:{isShow ? ' scale(1)' : ' scale(0)'}"
	>
		{text}
	</div>
{:else}
	<div class="relative">
		{@render children?.()}
		<div
			class="absolute{text === '' ? ' -top-1.5' : ' -top-2'}{isLeft
				? ' left-0'
				: ' right-0'} px-1 text-xs text-white whitespace-nowrap{radiusClass}{text === ''
				? ' h-3 w-3'
				: ' '} text-center leading-4 transition-all bg-[red]{injClass === '' ? '' : ` ${injClass}`}"
			style="transform: translateX(calc({isLeft ? '-' : ''}50% {isLeft ? '+' : '-'} {offsetX}px)) translateY({offsetY}px){isShow
				? ' scale(1)'
				: ' scale(0)'}"
		>
			{text}
		</div>
	</div>
{/if}



================================================
FILE: packages/stdf/src/lib/components/bottomSheet/BottomSheet.svelte
================================================
<script lang="ts">
	import { onMount, getContext } from 'svelte';
	import { fly } from 'svelte/transition';
	import { throttleWithRAF } from '../utils/index.js';
	import Mask from '../mask/Mask.svelte';
	import Icon from '../icon/Icon.svelte';
	import { zh_CN, type LangProps } from '../../lang/index.js';
	import type { BottomSheetProps } from '../../types/index.js';

	// 当前语言
	// current language
	const currentLang = (getContext('STDF_lang') || zh_CN) as LangProps;
	const bottomSheetLang: LangProps['bottomSheet'] = currentLang.bottomSheet;

	let {
		visible = $bindable(false),
		title = bottomSheetLang.title,
		titleAlign = 'left',
		showBackIcon = false,
		closeContent = 'downIcon',
		showDivider = true,
		duration = 450,
		outDuration = 240,
		mask = {},
		maskClosable = false,
		zIndex = 600,
		stayHeightList = [10, 50, 90],
		stayHeightIndex = 1,
		closeHeight = 0,
		radius = 'full',
		children,
		onheightChange,
		onclickMask,
		onclose,
		onback
	}: BottomSheetProps = $props();

	// 固定高度
	// stay height
	let stayHeight = stayHeightList[stayHeightIndex] || stayHeightList[stayHeightList.length - 1];

	// 此时是否正在滑动
	// is sliding or not now
	let isTouch = $state(false);

	// 滑动开始 Y 坐标，px
	// start Y coordinate, px
	let startY = 0;

	// 滑动中 Y 方向当前位置，px
	// current Y coordinate, px
	let currentY = 0;

	// 滑动开始距离顶部高度，%
	// start distance from top, %
	let startTop = $state(100 - stayHeight);

	// 滑动距离，%
	// move distance, %
	let moveDistance = $state(0);

	// 顶部滚动区域高度，%
	// top scroll area height, %
	let scrollTopHeight = $state(5);

	// 顶部滚动区域元素
	// top scroll area element
	let scrollTopDom = $state<HTMLDivElement | null>(null);

	// 当前距离顶部高度，%
	// current distance from top, %
	let currentTop = $state(0);
	$effect(() => {
		currentTop = startTop + moveDistance;
	});

	// 如果 stayHeightList 不是数组，或者元素不是正数，或者元素不是 0-100 之间的数，或者元素不是整数，给出警告。
	// If stayHeightList is not an array, or the element is not a positive number, or the element is not a number between 0 and 100, or the element is not an integer, give a warning.
	if (
		!Array.isArray(stayHeightList) ||
		stayHeightList.some((item) => typeof item !== 'number' || item < 0 || item > 100 || item % 1 !== 0)
	) {
		console.error(
			'[STDF BottomSheet error]stayHeightList 必须是一个 0-100 之间的正整数数组。(stayHeightList must be an array of positive integers between 0 and 100)'
		);
	}

	// 如果 stayHeightList 元素不是递增的，给出警告。
	// If the elements of stayHeightList are not increasing, give a warning.
	if (stayHeightList.some((item, index) => index > 0 && item <= stayHeightList[index - 1])) {
		console.error(
			'[STDF BottomSheet error]stayHeightList 数组元素必须是升序排列。(stayHeightList array elements must be in ascending order)'
		);
	}

	// 如果 stayHeightIndex 超出 stayHeightList 长度给出警告。
	// If stayHeightIndex exceeds the length of stayHeightList, give a warning.
	if (stayHeightIndex > stayHeightList.length - 1) {
		console.warn(
			'[STDF BottomSheet warn]stayHeightIndex 超出 stayHeightList 长度，将使用 stayHeightList 最后一个值。(stayHeightIndex exceeds the length of stayHeightList, the last value of stayHeightList will be used.)'
		);
	}

	// 如果 closeHeight 大于 stayHeightList 最小值给出警告。
	// If closeHeight is greater than the minimum value of stayHeightList, give a warning.
	if (closeHeight > stayHeightList[0]) {
		console.warn(
			'[STDF BottomSheet warn]closeHeight 大于 stayHeightList 最小值，closeHeight 将失效。(closeHeight is greater than the minimum value of stayHeightList, closeHeight will be invalid.)'
		);
	}

	// 标题对齐方式
	// title align
	const titleAlignClass = { left: ' text-left', center: ' text-center', right: ' text-right' };

	// 窗口圆角风格
	// window radius style
	const windowRadiusClass = { none: ' rounded-none', middle: ' rounded-t-lg', full: ' rounded-t-2xl' };

	// 图标圆角风格
	// icon radius style
	const iconRadiusClass = { none: ' rounded-none', middle: ' rounded-sm', full: ' rounded-full' };

	// 滑动开始
	// start sliding
	/** @type {(e:PointerEvent) => void} */
	const touchstartFun = (e: PointerEvent) => {
		moveDistance = 0;
		startTop = currentTop;
		startY = e.clientY;
		isTouch = true;
	};

	// 滑动中
	// sliding
	/** @type {(e:PointerEvent) => void} */
	const touchmoveFun = (e: PointerEvent) => {
		if (!isTouch) return;
		scrollTopDom?.setPointerCapture(e.pointerId);
		currentY = e.clientY;
		//移动百分比，moveDistance 为正时，向下移动
		//Move percentage, moveDistance is positive when moving down
		moveDistance = ((currentY - startY) / window.innerHeight) * 100;
		//处理向上滑动时超过最大高度情况
		//Handle the case when the maximum height is exceeded when sliding up
		if (moveDistance + startTop < 100 - stayHeightList[stayHeightList.length - 1]) {
			moveDistance = 100 - stayHeightList[stayHeightList.length - 1] - startTop;
		}
	};

	// 滑动结束
	// end sliding
	const touchendFun = () => {
		isTouch = false;
		//计算出每个高度对应的 top 值
		//Calculate the top value corresponding to each height
		let toTopList = stayHeightList.map((item) => 100 - item);
		let min = 100;
		let currentIndex = 0;
		toTopList.forEach((item, index) => {
			if (Math.abs(item - currentTop) < min) {
				min = Math.abs(item - currentTop);
				currentIndex = index;
			}
		});
		currentTop = toTopList[currentIndex];
		//派发事件，传递当前高度
		//Dispatch events and pass the current
		if (onheightChange) {
			onheightChange(stayHeightList[currentIndex]);
		}
		//判断滑动结束时如果位置低于 closeHeight 自动关闭，并派发事件
		//If the position is lower than closeHeight at the end of the slide, it will be automatically closed and the event will be dispatched.
		if (((window.innerHeight - currentY) / window.innerHeight) * 100 < closeHeight && closeHeight > 0) {
			visible = false;
			onclose?.();
		}
	};

	//点击遮罩层
	//click mask
	const clickMaskFn = () => {
		//点击遮罩时派发 clickMask 事件
		//Dispatch clickMask event when clicking mask
		onclickMask?.();
		if (maskClosable) {
			visible = false;
		}
	};

	//点击关闭图标
	//click close icon
	const closeFunc = () => {
		visible = false;
		//点击关闭时派发 close 事件
		//Dispatch close event when clicking close
		onclose?.();
	};

	//点击返回图标
	//click back icon
	const backFunc = () => {
		//点击返回时派发 back 事件
		//Dispatch back event when clicking back
		onback?.();
	};

	// 滚动时禁止 body 滚动
	// Disable body scrolling when scrolling
	$effect(() => {
		if (visible) {
			//当 visible 为 true 时，禁止 body 滚动
			//When visible is true, body scrolling is disabled
			const top = document.documentElement.scrollTop || document.body.scrollTop;
			document.body.style.cssText += `
            position: fixed;
            width: 100vw;
            left: 0;
            top: ${-top}px;
            touch-action:none;
        `;
		} else {
			const top = document.body.style.top;
			document.body.style.cssText += `
            position: static;
            touch-action:auto;
        `;
			window.scrollTo(0, Math.abs(parseFloat(top)));
		}
	});
	onMount(() => {
		if (visible && scrollTopDom) {
			// 滚动内容高度
			// Scroll content height
			scrollTopHeight = scrollTopDom.clientHeight;
		}
	});
</script>

{#if visible}
	<Mask visible {duration} {outDuration} {...mask} onclickMask={clickMaskFn} />
{/if}

<div class="pointer-events-none fixed inset-0 flex h-screen w-screen flex-col justify-end px-0" style="z-index:{zIndex};">
	{#if visible}
		<div
			class="fixed w-screen bg-white dark:bg-gray-950{windowRadiusClass[radius] || windowRadiusClass['full']} pointer-events-auto{isTouch
				? ''
				: ' transition-all duration-300'}"
			style="height:{stayHeightList[stayHeightList.length - 1]}%;top:{currentTop}%"
			in:fly={{
				y: (stayHeightList[stayHeightList.length - 1] / 100) * window.innerHeight,
				opacity: 1,
				duration
			}}
			out:fly={{
				y: (stayHeightList[stayHeightList.length - 1] / 100) * window.innerHeight,
				opacity: 1,
				duration: outDuration
			}}
		>
			<div
				onpointerdown={(e: PointerEvent) => touchstartFun(e)}
				onpointermove={(e: PointerEvent) => throttleWithRAF(touchmoveFun)(e)}
				onpointerup={touchendFun}
				bind:this={scrollTopDom}
				class="cursor-move touch-none select-none py-1"
			>
				<div class="h-1 w-8 bg-black/20 dark:bg-white/30 mx-auto{radius === 'none' ? ' rounded-none' : ' rounded-full'}"></div>
				<div class="flex items-center justify-between gap-2 px-3 py-1">
					{#if showBackIcon}
						<button
							class="h-6 w-6 flex-none bg-black/5 dark:bg-white/10 text-center{iconRadiusClass[radius] || iconRadiusClass['full']}"
							onclick={backFunc}
						>
							<Icon name="ri-arrow-left-s-line" alpha={0.4} size={16} top={-2} />
						</button>
					{/if}
					<div class="h-7 truncate text-lg font-bold grow{titleAlignClass[titleAlign] || titleAlignClass['left']}">
						{title}
					</div>
					{#if closeContent === ''}
						<!-- null -->
					{:else if closeContent === 'closeIcon'}
						<button
							class="h-6 w-6 flex-none bg-black/5 dark:bg-white/10 text-center{iconRadiusClass[radius] || iconRadiusClass['full']}"
							onclick={closeFunc}
						>
							<Icon name="ri-close-line" alpha={0.4} size={14} top={-2} />
						</button>
					{:else if closeContent === 'downIcon'}
						<button
							class="h-6 w-6 flex-none bg-black/5 dark:bg-white/10 text-center{iconRadiusClass[radius] || iconRadiusClass['full']}"
							onclick={closeFunc}
						>
							<Icon name="ri-arrow-down-s-line" alpha={0.4} size={16} top={-1} />
						</button>
					{:else}
						<button class="text-primary dark:text-dark cursor-pointer font-bold" onclick={closeFunc}>{closeContent}</button>
					{/if}
				</div>
			</div>
			{#if showDivider}
				<div class="h-px w-full bg-black/5 dark:bg-white/10"></div>
			{/if}
			<div
				class="overflow-auto"
				style="height:{window.innerHeight * ((100 - currentTop) / 100) - scrollTopHeight}px;overscroll-behavior-y: contain;"
			>
				{@render children?.()}
			</div>
		</div>
	{/if}
</div>



================================================
FILE: packages/stdf/src/lib/components/button/Button.svelte
================================================
<script lang="ts">
	import Icon from '../icon/Icon.svelte';
	import Loading from '../loading/Loading.svelte';
	import type { ButtonProps } from '../../types/index.js';

	let {
		fill = 'base',
		state = 'theme',
		radius = 'sm',
		size = 'big',
		line = 'solid',
		injClass = '',
		love = false,
		heightOut = '2',
		heightIn = '3',
		group = false,
		disabled = false,
		customSize = false,
		customWidth = 0,
		customHeight = 0,
		icon = null,
		loading = null,
		disabledLoading = true,
		type = 'button',
		children,
		onclick
	}: ButtonProps = $props();

	let innerDisabled = $derived(disabled || (loading && disabledLoading));

	// 状态样式
	// State style
	const stateObj = { theme: 'bg-primary dark:bg-dark', success: 'bg-success', warning: 'bg-warning', error: 'bg-error', info: 'bg-info' };

	// 圆角风格样式
	// Corner style style
	const radiusObj = { none: 'rounded-none', sm: 'rounded-sm', xl: 'rounded-xl', '2xl': 'rounded-2xl', full: 'rounded-full' };

	// 填充模式样式
	// Fill mode style
	const fillObj = {
		base: '',
		line: 'border border-black dark:border-white !text-black dark:!text-white',
		lineLight: 'border border-black/20 dark:border-white/30 !text-black dark:!text-white',
		lineTheme: 'border border-primary dark:border-dark !text-primary dark:!text-dark',
		text: '!text-black dark:!text-white',
		textTheme: '!text-primary dark:!text-dark',
		colorLight: '!bg-black/5 dark:!bg-white/10 !text-black dark:!text-white'
	};

	// 尺寸样式
	// Size style
	const sizeObj = { full: 'w-full', big: 'w-full', md: 'w-1/2', sm: 'w-1/4', auto: 'w-auto' };

	// 边框风格样式
	// Border style style
	const lineObj = { solid: 'border-solid', dashed: 'border-dashed', dotted: 'border-dotted' };

	// 按钮外部高度样式
	// Button outer height style
	const heightOutObj = { '0': 'py-0', '1': 'py-1', '2': 'py-2', '3': 'py-3', '4': 'py-4' };

	// 按钮高度样式
	// Button height style
	const heightInObj = { '0': 'py-0', '1': 'py-1', '2': 'py-2', '3': 'py-3', '4': 'py-4' };

	// 是否块级元素
	// Whether it is a block element
	const block = (size === 'full' || size === 'big') && !customSize;

	// 文字颜色
	// Text color
	const textColor = state === 'theme' ? 'text-white dark:text-black' : 'text-white';
</script>

<div
	class="{heightOutObj[heightOut] || heightOutObj['2']} {size === 'big' && !customSize ? 'px-4' : 'px-0'} {block ? 'block' : 'inline'} {love
		? 'text-xl'
		: ''}"
>
	<button
		{onclick}
		class="inline-flex items-center justify-center gap-1 truncate {!group && !innerDisabled ? 'active:opacity-80' : ''} {heightInObj[
			heightIn
		] || heightInObj['3']} {sizeObj[size] || sizeObj.big} {textColor} {lineObj[line] || lineObj.solid} {radiusObj[radius] ||
			radiusObj.sm} {fill === 'base' && (stateObj[state] || stateObj.theme)} {fillObj[fill] || fillObj.base} {injClass} {innerDisabled
			? 'cursor-not-allowed opacity-50'
			: ''}"
		disabled={innerDisabled}
		style={customSize ? `width:${customWidth}px;height:${customHeight}px;padding:0;` : ''}
		{type}
	>
		{#if loading}
			<Loading {...loading} />
		{/if}
		{#if icon && icon.name}
			<Icon {...icon} />
		{/if}
		{@render children?.()}
	</button>
</div>



================================================
FILE: packages/stdf/src/lib/components/calendar/Calendar.svelte
================================================
<script lang="ts">
	import { getContext } from 'svelte';
	import Popup from '../popup/Popup.svelte';
	import Button from '../button/Button.svelte';
	import {
		getNowBeforeOrAfterMonth,
		getCalendarData,
		getMonthListRange,
		getDateRange,
		getCurrentWeek,
		getCurrentMonth,
		getCurrentQuarter,
		getDaysRangeWithToday
	} from '../utils/index.js';
	import { zh_CN, type LangProps } from '../../lang/index.js';
	import type { CalendarProps } from '../../types/index.js';

	// 当前语言
	// current language
	const currentLang = (getContext('STDF_lang') || zh_CN) as LangProps;
	const calendarLang: LangProps['calendar'] = currentLang.calendar;

	let {
		visible = $bindable(false),
		startMonth = getNowBeforeOrAfterMonth(-6),
		endMonth = getNowBeforeOrAfterMonth(6),
		initMonth = getNowBeforeOrAfterMonth(0),
		mode = 'single',
		startSunday = false,
		weekendRed = false,
		monthCard = true,
		monthMark = false,
		monthMarkSize = '7xl',
		height = 50,
		infoDates = [],
		disabledDates = [],
		radius = 'xl',
		showSelectedDay = true,
		confirmText = calendarLang.confirmText,
		selectedText = calendarLang.selectedText,
		dayText = calendarLang.dayText,
		quickSelects = [],
		includeToday = false,
		useAnimation = true,
		highlightToday = true,
		outFormat = 'YYYYMMDD',
		popup = {},
		button = {},
		clear = true,
		onconfirm,
		onclose
	}: CalendarProps = $props();

	// 圆角风格样式
	// Rounded style style
	const radiusClass = { sm: 'rounded-sm', xl: 'rounded-xl', '2xl': 'rounded-2xl', none: 'rounded-none' };

	// 月份水印文字大小样式
	// Month watermark text size style
	const monthMarkSizeClass = {
		'3xl': 'text-3xl',
		'4xl': 'text-4xl',
		'5xl': 'text-5xl',
		'6xl': 'text-6xl',
		'7xl': 'text-7xl',
		'8xl': 'text-8xl',
		'9xl': 'text-9xl'
	};

	// 当天日期字符串，YYYYMMDD，日和天不足两位时前面补 0
	// Today's date string, YYYYMMDD, day and day are not less than two digits, and 0 is filled in front
	const now = new Date();
	const nowYear = now.getFullYear();
	const nowMonth = now.getMonth() + 1;
	const nowDay = now.getDate();
	const todayStr = `${nowYear}${nowMonth < 10 ? '0' + nowMonth : nowMonth}${nowDay < 10 ? '0' + nowDay : nowDay}`;

	// 滚动元素
	// Scroll element
	let scrollElement = $state<HTMLDivElement | null>(null);

	// 是否点击了快速选择
	// Whether to click the quick selection
	let isQuickSelect = $state(false);

	// 定义周数据文字
	// Define the week data text
	const weekTexts = startSunday ? calendarLang.weekSundayStartTextList : calendarLang.weekTextList;

	// 传入 startSunday 和位于周的索引，返回是否是周末
	// Pass in startSunday and the index of the week, and return whether it is a weekend
	const isWeekendFunc = (startSunday: boolean, index: number) => {
		if (startSunday) {
			return index === 0 || index === 6;
		} else {
			return index === 5 || index === 6;
		}
	};

	// 根据 startMonth 和 endMonth 将月份数据组成 monthList
	// According to startMonth and endMonth, the month data is assembled into monthList
	const monthList = getMonthListRange(startMonth, endMonth);

	// 如果 initMonth 在 startMonth 和 endMonth 之间 initMonthIndex 为 initMonth 在 monthList 中的索引，如果在 startMonth 之前，initMonthIndex 为 0，如果在 endMonth 之后，initMonthIndex 为 monthList.length - 1
	// If initMonth is between startMonth and endMonth, initMonthIndex is the index of initMonth in monthList. If it is before startMonth, initMonthIndex is 0. If it is after endMonth, initMonthIndex is monthList.length - 1
	const initMonthIndex = monthList.findIndex((item) => item === initMonth);

	// 循环 monthList，根据每个月份的数据，生成全部的日历数据，其中 month 为当前月，year 为年，data 为日期数组
	// Loop monthList, generate all calendar data according to the data of each month, where month is the current month, year is the year, and data is the date array
	const allMonthData: {
		year: string;
		month: string;
		days: { text: string; info?: string; disabled?: boolean; start?: boolean; end?: boolean }[];
	}[] = monthList.map((monthStr) => ({
		year: monthStr.slice(0, 4),
		month: monthStr.slice(4),
		days: getCalendarData(monthStr, startSunday).map((item) => ({
			text: item,
			info: '',
			disabled: false,
			start: false,
			end: false
		}))
	}));

	// 如果 infoDates 不为空，循环 allMonthData，循环 data，循环 infoDates，如果 infoDates 中的日期和 data 中的日期相同，将 infoDates 中的 info 赋值给 data 中的 info
	// If infoDates is not empty, loop allMonthData, loop data, loop infoDates, if the date in infoDates is the same as the date in data, assign the info in infoDates to the info in data
	if (infoDates.length > 0) {
		allMonthData.forEach((monthData) => {
			monthData.days.forEach((item) => {
				infoDates.forEach((info) => {
					if (info.text === monthData.year + monthData.month + item.text) {
						item.info = info.info;
					}
				});
			});
		});
	}

	// 如果 disabledDates 不为空，循环 allMonthData，循环 data，循环 disabledDates，如果 disabledDates 中的日期和 data 中的日期相同，将 disabledDates 中的 disabled 赋值给 data 中的 disabled
	// If disabledDates is not empty, loop allMonthData, loop data, loop disabledDates, if the date in disabledDates is the same as the date in data, assign the disabled in disabledDates to the disabled in data
	if (disabledDates.length > 0) {
		allMonthData.forEach((monthData) => {
			monthData.days.forEach((item) => {
				disabledDates.forEach((disabled) => {
					if (disabled === monthData.year + monthData.month + item.text) {
						item.disabled = true;
					}
				});
			});
		});
	}

	// 选中的日期
	// Selected date
	let selectedDate: string[] = $state([]);

	// 范围选择时，点击的开始与结束
	// When range selection is clicked, the beginning and end are clicked
	let rangeArr: string[] = [];

	// selectedDate 字符串
	// selectedDate string
	let selectedDateStr = $state('');

	// 点击日期事件
	// Click date event
	const clickDayFunc = (
		year: string,
		month: string,
		days: { text: string; info?: string; disabled?: boolean; start?: boolean; end?: boolean }
	) => {
		if (!days.text) {
			return;
		}
		if (isQuickSelect) {
			isQuickSelect = false;
			selectedDate = [];
		}
		if (mode === 'range') {
			rangeArr.push(`${year}${month}${days.text}`);
			if (rangeArr.length === 2) {
				// 将 rangeArr 排序，保证第一个日期小于第二个日期
				// Sort rangeArr to ensure that the first date is less than the second date
				rangeArr.sort((a, b) => Number(a) - Number(b));
				selectedDate = getDateRange(rangeArr[0], rangeArr[1], disabledDates);
				rangeArr = [];
			} else {
				selectedDate = rangeArr;
			}
		} else if (mode === 'multiple') {
			const index = selectedDate.findIndex((item) => item === `${year}${month}${days.text}`);
			if (index === -1) {
				selectedDate.push(`${year}${month}${days.text}`);
			} else {
				selectedDate.splice(index, 1);
			}
		} else {
			selectedDate = [`${year}${month}${days.text}`];
		}
		// 对 selectedDate 按照日期排序
		// Sort selectedDate by date
		selectedDate.sort((a, b) => Number(a) - Number(b));
		selectedDateStr = selectedDate.join(',');
	};

	// 快速选择项目
	// Quick selection item
	let quickSelectItem: string | number = $state('');

	// 点击快速选择
	// Click quick selection
	const quickSelectFunc = (type: string | number) => {
		isQuickSelect = true;
		quickSelectItem = type;
		if (type === 'week') {
			selectedDate = getCurrentWeek(startSunday);
		}
		if (type === 'month') {
			selectedDate = getCurrentMonth();
		}
		if (type === 'quarter') {
			selectedDate = getCurrentQuarter();
		}
		// 如果 type 是数字类型且是整数，表示选择最近几天，负整数表示选择之前几天，正整数表示选择之后几天
		// If type is a number type and is an integer, it means to select the last few days. A negative integer means to select the previous few days, and a positive integer means to select the next few days
		if (typeof type === 'number' && Number.isInteger(type)) {
			selectedDate = getDaysRangeWithToday(type, includeToday);
		}
		// 剔除 disabledDates 中的日期
		// Remove dates in disabledDates
		if (disabledDates && disabledDates.length) {
			disabledDates.forEach((item) => {
				const index = selectedDate.findIndex((date) => date === item);
				if (index !== -1) {
					selectedDate.splice(index, 1);
				}
			});
		}
		selectedDateStr = selectedDate.join(',');
		// 对快速选择做自动滚动
		// Automatic scrolling for quick selection
		if (scrollElement) {
			// 取 selectedDate 的第一个值，再取出前 6 位，再在 monthList 中找到对应的索引，再根据索引计算出滚动的高度
			// Take the first value of selectedDate, then take the first 6 digits, then find the corresponding index in monthList, and then calculate the height of the scroll according to the index
			const index = monthList.findIndex((item) => item === selectedDate[0].slice(0, 6));
			scrollElement.scrollTop = scrollElement.scrollHeight * (index / monthList.length);
		}
	};

	// 传入日期格式与日期字符对象，将其中的前四位对应 format 的 YYYY，中间两位对应 format 的 MM，后两位对应 format 的 DD，返回格式化后的字符串
	// Pass in the date format and date character object, and return the formatted string
	const getDateStrFunc = (format: string, date: string) => {
		const year = date.slice(0, 4);
		const month = date.slice(4, 6);
		const day = date.slice(6, 8);
		format = format.replace('YYYY', year);
		format = format.replace('MM', month);
		format = format.replace('DD', day);
		return format;
	};

	// 点击确定事件
	// Click the confirm event
	const confirmFunc = () => {
		visible = false;
		// 根据传入的 outFormat，循环 selectedDate，将 selectedDate 中的日期使用 getDateStrFunc 转换为 outFormat 格式的日期字符串
		// Loop selectedDate according to the outFormat passed in, and use getDateStrFunc to convert the date in selectedDate to a date string in the outFormat format
		if (selectedDate.length) {
			selectedDate = selectedDate.map((item) => getDateStrFunc(outFormat, item));
		}
		onconfirm?.(selectedDate);
	};

	// 根据 initMonthIndex 在 monthList 中的索引，自动滚动到 scrollElement 高度的百分比
	// Automatically scroll to the percentage of the height of scrollElement according to the index of initMonthIndex in monthList
	$effect(() => {
		if (scrollElement && visible && !isQuickSelect) {
			scrollElement.scrollTop = scrollElement.scrollHeight * (initMonthIndex / monthList.length);
		}
	});

	// 监听 visible 的变化，派发事件
	// Listen to the change of visible, dispatch events
	$effect(() => {
		if (!visible) {
			if (clear) {
				selectedDate = [];
				selectedDateStr = '';
			}
			onclose?.();
		}
	});
</script>

<Popup
	bind:visible
	size={0}
	maskClosable
	transitionDistance={(window.innerHeight * height) / 100 + 40 + 64 + (quickSelects.length > 0 && mode === 'range' ? 36 : 0)}
	{...popup}
>
	<div>
		<div class="sticky left-0 top-0 z-10 w-full bg-gray-50 dark:bg-gray-800">
			{#if quickSelects.length > 0 && mode === 'range'}
				<div class="calendar-container flex flex-nowrap gap-4 overflow-x-auto px-4 pb-1 pt-2">
					{#each quickSelects as item}
						<button
							class="flex-none rounded-sm bg-white px-2 py-1 text-xs shadow-sm dark:bg-black dark:shadow-white/10"
							class:!bg-primary={isQuickSelect && quickSelectItem === item}
							class:text-white={isQuickSelect && quickSelectItem === item}
							class:dark:!bg-dark={isQuickSelect && quickSelectItem === item}
							class:dark:text-black={isQuickSelect && quickSelectItem === item}
							onclick={() => quickSelectFunc(item)}
						>
							{#if item === 'week'}
								{calendarLang.currentWeekText}
							{:else if item === 'month'}
								{calendarLang.currentMonthText}
							{:else if item === 'quarter'}
								{calendarLang.currentQuarterText}
							{:else if Number.isInteger(item) && item < 0}
								{calendarLang.beforeText + ' ' + Math.abs(item) + ' ' + calendarLang.dayText}
							{:else if Number.isInteger(item) && item > 0}
								{calendarLang.afterText + ' ' + Math.abs(item) + ' ' + calendarLang.dayText}
							{:else}
								<!-- else content here -->
							{/if}
						</button>
					{/each}
				</div>
			{/if}
			<div class="flex h-10 items-center justify-around gap-1 px-6 text-center leading-10">
				{#each weekTexts as item, index}
					<div class="flex-1 font-bold{weekendRed && isWeekendFunc(startSunday, index) ? ' text-error' : ''}">
						{item}
					</div>
				{/each}
			</div>
		</div>
		<div
			class="calendar-container flex flex-col gap-4 overflow-y-auto bg-gray-50 px-4 py-2 dark:bg-gray-800 {useAnimation
				? 'scroll-smooth'
				: 'scroll-auto'}"
			style="height:{(window.innerHeight * height) / 100}px"
			bind:this={scrollElement}
		>
			{#each allMonthData as item}
				<div
					class="{monthCard ? `bg-white shadow-md dark:bg-black dark:shadow-white/5 ${radiusClass[radius] || 'rounded-xl'}` : ''} relative"
				>
					<div class="px-4 pt-4 text-xl text-black/30 dark:text-white/30">
						<span class="mr-2 font-bold text-black dark:text-white">
							{calendarLang.monthTextList[Number(item.month) - 1]}
						</span>
						{item.year}
					</div>
					<div class="grid grid-cols-7 gap-y-1 p-2 text-center">
						{#each item.days as day}
							<button
								class="p-px{day.text ? ' bg-primary/10 dark:bg-dark/20' : ''}"
								onclick={() => {
									if (!day.disabled) clickDayFunc(item.year, item.month, day);
								}}
								class:!bg-transparent={!selectedDateStr.includes(`${item.year}${item.month}${day.text}`)}
								class:!rounded-l-xl={radius === 'xl' &&
									mode === 'range' &&
									(selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) === 0 || day.start)}
								class:!rounded-r-xl={radius === 'xl' &&
									mode === 'range' &&
									(selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) === selectedDateStr.length - 8 || day.end)}
								class:!rounded-xl={radius === 'xl' && mode !== 'range'}
								class:!rounded-l-2xl={radius === '2xl' &&
									mode === 'range' &&
									(selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) === 0 || day.start)}
								class:!rounded-r-2xl={radius === '2xl' &&
									mode === 'range' &&
									(selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) === selectedDateStr.length - 8 || day.end)}
								class:!rounded-2xl={radius === '2xl' && mode !== 'range'}
								class:!rounded-l-none={radius === 'none' &&
									mode === 'range' &&
									(selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) === 0 || day.start)}
								class:!rounded-r-none={radius === 'none' &&
									mode === 'range' &&
									(selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) === selectedDateStr.length - 8 || day.end)}
								class:!rounded-none={radius === 'none' && mode !== 'range'}
								class:!rounded-l-sm={radius === 'sm' &&
									mode === 'range' &&
									(selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) === 0 || day.start)}
								class:!rounded-r-sm={radius === 'sm' &&
									mode === 'range' &&
									(selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) === selectedDateStr.length - 8 || day.end)}
								class:!rounded-sm={radius === 'sm' && mode !== 'range'}
							>
								<div
									class="{radiusClass[radius] || 'rounded-xl'} relative flex h-full w-full flex-col justify-center {day.info
										? 'py-1'
										: 'py-2'}"
									class:bg-primary={(day.text && mode !== 'range' && selectedDateStr.includes(`${item.year}${item.month}${day.text}`)) ||
										(day.text &&
											selectedDateStr.includes(`${item.year}${item.month}${day.text}`) &&
											mode === 'range' &&
											(selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) === 0 ||
												selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) === selectedDateStr.length - 8))}
									class:dark:bg-dark={(day.text && mode !== 'range' && selectedDateStr.includes(`${item.year}${item.month}${day.text}`)) ||
										(day.text &&
											selectedDateStr.includes(`${item.year}${item.month}${day.text}`) &&
											mode === 'range' &&
											(selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) === 0 ||
												selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) === selectedDateStr.length - 8))}
									class:text-white={(day.text && mode !== 'range' && selectedDateStr.includes(`${item.year}${item.month}${day.text}`)) ||
										(day.text &&
											selectedDateStr.includes(`${item.year}${item.month}${day.text}`) &&
											mode === 'range' &&
											(selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) === 0 ||
												selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) === selectedDateStr.length - 8))}
									class:dark:text-black={(day.text &&
										mode !== 'range' &&
										selectedDateStr.includes(`${item.year}${item.month}${day.text}`)) ||
										(day.text &&
											selectedDateStr.includes(`${item.year}${item.month}${day.text}`) &&
											mode === 'range' &&
											(selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) === 0 ||
												selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) === selectedDateStr.length - 8))}
									class:text-primary={mode === 'range' &&
										selectedDateStr.includes(`${item.year}${item.month}${day.text}`) &&
										selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) !== 0 &&
										selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) !== selectedDateStr.length - 8}
									class:dark:text-dark={mode === 'range' &&
										selectedDateStr.includes(`${item.year}${item.month}${day.text}`) &&
										selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) !== 0 &&
										selectedDateStr.indexOf(`${item.year}${item.month}${day.text}`) !== selectedDateStr.length - 8}
									class:border={item.year + item.month + day.text === todayStr && highlightToday}
									class:border-primary={item.year + item.month + day.text === todayStr && highlightToday}
									class:dark:border-dark={item.year + item.month + day.text === todayStr && highlightToday}
								>
									<div class="font-bold">
										{day.text ? Number(day.text) : ''}
									</div>
									<div class="text-xs opacity-50">{day.info || ''}</div>
									{#if day.text && day.disabled}
										<div
											class="absolute left-1/2 top-1/2 h-4/5 w-4/5 -translate-x-1/2 -translate-y-1/2 text-black/60 opacity-40 dark:text-white"
										>
											<svg viewBox="0 0 1024 1024" version="1.1" width="100%" height="100%" style="fill: currentColor;">
												<path
													d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333zM170.666667 512a341.333333 341.333333 0 0 0 550.016 270.08L241.92 303.36A339.84 339.84 0 0 0 170.666667 512z m341.333333-341.333333a339.882667 339.882667 0 0 0-209.877333 72.106666L781.226667 721.92A341.333333 341.333333 0 0 0 512 170.666667z"
												/>
											</svg>
										</div>
									{/if}
								</div>
							</button>
						{/each}
					</div>
					{#if monthMark}
						<div
							class="pointer-events-none absolute w-full {monthMarkSizeClass[monthMarkSize] ||
								'text-7xl'} left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 text-center font-bold text-black/5 {monthCard
								? 'dark:text-white/10'
								: 'dark:text-white/5'}"
						>
							{calendarLang.monthTextList[Number(item.month) - 1]}
						</div>
					{/if}
				</div>
			{/each}
		</div>
		<div class="sticky bottom-0 left-0 z-10 w-full bg-gray-50 dark:bg-gray-800">
			<Button {...button} onclick={confirmFunc}>
				{confirmText}
				{showSelectedDay && mode !== 'single' && selectedDateStr.split(',').length > 0
					? `(${selectedText} ${selectedDate.length} ${dayText})`
					: ''}
			</Button>
		</div>
	</div>
</Popup>

<style>
	.calendar-container::-webkit-scrollbar {
		display: none; /* Chrome Safari */
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/cell/Cell.svelte
================================================
<script lang="ts">
	import Icon from '../icon/Icon.svelte';
	import Switch from '../switch/Switch.svelte';
	import type { CellProps } from '../../types/index.js';

	let {
		title = '',
		detail = '',
		right = 'arrow',
		left = null,
		subTitle = '',
		info = '',
		line = false,
		my = '4',
		mx = '2',
		radius = 'lg',
		switchActive = $bindable(false),
		shadow = 'xs',
		injClass = '',
		love = false,
		clickAll = true,
		leftChild,
		rightChild,
		detailChild,
		onclick
	}: CellProps = $props();

	// 圆角风格样式
	// Rounded style style
	const radiusObj = {
		none: ' rounded-none',
		sm: ' rounded-sm',
		md: ' rounded-md',
		lg: ' rounded-lg',
		xl: ' rounded-xl',
		'2xl': ' rounded-2xl',
		full: ' rounded-full'
	};

	// 阴影风格样式
	// Shadow style style
	const shadowClass = {
		none: ' shadow-none',
		xs: ' shadow-xs dark:shadow-white/5',
		sm: ' shadow-sm dark:shadow-white/5',
		md: ' shadow-md dark:shadow-white/10',
		lg: ' shadow-lg dark:shadow-white/10',
		xl: ' shadow-xl dark:shadow-white/10',
		'2xl': ' shadow-2xl dark:shadow-white/25'
	};

	// 左右间距样式
	// Left and right margin style
	const mxClass = {
		'0': ' mx-0',
		'1': ' mx-1',
		'2': ' mx-2',
		'3': ' mx-3',
		'4': ' mx-4',
		'6': ' mx-6',
		'8': ' mx-8'
	};

	// 上下边距样式
	// Top and bottom margin style
	const myClass = {
		'0': ' my-0',
		'1': ' my-1',
		'2': ' my-2',
		'3': ' my-3',
		'4': ' my-4',
		'6': ' my-6',
		'8': ' my-8'
	};

	// 点击事件
	// Click event
	const setClickFun = () => {
		if (clickAll) {
			if (typeof right === 'object' && right?.type === 'switch' && !right?.switch?.disabled) {
				switchActive = right?.switch?.async ? switchActive : !switchActive;
			}
			// 派发事件
			// Dispatch event
			onclick?.();
		}
	};
</script>

<div
	class="bg-white px-3 dark:bg-gray-800{clickAll ? ' active:bg-gray-100 dark:active:bg-gray-600' : ''} {myClass[my] ||
		myClass['4']}{mxClass[mx] || mxClass['2']}{radiusObj[radius] || radiusObj['lg']} {shadowClass[shadow] || shadowClass['xs']}{love
		? ' text-xl'
		: ''} {injClass}"
>
	<button
		onclick={setClickFun}
		class="flex w-full items-center justify-between gap-4 py-4{line && my === '0' ? ' border-b border-black/5 dark:border-white/5' : ''}"
	>
		<div class="flex items-center justify-between">
			{#if leftChild}
				{@render leftChild?.()}
			{:else if left}
				<div class="mr-1 flex flex-col justify-center">
					<Icon {...left} />
				</div>
			{:else}{/if}
			<div class="flex flex-col text-left {subTitle === '' ? 'justify-center' : 'justify-between'}">
				<div class="font-medium">{title}</div>
				<div class="text-xs text-gray-500 dark:text-gray-400">{subTitle}</div>
			</div>
		</div>
		<div class="11 flex items-center justify-between">
			<div class="flex flex-col {info === '' ? 'justify-center' : 'justify-between'} text-right">
				{#if detailChild}
					{@render detailChild?.()}
				{:else if detail}
					<div class="text-gray-700 dark:text-gray-300">{detail}</div>
				{:else}{/if}
				<div class="text-xs font-light text-gray-500 dark:text-gray-400">{info}</div>
			</div>
			{#if rightChild}
				{@render rightChild?.()}
			{:else if right === 'arrow'}
				<div class="flex flex-col justify-center text-gray-700 dark:text-gray-300">
					<Icon name="ri-arrow-right-s-line" size={love ? 26 : 20} alpha={0.6} top={-2} />
				</div>
			{:else if typeof right === 'object' && right?.type === 'switch'}
				<div class="ml-1 flex flex-col justify-center">
					<Switch active={switchActive} {...right?.switch} />
				</div>
			{:else if typeof right === 'object' && right?.type === 'icon' && right?.icon}
				<div class="ml-1 flex flex-col justify-center">
					<Icon {...right?.icon} />
				</div>
			{:else}{/if}
		</div>
	</button>
</div>



================================================
FILE: packages/stdf/src/lib/components/cell/CellGroup.svelte
================================================
<script lang="ts">
	import type { CellGroupProps } from '../../types/index.js';

	let { radius = 'lg', shadow = 'xs', my = '4', mx = '2', children }: CellGroupProps = $props();

	const shadowClass = {
		none: ' shadow-none',
		xs: ' shadow-xs dark:shadow-white/5',
		sm: ' shadow-sm dark:shadow-white/5',
		md: ' shadow-md dark:shadow-white/10',
		lg: ' shadow-lg dark:shadow-white/10',
		xl: ' shadow-xl dark:shadow-white/10',
		'2xl': ' shadow-2xl dark:shadow-white/25'
	};
	const radiusClass = {
		none: ' rounded-none',
		sm: ' rounded-sm',
		md: ' rounded-md',
		lg: ' rounded-lg',
		xl: ' rounded-xl',
		'2xl': ' rounded-2xl',
		full: ' rounded-full'
	};
	const mxClass = { '0': ' mx-0', '1': ' mx-1', '2': ' mx-2', '3': ' mx-3', '4': ' mx-4', '6': ' mx-6', '8': ' mx-8' };
	const myClass = { '0': ' my-0', '1': ' my-1', '2': ' my-2', '3': ' my-3', '4': ' my-4', '6': ' my-6', '8': ' my-8' };
</script>

<div
	class="bg-white dark:bg-black overflow-hidden{shadowClass[shadow] || shadowClass['xs']}{radiusClass[radius] || radiusClass['lg']}{myClass[
		my
	] || myClass['4']}{mxClass[mx] || mxClass['2']}"
>
	{@render children?.()}
</div>



================================================
FILE: packages/stdf/src/lib/components/checkbox/Checkbox.svelte
================================================
<script lang="ts">
	import CheckboxItem from './CheckboxItem.svelte';
	import type { CheckboxProps } from '../../types/index.js';

	let {
		data = [],
		layout = 'v',
		checkeds = $bindable([]),
		textPosition = 'r',
		icon = 'default',
		iconChecked = 'default',
		checkboxChild,
		onchange
	}: CheckboxProps = $props();

	const clickItemFn = (name: string) => {
		checkeds = checkeds.includes(name) ? checkeds.filter((v) => v !== name) : [name, ...checkeds];
		onchange?.(checkeds);
	};
</script>

<div class={layout === 'inline' ? 'flex flex-wrap' : `flex ${layout === 'h' ? 'justify-between' : 'w-full flex-col space-y-2'}`}>
	{#each data as item}
		{#if checkboxChild}
			{@render checkboxChild({ item })}
		{:else}
			<CheckboxItem {layout} {...item} {textPosition} {icon} {iconChecked} checked={checkeds.includes(item.name)} onclick={clickItemFn}>
				{item.label}
			</CheckboxItem>
		{/if}
	{/each}
</div>



================================================
FILE: packages/stdf/src/lib/components/checkbox/CheckboxItem.svelte
================================================
<script lang="ts">
	import Icon from '../icon/Icon.svelte';
	import type { CheckboxItemProps } from '../../types/index.js';

	let {
		name = '',
		layout = 'v',
		checked = false,
		textPosition = 'r',
		icon = 'default',
		iconChecked = 'default',
		children,
		onclick
	}: CheckboxItemProps = $props();

	// 点击选项事件
	// Click option event
	const clickRadioFun = () => {
		onclick?.(name);
	};
</script>

<button
	onclick={() => clickRadioFun()}
	class="{layout === 'inline' ? 'inline-block' : 'flex'} grow active:opacity-80 {textPosition === 'l' && layout === 'v'
		? 'justify-between'
		: ''} {textPosition === 'b' || textPosition === 't' ? 'flex-col items-center' : layout === 'h' ? 'justify-center' : 'items-center'}"
>
	{#if textPosition === 'l' || textPosition === 't'}
		<div class="{textPosition === 'l' && icon !== null ? 'mr-0.5 text-left' : ''} {layout === 'v' ? 'grow' : ''}">
			{@render children?.()}
			{#if layout === 'v'}
				<div class="mt-1 h-px bg-black/10 dark:bg-white/10"></div>
			{/if}
		</div>
	{/if}
	<div class:hidden={!checked}>
		{#if iconChecked === null}{:else if iconChecked === 'default'}
			<Icon name="ri-checkbox-fill" theme top={textPosition === 't' || textPosition === 'b' ? 0 : -1} />
		{:else}
			<Icon {...iconChecked} theme />
		{/if}
	</div>
	<div class:hidden={checked}>
		{#if icon === null}{:else if icon === 'default'}
			<Icon name="ri-checkbox-line" alpha={0.2} top={textPosition === 't' || textPosition === 'b' ? 0 : -1} />
		{:else}
			<Icon alpha={0.2} {...icon} />
		{/if}
	</div>
	{#if textPosition === 'r' || textPosition === 'b'}
		<div class={textPosition === 'r' && icon !== null ? 'ml-0.5 text-left' : ''}>
			{@render children?.()}
		</div>
	{/if}
</button>



================================================
FILE: packages/stdf/src/lib/components/dialog/Dialog.svelte
================================================
<script lang="ts">
	import { getContext } from 'svelte';
	import Popup from '../popup/Popup.svelte';
	import Button from '../button/Button.svelte';
	import Icon from '../icon/Icon.svelte';
	import { zh_CN, type LangProps } from '../../lang/index.js';
	import type { DialogProps } from '../../types/index.js';

	// 当前语言
	// current language
	const currentLang = (getContext('STDF_lang') || zh_CN) as LangProps;
	const dialogLang: LangProps['dialog'] = currentLang.dialog;

	let {
		visible = $bindable(false),
		title = dialogLang.title,
		titleAlign = 'center',
		content = dialogLang.content,
		popup = {},
		showIcon = false,
		icon = {},
		btnStyle = 'button',
		primaryText = dialogLang.primaryText,
		primaryButton = {},
		secondaryText = dialogLang.secondaryText,
		secondaryButton = {},
		btnRatio = [1, 1],
		btnReverse = false,
		secondaryClose = true,
		btnGap = '2',
		onsecondary,
		onprimary,
		onclose,
		contentChild,
		primaryChild
	}: DialogProps = $props();

	// 标题对齐方式
	// Title alignment
	const titleAlignClass = { left: ' text-left', center: ' text-center', right: ' text-right' };

	// 按钮间距
	// Button spacing
	const btnGapClass = { '0': '', '1': ' gap-1', '2': ' gap-2', '4': ' gap-4', '8': ' gap-8', '12': ' gap-12', '16': ' gap-16' };
</script>

<Popup
	bind:visible
	size={0}
	maskClosable={false}
	duration={300}
	outDuration={150}
	position="center"
	radiusPosition="all"
	radius="lg"
	px="4"
	{...popup}
>
	<div class="px-4 pt-4{btnStyle === 'button' ? ' pb-2' : ''} space-y-4 text-center">
		<div class="font-bold{titleAlignClass[titleAlign] || titleAlignClass['center']}">{title}</div>
		{#if showIcon}
			<div><Icon {...icon} /></div>
		{/if}
		<div>
			{#if contentChild}
				{@render contentChild?.()}
			{:else}
				{content}
			{/if}
		</div>
		<div
			class="flex w-full{btnGapClass[btnGap] || btnGapClass['2']}{btnReverse ? ' flex-row-reverse' : ''}{btnStyle === 'textLine'
				? ' border-t border-black/10 dark:border-white/10'
				: ''}"
		>
			<div class={btnStyle === 'textLine' && !btnReverse ? 'border-r border-black/10 dark:border-white/10' : ''} style="flex:{btnRatio[1]}">
				<Button
					size="full"
					fill={btnStyle === 'button' ? 'colorLight' : 'text'}
					heightIn={btnStyle === 'button' ? '3' : '2'}
					injClass={btnStyle === 'button' ? '' : 'font-bold'}
					{...secondaryButton}
					onclick={() => {
						if (secondaryClose) {
							visible = false;
							onclose?.();
						}
						onsecondary?.();
					}}
				>
					{secondaryText}
				</Button>
			</div>
			<div class={btnStyle === 'textLine' && btnReverse ? 'border-r border-black/10 dark:border-white/10' : ''} style="flex:{btnRatio[0]}">
				<Button
					size="full"
					fill={btnStyle === 'button' ? 'base' : 'textTheme'}
					heightIn={btnStyle === 'button' ? '3' : '2'}
					injClass={btnStyle === 'button' ? '' : 'font-bold'}
					{...primaryButton}
					onclick={() => onprimary?.()}
				>
					{#if primaryChild}
						{@render primaryChild?.()}
					{:else}
						{primaryText}
					{/if}
				</Button>
			</div>
		</div>
	</div>
</Popup>



================================================
FILE: packages/stdf/src/lib/components/divider/Divider.svelte
================================================
<script lang="ts">
	import type { DividerProps } from '../../types/index.js';

	let {
		layout = 'h',
		px = '0',
		py = '4',
		text = '',
		align = 'center',
		line = 'solid',
		mx = '1',
		weight = '1',
		injClass = ''
	}: DividerProps = $props();

	// 水平间距样式
	// Horizontal spacing style
	const pxObj = { '0': 'px-0', '4': 'px-4', '8': 'px-8', '16': 'px-16', '36': 'px-36' };

	// 水平高度样式
	// Horizontal height style
	const pyObj = { '0': 'py-0', '4': 'py-4', '8': 'py-8' };

	// 垂直间距样式
	// Vertical spacing style
	const mxObj = { '1': 'm-1', '2': 'm-2', '4': 'm-4' };

	// 线条风格样式
	// Line style style
	const lineObj = { solid: 'border-solid', dashed: 'border-dashed', dotted: 'border-dotted' };

	// 线条粗细样式
	// Line thickness style
	const weightHObj = { '1': 'border-t', '2': 'border-t-2 rounded-full', '4': 'border-t-4 rounded-full' };

	// 线条粗细样式
	// Line thickness style
	const weightWObj = { '1': 'border-r', '2': 'border-r-2 rounded-full', '4': 'border-r-4 rounded-full' };
</script>

{#if layout === 'v'}
	<div
		class="inline {weightWObj[weight] || weightWObj['1']} border-black/10 dark:border-white/20 {mxObj[mx] || mxObj['1']} {lineObj[line] ||
			lineObj.solid} {injClass}"
	></div>
{:else}
	<div class="flex items-center {pxObj[px] || pxObj['0']} {pyObj[py] || pyObj['4']}">
		{#if (text !== '' && align !== 'left') || text === ''}
			<div
				class="grow {weightHObj[weight] || weightHObj['1']} border-black/10 dark:border-white/20 {lineObj[line] ||
					lineObj.solid} {injClass}"
			></div>
		{/if}
		{#if text !== ''}
			<div class="mx-2 flex-none text-xs text-gray-400 {injClass}">{text}</div>
		{/if}
		{#if (text !== '' && align !== 'right') || text === ''}
			<div
				class="grow {weightHObj[weight] || weightHObj['1']} border-black/10 dark:border-white/20 {lineObj[line] ||
					lineObj.solid} {injClass}"
			></div>
		{/if}
	</div>
{/if}



================================================
FILE: packages/stdf/src/lib/components/grids/Grid.svelte
================================================
<script lang="ts">
	import type { GridProps } from '../../types/index.js';

	let { col = '1', row = '1', children }: GridProps = $props();

	// 根据行数生成样式
	// Generate styles based on the number of rows
	const rowObj = { '1': 'row-span-1', '2': 'row-span-2', '3': 'row-span-3', '4': 'row-span-4', '5': 'row-span-5', '6': 'row-span-6' };

	// 根据列数生成样式
	// Generate styles based on the number of columns
	const colObj = {
		'1': ' col-span-1',
		'2': ' col-span-2',
		'3': ' col-span-3',
		'4': ' col-span-4',
		'5': ' col-span-5',
		'6': ' col-span-6',
		'7': ' col-span-7',
		'8': ' col-span-8',
		'9': ' col-span-9',
		'10': ' col-span-10',
		'11': ' col-span-11',
		'12': ' col-span-12'
	};
</script>

<div class="{rowObj[row] || rowObj['1']}{colObj[col] || colObj['1']}">
	{@render children?.()}
</div>



================================================
FILE: packages/stdf/src/lib/components/grids/Grids.svelte
================================================
<script lang="ts">
	import type { GridsProps } from '../../types/index.js';

	let { cols = '6', gap = '2', mx = '2', my = '2', children }: GridsProps = $props();

	//根据列数生成样式
	// Generate styles based on the number of columns
	const colsObj = {
		'1': ' grid-cols-1',
		'2': ' grid-cols-2',
		'3': ' grid-cols-3',
		'4': ' grid-cols-4',
		'5': ' grid-cols-5',
		'6': ' grid-cols-6',
		'7': ' grid-cols-7',
		'8': ' grid-cols-8',
		'9': ' grid-cols-9',
		'10': ' grid-cols-10',
		'11': ' grid-cols-11',
		'12': ' grid-cols-12'
	};

	//水平外边距样式
	// Horizontal margin style
	const mxObj = { '0': ' mx-0', '1': ' mx-1', '2': ' mx-2', '4': ' mx-4', '8': ' mx-8' };

	//垂直外边距样式
	// Vertical margin style
	const myObj = { '0': ' my-0', '1': ' my-1', '2': ' my-2', '4': ' my-4', '8': ' my-8' };

	//内部间距样式
	// Internal spacing style
	const gapObj = { '0': ' gap-0', '1': ' gap-1', '2': ' gap-2', '4': ' gap-4', '8': ' gap-8' };
</script>

<div class="grid{colsObj[cols] || colsObj['6']}{mxObj[mx] || mxObj['2']}{myObj[my] || myObj['2']}{gapObj[gap] || gapObj['2']}">
	{@render children?.()}
</div>



================================================
FILE: packages/stdf/src/lib/components/icon/Icon.svelte
================================================
<script lang="ts">
	import { getContext } from 'svelte';
	import type { IconProps } from '../../types/index.js';

	let {
		name = '',
		size = 24,
		theme = false,
		alpha = 1,
		path = getContext('STDF-global-icon-svg-path') || 'fonts/symbol.svg',
		top = 0,
		injClass = '',
		children
	}: IconProps = $props();
</script>

<i class="relative{theme ? ' text-primary dark:text-dark' : ''} {injClass}" style="top:{top}px;">
	{#if children}
		{@render children()}
	{:else}
		<svg width={size} height={size === 'full' ? '100%' : size} class="inline fill-current" style="fill-opacity: {alpha};">
			<use xlink:href="/{path}#{name}" />
		</svg>
	{/if}
</i>



================================================
FILE: packages/stdf/src/lib/components/indexBar/IndexBar.svelte
================================================
<script lang="ts">
	import { onMount } from 'svelte';
	import { fly } from 'svelte/transition';
	import { throttleWithRAF } from '../utils/index.js';
	import type { IndexBarProps } from '../../types/index.js';

	let {
		data = [],
		current = $bindable(0),
		top = 0,
		height = 100,
		radius = 'middle',
		scrollAlign = true,
		titleInjClass = '',
		textInjClass = '',
		onclickChild
	}: IndexBarProps = $props();

	// 用于绑定 bar 的高度
	// Used to bind the height of the bar
	let barHeight = $state(0);

	// 主体内容高度累计，用于监听滑动
	// The cumulative height of the main content is used to listen to the slide
	let longSumList: number[] = [];

	// 当前滑动的索引
	// Current sliding index
	let currentTouch = $state(-1);

	// 主体内容元素
	// Main body content element
	let bodyDom: HTMLElement | null = $state(null);

	// Bar 外层距离顶部的距离
	// Bar outside the distance from the top
	let barToTop = 0;

	// bar 元素
	// bar element
	let barDom: HTMLDivElement | null = $state(null);

	let isDown = false; //是否按下 is down

	// 每一个的高度
	// Height of each
	let itemHeight = $derived(barHeight / data.length);

	// 圆角风格样式
	// Rounded style style
	const radiusObj = { none: 'rounded-none', middle: 'rounded-sm', full: 'rounded-full' };

	onMount(() => {
		if (bodyDom) {
			bodyDom.scrollTop = 0;
		}
		for (let t = 0; t < data.length + 1; t++) {
			const long = data.slice(0, t).reduce((sum, current) => {
				return sum + (current?.height ?? 0);
			}, 0);
			longSumList.push(long);
		}
		//如果索引内容区域高度不够，中英文报错
		//If the index content area height is not enough, Chinese and English errors
		if (height < barHeight) {
			console.error('[STDF IndexBar error]注意：索引内容区域高度不够。(Note: The height of the index content area is not enough.)');
		}
		barToTop = top + (height - barHeight) / 2;
	});

	//bar区域滑动开始
	//Bar area sliding start
	const touchBoxStart = (e: PointerEvent) => {
		isDown = true;
		const clientY = e.clientY;
		currentTouch = Math.floor((clientY - barToTop) / itemHeight);
		current = Math.floor((clientY - barToTop) / itemHeight);
		if (bodyDom) {
			bodyDom.scrollTop = data.slice(0, current).reduce((sum, current) => {
				return sum + (current?.height ?? 0);
			}, 0);
		}
	};

	// bar 区域滑动中
	// bar area sliding in the middle
	const touchBoxMove = (e: PointerEvent) => {
		if (!isDown) {
			return;
		}
		if (barDom) {
			barDom.setPointerCapture(e.pointerId);
		}
		const clientY = e.clientY;
		currentTouch = Math.floor((clientY - barToTop) / itemHeight);
		current = Math.floor((clientY - barToTop) / itemHeight);
		if (clientY < barToTop) {
			currentTouch = 0;
			current = 0;
		}
		if (clientY > barHeight + barToTop) {
			currentTouch = data.length - 1;
			current = data.length - 1;
		}
		if (bodyDom) {
			bodyDom.scrollTop = data.slice(0, current).reduce((sum, current) => {
				return sum + (current?.height ?? 0);
			}, 0);
		}
	};

	// bar 区域滑动结束
	// bar area sliding end
	const touchBoxEnd = () => {
		currentTouch = -1;
		isDown = false;
	};

	//监听主体内容滚动
	//Listen to the main content scroll
	const scrollBody = () => {
		if (!bodyDom) {
			return;
		}
		const scrollTop = bodyDom.scrollTop + top;
		for (let w = 0; w < longSumList.length; w++) {
			if (scrollTop - top >= longSumList[w] && scrollTop - top < longSumList[w + 1]) {
				current = w;
			}
		}
	};
</script>

<div bind:this={bodyDom} class="overflow-y-auto {scrollAlign && 'snap-y'}" onscroll={scrollBody} style="height:{height}px;">
	{#each data as group, index}
		<div class="snap-start px-4 pt-8" bind:clientHeight={group.height}>
			<div class="text-primary dark:text-dark text-sm {titleInjClass}">{group.title}</div>
			{#each group.child as child, childIndex}
				<button class="w-full py-2 text-left {textInjClass}" onclick={() => onclickChild && onclickChild(index, group, childIndex, child)}>
					{child}
				</button>
				<div class="h-px bg-black/5 dark:bg-white/5"></div>
			{/each}
		</div>
	{/each}
</div>
<div
	onpointerdown={touchBoxStart}
	onpointermove={(e) => throttleWithRAF(touchBoxMove)(e)}
	onpointerup={touchBoxEnd}
	bind:clientHeight={barHeight}
	bind:this={barDom}
	class="fixed right-5 flex w-7 cursor-move touch-none select-none flex-col justify-around bg-black/5 p-1 dark:bg-white/5 {radiusObj[
		radius
	] || radiusObj.middle}"
	style="top:{top + (height - barHeight) / 2}px;min-height:{height / 4}px;"
>
	{#each data as group, i}
		<div class="relative flex flex-1 flex-col justify-center">
			<div
				class="h-5 w-5 text-center text-xs leading-5 transition-all {current === i
					? 'bg-primary dark:bg-dark text-white dark:text-black'
					: 'text-gray-600 dark:text-gray-400'} {radiusObj[radius] || radiusObj.middle}"
			>
				{group.index}
			</div>
			{#if currentTouch === i}
				<div
					class="border-primary text-primary dark:border-dark dark:text-dark absolute -left-24 top-1/2 h-14 w-14 -translate-y-2/4 border text-center text-3xl leading-[3.5rem] {radiusObj[
						radius
					] || radiusObj.middle}"
					transition:fly={{ x: 38, duration: 300 }}
				>
					{group.index}
				</div>
			{/if}
		</div>
	{/each}
</div>



================================================
FILE: packages/stdf/src/lib/components/input/Input.svelte
================================================
<script lang="ts">
	import { getContext } from 'svelte';
	import Icon from '../icon/Icon.svelte';
	import { zh_CN, type LangProps } from '../../lang/index.js';
	import type { InputProps } from '../../types/index.js';

	// 当前语言
	// current language
	const currentLang = (getContext('STDF_lang') || zh_CN) as LangProps;
	const inputLang: LangProps['input'] = currentLang.input;

	let {
		title = '',
		titlePosition = 'out',
		inputPosition = 'left',
		placeholder = '',
		radius = 'sm',
		label1 = null,
		label2 = null,
		label3 = null,
		label4 = null,
		label5 = null,
		label6 = null,
		tip = null,
		data1 = null,
		data2 = null,
		data3 = null,
		value = $bindable(''),
		clear = false,
		inputStyle = 'block',
		lineTransition = null,
		duration = 'base',
		autocomplete = true,
		py = '2',
		disabled = false,
		state: inputState = 'theme',
		type = 'text',
		inputmode = '',
		maxlength = 24,
		textareaMaxlength = 200,
		rows = 2,
		autosize = false,
		negative = false,
		onfocus,
		onblur,
		onchange,
		onclear,
		onclickLabel1,
		onclickLabel2,
		onclickLabel3,
		onclickLabel4,
		onclickLabel5,
		onclickLabel6,
		onkeydown,
		titleChild,
		data1Child,
		data2Child,
		data3Child,
		label1Child,
		label2Child,
		label3Child,
		label4Child,
		label5Child,
		label6Child,
		tipChild
	}: InputProps = $props();

	// 是否获取焦点
	// Whether to get focus
	let focus = $state(false);

	// 中文输入上屏标识
	// Chinese input screening flag
	let flag = true;

	//textarea 元素
	//textarea element
	let textareaDom: HTMLTextAreaElement | undefined = $state(undefined);

	// 输入模式判断
	// Input mode judgment
	const modeFun = (type: string) => {
		switch (type) {
			case 'password':
				return 'text';
			case 'number':
				return 'decimal';
			case 'textarea':
				return 'text';
			default:
				return type;
		}
	};

	// 输入框类型判断
	// Input box type judgment
	const mode = $derived(inputmode === '' ? modeFun(type) : inputmode);

	// 输入框类型判断
	// Input type judgment
	const typeAction = (node: HTMLInputElement | HTMLTextAreaElement) => {
		if (type !== 'textarea' && node instanceof HTMLInputElement) {
			node.type = type === 'password' ? 'password' : 'text';
		}
	};

	// 圆角风格样式
	// Corner style style
	const radiusObj = { none: 'rounded-none', sm: 'rounded-sm', xl: 'rounded-xl', '2xl': 'rounded-2xl', full: 'rounded-full' };

	// 输入框风格样式
	// Input box style style
	const inputStyleObj = {
		block: 'px-2 ring-2 ring-transparent bg-black/5 dark:bg-white/5 ' + radiusObj[radius] || radiusObj.sm,
		line: 'px-1 border-b bg-transparent border-gray-300 dark:border-gray-500'
	};

	// 状态样式
	// State style
	const stateObj = {
		theme: 'ring-primary dark:ring-dark',
		success: 'ring-success',
		warning: 'ring-warning',
		error: 'ring-error',
		info: 'ring-info'
	};

	// 根据是否获取焦点判断输入框样式
	// Determine the input box style according to whether to get focus
	const inputStyleFocusObj = $derived({
		block: 'px-2 ring-2 bg-transparent ' + stateObj[inputState] || stateObj.theme + radiusObj[radius] || radiusObj.sm,
		line: 'px-1 border-b bg-transparent border-gray-300 dark:border-gray-500'
	});

	// 线性动画样式
	// Linear animation style
	const lineTransitionStateObj = {
		theme: 'bg-primary dark:bg-dark ',
		success: 'bg-success',
		warning: 'bg-warning',
		error: 'bg-error',
		info: 'bg-info'
	};

	// 动画时长样式
	// Animation duration style
	const durationObj = { fast: 'duration-150', base: 'duration-300', slow: 'duration-500', slower: 'duration-1000' };

	// 垂直间距样式
	// Vertical spacing style
	const pyObj = { '0': 'py-0', '0.5': 'py-0.5', '1': 'py-1', '2': 'py-2', '3': 'py-3', '4': 'py-4', '6': 'py-6' };

	// 获取焦点是派发事件
	// Get focus to dispatch events
	const onFocus = () => {
		focus = true;
		onfocus?.(value);
	};

	// 失去焦点时派发事件
	// Dispatch events when focus is lost
	const onBlur = () => {
		focus = false;
		onblur?.(value);
	};

	// 输入内容变化时触发
	// Triggered when input content changes
	const valueChangeFun = (e: HTMLInputElement | HTMLTextAreaElement) => {
		//处理拼音输入时，内容上屏后才做校验
		//Handle pinyin input, content screening after validation
		setTimeout(function () {
			if (flag) {
				if (type === 'textarea' && autosize) {
					if (textareaDom) {
						textareaDom.style.height = textareaDom.scrollHeight + 'px';
					}
				}
				if (type === 'textarea' && e.value.length > textareaMaxlength) {
					//去除最后一个字符
					//Remove the last character
					e.value = e.value.substring(0, textareaMaxlength);
				}
				if (type !== 'textarea' && e.value.length > maxlength) {
					//去除最后一个字符
					//Remove the last character
					e.value = e.value.substring(0, maxlength);
				}
				if (type === 'decimal' || type === 'number') {
					// 数字
					// Number
					if (negative && e.value.startsWith('-')) {
						// 允许第一个字符为负号
						// Allow the first character to be a negative sign
						value =
							'-' +
							e.value
								.substring(1)
								.replace(/[^\d.]+/g, '')
								.replace(/\.{2,}/g, '.')
								.replace(/^(\d*\.\d*)\./, '$1');
					} else {
						// 不允许小数点开头且只允许一个小数点
						// Do not allow decimal points to start and only allow one decimal point
						value = e.value
							.replace(/[^\d.]+/g, '')
							.replace(/^\./, '')
							.replace(/\.{2,}/g, '.')
							.replace(/^(\d*\.\d*)\./, '$1');
					}
				} else if (type === 'numeric') {
					// 整数
					// Integer
					if (negative && e.value.startsWith('-')) {
						// 允许第一个字符为负号
						// Allow the first character to be a negative sign
						value = '-' + e.value.substring(1).replace(/[^\d]+/g, '');
					} else {
						value = e.value.replace(/[^\d]+/g, '');
					}
				} else {
					value = e.value;
				}
				onchange?.(value);
			}
		}, 0);
	};

	//拼音输入时，文字还未上屏触发
	//Triggered when the text has not been screened during pinyin input
	const compositionendFun = () => {
		flag = true;
	};

	//拼音输入时，文字完成上屏触发
	//Triggered when the text is completed during pinyin input
	const compositionstartFun = () => {
		flag = false;
	};

	//清除时触发
	//Triggered when cleared
	const clearFun = () => {
		value = '';
		onclear?.();
		onchange?.('');
	};

	// 键盘事件
	// Keyboard event
	const keydownFunc = (e: KeyboardEvent) => {
		// 派发事件，并传出按键的 key
		// Dispatch events and pass out the key of the key
		onkeydown?.(e.key);
	};
</script>

<div class="px-2 {pyObj[py] || pyObj['2']}">
	<label>
		<div class="flex px-2 {title === '' ? 'justify-end' : 'justify-between'}">
			{#if titlePosition === 'out'}
				{#if titleChild}
					{@render titleChild?.()}
				{:else if title === ''}{:else}
					<div class="mb-1 text-sm font-semibold">{title}</div>
				{/if}
			{/if}
			<div class="flex space-x-2 text-xs">
				{#if data1Child}
					{@render data1Child?.()}
				{:else if data1 === ''}{:else}
					{data1}
				{/if}
				{#if data2Child}
					{@render data2Child?.()}
				{:else if data2 === ''}{:else}
					{data2}
				{/if}
			</div>
		</div>
		<div
			class="relative my-0.5 flex items-center space-x-1 whitespace-nowrap text-sm transition-all {durationObj[duration] ||
				durationObj.base} {titlePosition === 'in' ? 'py-1' : 'py-3'} {focus
				? inputStyleFocusObj[inputStyle] || inputStyleFocusObj.block
				: inputStyleObj[inputStyle] || inputStyleObj.block} {inputStyle === 'block' ? radiusObj[radius] || radiusObj.sm : ''}"
		>
			{#if label1Child}
				{@render label1Child?.()}
			{:else if label1 === null}{:else}
				<button onclick={() => onclickLabel1 && onclickLabel1()}>
					<Icon {...label1} />
				</button>
			{/if}
			{#if label2Child}
				{@render label2Child?.()}
			{:else if label2 === null}{:else}
				<button onclick={() => onclickLabel2 && onclickLabel2()}>
					{label2}
				</button>
			{/if}
			{#if label3Child}
				{@render label3Child?.()}
			{:else if label3 === null}{:else}
				<button onclick={() => onclickLabel3 && onclickLabel3()}>
					<Icon {...label3} />
				</button>
			{/if}
			<div class="flex grow flex-col">
				{#if titlePosition === 'in'}
					<div class="text-xs text-gray-400">{title}</div>
				{/if}
				<div class="flex space-x-1">
					<div class="w-full">
						{#if type === 'textarea'}
							<textarea
								bind:value
								use:typeAction
								{rows}
								inputmode={mode as 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'email' | 'search' | 'url'}
								placeholder={placeholder !== '' ? placeholder : title !== '' ? inputLang.pleaseInput + ' ' + title : ''}
								class="focus:outline-hidden w-full bg-transparent font-semibold text-black dark:text-white {inputPosition === 'left'
									? 'text-left'
									: 'text-right'} {disabled ? 'cursor-not-allowed opacity-50' : ''}"
								onfocus={onFocus}
								onblur={() => onBlur()}
								oninput={(e) => valueChangeFun(e.currentTarget)}
								oncompositionend={compositionendFun}
								oncompositionstart={compositionstartFun}
								autocomplete={autocomplete === true ? 'on' : 'off'}
								{disabled}
								bind:this={textareaDom}
								onkeydown={keydownFunc}
							></textarea>
						{:else}
							<input
								bind:value
								use:typeAction
								inputmode={mode as 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'email' | 'search' | 'url'}
								placeholder={placeholder !== '' ? placeholder : title !== '' ? inputLang.pleaseInput + ' ' + title : ''}
								class="focus:outline-hidden w-full whitespace-normal bg-transparent font-semibold text-black dark:text-white {inputPosition ===
								'left'
									? 'text-left'
									: 'text-right'} {disabled ? 'cursor-not-allowed opacity-50' : ''}"
								onfocus={onFocus}
								onblur={() => onBlur()}
								oninput={(e) => valueChangeFun(e.currentTarget)}
								oncompositionend={compositionendFun}
								oncompositionstart={compositionstartFun}
								autocomplete={autocomplete === true ? 'on' : 'off'}
								{disabled}
								onkeydown={keydownFunc}
							/>
						{/if}
					</div>
					{#if clear && value !== ''}
						<button onclick={() => clearFun()}>
							<Icon name="ri-close-circle-fill" size={16} alpha={0.3} />
						</button>
					{/if}
				</div>
			</div>
			{#if label4Child}
				{@render label4Child?.()}
			{:else if label4 === null}{:else}
				<button onclick={() => onclickLabel4 && onclickLabel4()}>
					<Icon {...label4} />
				</button>
			{/if}
			{#if label5Child}
				{@render label5Child?.()}
			{:else if label5 === null}{:else}
				<button onclick={() => onclickLabel5 && onclickLabel5()}>
					{label5}
				</button>
			{/if}
			{#if label6Child}
				{@render label6Child?.()}
			{:else if label6 === null}{:else}
				<button onclick={() => onclickLabel6 && onclickLabel6()}>
					<Icon {...label6} />
				</button>
			{/if}
			{#if inputStyle === 'line'}
				<div
					class="absolute -bottom-px h-0.5 {lineTransition === null ? 'transition-colors' : 'transition-all'} {durationObj[duration] ||
						durationObj.base} {!focus && lineTransition === null && 'w-full bg-transparent'} {focus &&
						lineTransition === null &&
						`${lineTransitionStateObj[inputState] || lineTransitionStateObj.theme} w-full`} {!focus &&
						lineTransition !== null &&
						`w-0 ${lineTransitionStateObj[inputState] || lineTransitionStateObj.theme}`} {focus &&
						lineTransition !== null &&
						`w-full ${lineTransitionStateObj[inputState] || lineTransitionStateObj.theme}`}"
					style={lineTransition === 'center'
						? 'left:50%;transform:translateX(calc( -50% - 0.25rem ));-webkit-transform:translateX(calc( -50% - 0.25rem ));'
						: 'left:0;transform:translateX( -0.25rem );-webkit-transform:translateX( -0.25rem );'}
				></div>
			{/if}
		</div>
		<div class="flex px-2 {tip === null ? 'justify-end' : 'justify-between'}">
			{#if tipChild}
				{@render tipChild?.()}
			{:else if tip === null}{:else}
				<div class="text-xs text-gray-400">
					{tip}
				</div>
			{/if}
			{#if data3Child}
				{@render data3Child?.()}
			{:else if data3 === null}{:else}
				<div class="text-xs">
					{data3}
				</div>
			{/if}
		</div>
	</label>
</div>



================================================
FILE: packages/stdf/src/lib/components/loading/Loading.svelte
================================================
<script lang="ts">
	import { onMount } from 'svelte';
	import type { LoadingProps } from '../../types/index.js';
	import {
		Loading1_0,
		Loading1_1,
		Loading1_2,
		Loading1_3,
		Loading1_4,
		Loading1_5,
		Loading1_6,
		Loading1_7,
		Loading1_8,
		Loading1_9,
		Loading1_10,
		Loading1_11,
		Loading1_12,
		Loading1_13,
		Loading1_14,
		Loading1_15,
		Loading1_16,
		Loading1_17,
		Loading1_18,
		Loading1_19,
		Loading1_20,
		Loading1_21,
		Loading1_22,
		Loading1_23,
		Loading1_24,
		Loading1_25,
		Loading1_26,
		Loading1_27,
		Loading1_28,
		Loading1_29,
		Loading1_30,
		Loading1_31,
		Loading1_32,
		Loading1_33,
		Loading1_34,
		Loading1_35,
		Loading1_36,
		Loading1_37,
		Loading1_38,
		Loading1_39,
		Loading1_40,
		Loading1_41,
		Loading1_42,
		Loading1_43,
		Loading1_44,
		Loading1_45,
		Loading1_46,
		Loading1_47,
		Loading1_48,
		Loading1_49,
		Loading1_50,
		Loading1_51,
		Loading1_52,
		Loading1_53
	} from './loadings/oneColor/index.js';
	import { Loading2_0, Loading2_1, Loading2_2, Loading2_3, Loading2_4, Loading2_5 } from './loadings/twoColor/index.js';
	import { Loading4_0, Loading4_1, Loading4_2, Loading4_3 } from './loadings/fourColor/index.js';

	let {
		type = '1_0',
		height = '8',
		width = '8',
		theme = false,
		inverse = false,
		customColor = [],
		lazyAnimation = true,
		speed = $bindable(1)
	}: LoadingProps = $props();

	// loading 元素
	// loading element
	let loadingDom: HTMLDivElement | null = $state(null);

	// 容器高度样式
	// container height class
	const heightClass = {
		'2': 'h-2',
		'4': 'h-4',
		'6': 'h-6',
		'8': 'h-8',
		'12': 'h-12',
		'16': 'h-16',
		'20': 'h-20',
		'28': 'h-28',
		'36': 'h-36',
		'48': 'h-48',
		'56': 'h-56',
		'64': 'h-64',
		'72': 'h-72',
		'80': 'h-80',
		'96': 'h-96',
		full: 'h-full'
	};

	// 容器宽度样式
	// container width class
	const widthClass = {
		'2': 'w-2',
		'4': 'w-4',
		'6': 'w-6',
		'8': 'w-8',
		'12': 'w-12',
		'16': 'w-16',
		'20': 'w-20',
		'28': 'w-28',
		'36': 'w-36',
		'48': 'w-48',
		'56': 'w-56',
		'64': 'w-64',
		'72': 'w-72',
		'80': 'w-80',
		'96': 'w-96',
		full: 'w-full'
	};

	// 组合容器高度和宽度样式
	// combine container height and width class
	const sizeFunc = (height: string, width: string) => {
		return heightClass[height as keyof typeof heightClass] + ' ' + widthClass[width as keyof typeof widthClass];
	};

	// 递归获取 dom 的所有后代元素
	// recursively get all descendants of dom
	const getAllChildren = (dom: HTMLElement) => {
		let children: HTMLElement[] = [];
		if (dom?.children?.length) {
			for (let i = 0; i < dom.children.length; i++) {
				children.push(dom.children[i] as HTMLElement);
				children = children.concat(getAllChildren(dom.children[i] as HTMLElement));
			}
		}
		return children;
	};

	//判断 Loading 容器是否在可视区域内，如果不在，则设置所有后代元素的动画状态为 paused
	//determine whether the Loading container is in the visible area. If not, set the animation state of all descendants to paused
	const io = new IntersectionObserver((ele) => {
		ele.forEach((item) => {
			if (!loadingDom) return;
			const loadingChildren = getAllChildren(loadingDom);
			// isIntersecting 是一个 Boolean 值，判断目标元素当前是否可见
			// isIntersecting is a Boolean value that determines whether the target element is currently visible
			if (item.isIntersecting) {
				//loadingDom 所有后代元素的 animation-play-state 设置为 running
				//loadingDom all descendants of the element's animation-play-state set to running
				if (loadingChildren.length > 0) {
					loadingChildren.forEach((item: HTMLElement) => {
						item.style.animationPlayState = 'running';
					});
				}
			} else {
				//loadingDom 所有后代元素的 animation-play-state 设置为 paused
				//loadingDom all descendants of the element's animation-play-state set to paused
				if (loadingChildren.length > 0) {
					loadingChildren.forEach((item: HTMLElement) => {
						item.style.animationPlayState = 'paused';
					});
				}
			}
		});
	});
	onMount(() => {
		if (lazyAnimation && loadingDom) {
			io.observe(loadingDom);
		}
	});
</script>

<div bind:this={loadingDom}>
	<!--one-->
	{#if type === '1_0'}
		<Loading1_0 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_1'}
		<Loading1_1 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_2'}
		<Loading1_2 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_3'}
		<Loading1_3 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_4'}
		<Loading1_4 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_5'}
		<Loading1_5 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_6'}
		<Loading1_6 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_7'}
		<Loading1_7 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_8'}
		<Loading1_8 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_9'}
		<Loading1_9 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_10'}
		<Loading1_10 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_11'}
		<Loading1_11 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_12'}
		<Loading1_12 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_13'}
		<Loading1_13 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_14'}
		<Loading1_14 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_15'}
		<Loading1_15 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_16'}
		<Loading1_16 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_17'}
		<Loading1_17 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_18'}
		<Loading1_18 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_19'}
		<Loading1_19 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_20'}
		<Loading1_20 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_21'}
		<Loading1_21 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_22'}
		<Loading1_22 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_23'}
		<Loading1_23 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_24'}
		<Loading1_24 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_25'}
		<Loading1_25 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_26'}
		<Loading1_26 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_27'}
		<Loading1_27 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_28'}
		<Loading1_28 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_29'}
		<Loading1_29 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_30'}
		<Loading1_30 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_31'}
		<Loading1_31 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_32'}
		<Loading1_32 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_33'}
		<Loading1_33 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_34'}
		<Loading1_34 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_35'}
		<Loading1_35 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_36'}
		<Loading1_36 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_37'}
		<Loading1_37 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_38'}
		<Loading1_38 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_39'}
		<Loading1_39 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_40'}
		<Loading1_40 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_41'}
		<Loading1_41 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_42'}
		<Loading1_42 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_43'}
		<Loading1_43 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_44'}
		<Loading1_44 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_45'}
		<Loading1_45 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_46'}
		<Loading1_46 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_47'}
		<Loading1_47 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_48'}
		<Loading1_48 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_49'}
		<Loading1_49 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_50'}
		<Loading1_50 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_51'}
		<Loading1_51 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_52'}
		<Loading1_52 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '1_53'}
		<Loading1_53 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />

		<!--twoColor-->
	{:else if type === '2_0'}
		<Loading2_0 {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '2_1'}<Loading2_1 {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '2_2'}<Loading2_2 {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '2_3'}<Loading2_3 {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '2_4'}<Loading2_4 {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '2_5'}<Loading2_5 {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />

		<!--fourColor-->
	{:else if type === '4_0'}
		<Loading4_0 size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '4_1'}
		<Loading4_1 size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '4_2'}
		<Loading4_2 size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else if type === '4_3'}
		<Loading4_3 size={sizeFunc(height, width)} {customColor} bind:speed />
	{:else}
		<Loading1_0 {theme} {inverse} size={sizeFunc(height, width)} {customColor} bind:speed />
	{/if}
</div>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/fourColor/4_0.svelte
================================================
<script lang="ts">
	type Props = { size?: string; customColor?: string[]; speed?: number };

	let { size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();
</script>

<div
	class="{size} loading m-auto rounded-full border-4"
	style="border-color: {customColor[0] || '#DA1414'} {customColor[1] || '#11BB8D'} {customColor[2] || '#7356BF'} {customColor[3] ||
		'#FFC043'};animation-duration: {2 / speed}s;-webkit-animation-duration: {2 / speed}s;"
></div>

<style>
	.loading {
		animation: loading-animation 2s ease-in-out infinite alternate;
	}

	@keyframes loading-animation {
		from {
			transform: rotate(0deg);
		}

		to {
			transform: rotate(720deg);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/fourColor/4_1.svelte
================================================
<script lang="ts">
	type Props = { size?: string; customColor?: string[]; speed?: number };

	let { size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();
</script>

<div class="{size} relative m-auto rotate-45">
	<div
		class="shape1 absolute left-0 top-0 h-1/3 w-1/3"
		style="background: {customColor[0] || '#DA1414'};animation-duration: {0.5 / speed}s;-webkit-animation-duration: {0.5 / speed}s;"
	></div>
	<div
		class="shape2 absolute right-0 top-0 h-1/3 w-1/3"
		style="background: {customColor[1] || '#11BB8D'};animation-duration: {0.5 / speed}s;-webkit-animation-duration: {0.5 / speed}s;"
	></div>
	<div
		class="shape3 absolute bottom-0 right-0 h-1/3 w-1/3"
		style="background: {customColor[2] || '#7356BF'};animation-duration: {0.5 / speed}s;-webkit-animation-duration: {0.5 / speed}s;"
	></div>
	<div
		class="shape4 absolute bottom-0 left-0 h-1/3 w-1/3"
		style="background: {customColor[3] || '#FFC043'};animation-duration: {0.5 / speed}s;-webkit-animation-duration: {0.5 / speed}s;"
	></div>
</div>

<style>
	.shape1 {
		animation: animationShape1 0.5s ease infinite alternate;
	}

	.shape2 {
		animation: animationShape2 0.5s ease infinite alternate;
	}

	.shape3 {
		animation: animationShape3 0.5s ease infinite alternate;
	}

	.shape4 {
		animation: animationShape4 0.5s ease infinite alternate;
	}

	@keyframes animationShape1 {
		0% {
			transform: translate(0, 0);
		}

		100% {
			transform: translate(16px, 16px);
		}
	}

	@keyframes animationShape2 {
		0% {
			transform: translate(0, 0);
		}

		100% {
			transform: translate(-16px, 16px);
		}
	}

	@keyframes animationShape3 {
		0% {
			transform: translate(0, 0);
		}

		100% {
			transform: translate(-16px, -16px);
		}
	}

	@keyframes animationShape4 {
		0% {
			transform: translate(0, 0);
		}

		100% {
			transform: translate(16px, -16px);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/fourColor/4_2.svelte
================================================
<script lang="ts">
	type Props = { size?: string; customColor?: string[]; speed?: number };

	let { size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();
</script>

<div class="{size} loading relative m-auto" style="animation-duration: {1.6 / speed}s;-webkit-animation-duration: {1.6 / speed}s;">
	<div
		class="shape1 absolute h-1/3 w-1/3 rounded-full"
		style="background: {customColor[0] || '#DA1414'};animation-duration: {0.8 / speed}s;-webkit-animation-duration: {0.8 / speed}s;"
	></div>
	<div
		class="shape2 absolute h-1/3 w-1/3 rounded-full"
		style="background: {customColor[1] || '#11BB8D'};animation-duration: {0.8 / speed}s;-webkit-animation-duration: {0.8 / speed}s;"
	></div>
	<div
		class="shape3 absolute h-1/3 w-1/3 rounded-full"
		style="background: {customColor[2] || '#7356BF'};animation-duration: {0.8 / speed}s;-webkit-animation-duration: {0.8 / speed}s;"
	></div>
	<div
		class="shape4 absolute h-1/3 w-1/3 rounded-full"
		style="background: {customColor[3] || '#FFC043'};animation-duration: {0.8 / speed}s;-webkit-animation-duration: {0.8 / speed}s;"
	></div>
</div>

<style>
	.loading {
		animation: animationContainer 1.6s ease infinite;
	}
	.shape1 {
		animation: animationShape1 0.8s ease infinite alternate;
	}

	.shape2 {
		animation: animationShape2 0.8s ease infinite alternate;
	}

	.shape3 {
		animation: animationShape3 0.8s ease infinite alternate;
	}

	.shape4 {
		animation: animationShape4 0.8s ease infinite alternate;
	}

	@keyframes animationContainer {
		0% {
			transform: rotate(0);
		}

		100% {
			transform: rotate(360deg);
		}
	}

	@keyframes animationShape1 {
		0% {
			top: 0;
			left: 0;
		}
		100% {
			top: 66.6666666667%;
			left: 66.6666666667%;
		}
	}

	@keyframes animationShape2 {
		0% {
			top: 0;
			left: 66.6666666667%;
		}
		100% {
			top: 66.6666666667%;
			left: 0;
		}
	}

	@keyframes animationShape3 {
		0% {
			top: 66.6666666667%;
			left: 66.6666666667%;
		}
		100% {
			top: 0;
			left: 0;
		}
	}

	@keyframes animationShape4 {
		0% {
			top: 66.6666666667%;
			left: 0;
		}
		100% {
			top: 0;
			left: 66.6666666667%;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/fourColor/4_3.svelte
================================================
<script lang="ts">
	type Props = { size?: string; customColor?: string[]; speed?: number };

	let { size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();
</script>

<div class="{size} loading relative m-auto" style="animation-duration: {1.2 / speed}s;-webkit-animation-duration: {1.2 / speed}s;">
	<div
		class="shape1 absolute h-1/2 w-1/2 rounded-tl-full"
		style="background: {customColor[0] || '#DA1414'};animation-duration: {0.6 / speed}s;-webkit-animation-duration: {0.6 / speed}s;"
	></div>
	<div
		class="shape2 absolute h-1/2 w-1/2 rounded-tr-full"
		style="background: {customColor[1] || '#11BB8D'};animation-duration: {0.6 / speed}s;-webkit-animation-duration: {0.6 / speed}s;"
	></div>
	<div
		class="shape3 absolute h-1/2 w-1/2 rounded-br-full"
		style="background: {customColor[2] || '#7356BF'};animation-duration: {0.6 / speed}s;-webkit-animation-duration: {0.6 / speed}s;"
	></div>
	<div
		class="shape4 absolute h-1/2 w-1/2 rounded-bl-full"
		style="background: {customColor[3] || '#FFC043'};animation-duration: {0.6 / speed}s;-webkit-animation-duration: {0.6 / speed}s;"
	></div>
</div>

<style>
	.loading {
		animation: animationContainer 1.2s ease infinite;
	}
	.shape1 {
		animation: animationShape1 0.6s ease infinite alternate;
	}

	.shape2 {
		animation: animationShape2 0.6s ease infinite alternate;
	}

	.shape3 {
		animation: animationShape3 0.6s ease infinite alternate;
	}

	.shape4 {
		animation: animationShape4 0.6s ease infinite alternate;
	}

	@keyframes animationContainer {
		0% {
			transform: rotate(0);
		}

		100% {
			transform: rotate(360deg);
		}
	}
	@keyframes animationShape1 {
		0% {
			top: 0;
			left: 0;
		}
		100% {
			top: -10%;
			left: -10%;
		}
	}

	@keyframes animationShape2 {
		0% {
			top: 0;
			left: 50%;
		}
		100% {
			top: -10%;
			left: 60%;
		}
	}

	@keyframes animationShape3 {
		0% {
			top: 50%;
			left: 50%;
		}
		100% {
			top: 60%;
			left: 60%;
		}
	}

	@keyframes animationShape4 {
		0% {
			top: 50%;
			left: 0;
		}
		100% {
			top: 60%;
			left: -10%;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/fourColor/index.ts
================================================
export { default as Loading4_0 } from './4_0.svelte';
export { default as Loading4_1 } from './4_1.svelte';
export { default as Loading4_2 } from './4_2.svelte';
export { default as Loading4_3 } from './4_3.svelte';



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_0.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: string[]; speed?: number };

	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' text-dark dark:text-primary' : ' text-white dark:text-black';
		} else {
			return theme ? ' text-primary dark:text-dark' : ' text-black dark:text-white';
		}
	};
</script>

<div class="{size} m-auto">
	<svg
		viewBox="0 0 24 24"
		class="animate-spin{colorClass()}"
		style="color: {customColor[0]};animation-duration: {1 / speed}s;-webkit-animation-duration: {1 / speed}s;"
	>
		<circle cx="12" cy="12" r="10" stroke-width="4" fill="none" class="opacity-5" stroke="currentColor" />
		<circle
			cx="12"
			cy="12"
			r="10"
			stroke-width="4"
			class="opacity-80"
			stroke="currentColor"
			fill="none"
			stroke-dashoffset="46.07669455648491"
			stroke-dasharray="69.11503837897544"
			stroke-linecap="round"
		/>
	</svg>
</div>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_1.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: string[]; speed?: number };

	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' border-dark dark:border-primary' : ' border-white dark:border-black';
		} else {
			return theme ? ' border-primary dark:border-dark' : ' border-black dark:border-white';
		}
	};
</script>

<div
	class="{size} m-auto border-2{colorClass()} animate-spin rounded-full border-t-transparent dark:border-t-transparent"
	style="border-color: {customColor[0]};border-top-color:transparent;animation-duration: {1 / speed}s;-webkit-animation-duration: {1 /
		speed}s;"
></div>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_10.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} m-auto flex items-center justify-between">
	{#each [0, 1, 2] as i}
		<div
			class="{colorClass()} loading h-2 w-2 rounded-full"
			style="animation-delay: {i === 1 ? -0.3 : 0}s;background: {customColor[0]};animation-duration: {1 /
				speed}s;-webkit-animation-duration: {1 / speed}s;"
		></div>
	{/each}
</div>

<style>
	.loading {
		animation: loading 1s infinite linear;
	}

	@keyframes loading {
		50% {
			opacity: 0.2;
			transform: scale(0.75);
		}
		100% {
			opacity: 1;
			transform: scale(1.2);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_11.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} relative m-auto">
	{#each [0, 1, 2, 3, 4] as i}
		<div
			class="absolute -left-1/2 top-1/4{colorClass()} loading h-4 w-4 rounded-full opacity-60"
			style="animation-delay: {-0.5 * i}s, {-0.5 * (i + 1)}s;top:calc(5);background: {customColor[0]};animation-duration: {2.5 /
				speed}s;-webkit-animation-duration: {2.5 / speed}s;"
		></div>
	{/each}
</div>

<style>
	.loading {
		animation:
			loading1 2.5s infinite cubic-bezier(0.25, 0, 0.75, 1),
			loading2 2.5s infinite cubic-bezier(0.25, 0, 0.75, 1);
	}

	@keyframes loading1 {
		50% {
			left: 100%;
		}
	}

	@keyframes loading2 {
		50% {
			transform: scale(0.3, 0.3);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_12.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} loading relative m-auto box-border">
	<div
		class="absolute{colorClass()} ball rounded-full"
		style="background: {customColor[0]};animation-duration: {speed >= 1 ? 0.6 / speed : 0.6}s;-webkit-animation-duration: {speed >= 1
			? 0.6 / speed
			: 0.6}s;"
	></div>
	<div
		class="absolute top-0 right-0{colorClass()} steps step1"
		style="background: {customColor[0]};animation-duration: {speed >= 1 ? 1.8 / speed : 1.8}s;-webkit-animation-duration: {speed >= 1
			? 1.8 / speed
			: 1.8}s;"
	></div>
	<div
		class="absolute top-0 right-0{colorClass()} steps step2"
		style="background: {customColor[0]};animation-duration: {speed >= 1 ? 1.8 / speed : 1.8}s;-webkit-animation-duration: {speed >= 1
			? 1.8 / speed
			: 1.8}s;"
	></div>
	<div
		class="absolute top-0 right-0{colorClass()} steps step3"
		style="background: {customColor[0]};animation-duration: {speed >= 1 ? 1.8 / speed : 1.8}s;-webkit-animation-duration: {speed >= 1
			? 1.8 / speed
			: 1.8}s;"
	></div>
</div>

<style>
	.loading {
		width: 42px;
		height: 32px;
	}

	.ball {
		bottom: 32%;
		left: 18%;
		width: 14px;
		height: 14px;
		transform-origin: center bottom;
		animation: ball-climbing-dot-jump 0.6s ease-in-out infinite;
	}

	.steps {
		width: 14px;
		height: 2px;
		transform: translate(60%, 0);
		animation: ball-climbing-dot-steps 1.8s linear infinite;
	}

	.step1 {
		animation-delay: 0ms;
	}

	.step2 {
		animation-delay: -600ms;
	}

	.step3 {
		animation-delay: -1200ms;
	}

	@keyframes ball-climbing-dot-jump {
		0% {
			transform: scale(1, 0.8);
		}

		20% {
			transform: scale(0.8, 1.1);
		}

		40% {
			transform: scale(1, 1);
		}

		50% {
			bottom: 125%;
		}

		46% {
			transform: scale(1, 1);
		}

		80% {
			transform: scale(0.8, 1.1);
		}

		90% {
			transform: scale(0.8, 1.1);
		}

		100% {
			transform: scale(1, 0.8);
		}
	}

	@keyframes ball-climbing-dot-steps {
		0% {
			top: 0;
			right: 0;
			opacity: 0;
		}

		50% {
			opacity: 1;
		}

		100% {
			top: 100%;
			right: 100%;
			opacity: 0;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_13.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' border-dark dark:border-primary' : ' border-white dark:border-black';
		} else {
			return theme ? ' border-primary dark:border-dark' : ' border-black dark:border-white';
		}
	};
</script>

<div class="{size} relative m-auto box-border">
	<div
		class="absolute left-1/2 top-1/2 {size} m-auto border-2 !border-l-transparent !border-r-transparent rounded-full{colorClass()} loading"
		style="border-color: {customColor[0]};animation-duration: {1.5 / speed}s;-webkit-animation-duration: {1.5 / speed}s;"
	></div>
	<div
		class="absolute left-1/2 top-1/2 m-auto h-1/2 w-1/2 border-2 !border-b-transparent !border-t-transparent rounded-full{colorClass()} loading"
		style="animation-direction: reverse;border-color: {customColor[0]};animation-duration: {1.5 / speed}s;-webkit-animation-duration: {1.5 /
			speed}s;"
	></div>
</div>

<style>
	.loading {
		animation: ball-clip-rotate-multiple-rotate 1.5s ease-in-out infinite;
	}

	@keyframes ball-clip-rotate-multiple-rotate {
		0% {
			transform: translate(-50%, -50%) rotate(0deg);
		}

		50% {
			transform: translate(-50%, -50%) rotate(180deg);
		}

		100% {
			transform: translate(-50%, -50%) rotate(360deg);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_14.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const borderClass = () => {
		if (inverse) {
			return theme ? ' border-dark dark:border-primary' : ' border-white dark:border-black';
		} else {
			return theme ? ' border-primary dark:border-dark' : ' border-black dark:border-white';
		}
	};
	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} relative m-auto">
	<div
		class="absolute h-full w-full border-2 !border-l-transparent !border-r-transparent rounded-full{borderClass()} loading1"
		style="border-color: {customColor[0]};animation-duration: {1 / speed}s;-webkit-animation-duration: {1 / speed}s;"
	></div>
	<div
		class="absolute left-1/4 top-1/4 h-1/2 w-1/2 rounded-full{colorClass()} loading2"
		style="background: {customColor[0]};animation-duration: {1 / speed}s;-webkit-animation-duration: {1 / speed}s;"
	></div>
</div>

<style>
	.loading1 {
		animation: ball-clip-rotate-multiple-rotate 1s ease-in-out infinite;
	}

	.loading2 {
		animation: ball-clip-rotate-pulse-scale 1s cubic-bezier(0.09, 0.57, 0.49, 0.9) infinite;
	}

	@keyframes ball-clip-rotate-multiple-rotate {
		0% {
			transform: rotate(0deg);
		}

		50% {
			transform: rotate(180deg);
		}

		100% {
			transform: rotate(360deg);
		}
	}

	@keyframes ball-clip-rotate-pulse-scale {
		0%,
		100% {
			opacity: 1;
			transform: scale(1);
		}

		30% {
			opacity: 0.3;
			transform: scale(0.15);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_15.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: string[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} relative m-auto">
	<div
		class="absolute{colorClass()} loading1 top-1/2 h-1/4 w-1/4 rounded-full"
		style="left:0;background: {customColor[0]};animation-duration: {1 / speed}s;-webkit-animation-duration: {1 / speed}s;"
	></div>
	<div
		class="absolute{colorClass()} loading2 top-1/2 h-1/4 w-1/4 rounded-full"
		style="left:25%;background: {customColor[0]};animation-duration: {1 / speed}s;-webkit-animation-duration: {1 / speed}s;"
	></div>
	<div
		class="absolute{colorClass()} loading3 top-1/2 h-1/4 w-1/4 rounded-full"
		style="left:50%;background: {customColor[0]};animation-duration: {1 / speed}s;-webkit-animation-duration: {1 / speed}s;"
	></div>
	<div
		class="absolute{colorClass()} loading4 top-1/2 h-1/4 w-1/4 rounded-full"
		style="left:75%;background: {customColor[0]};animation-duration: {1 / speed}s;-webkit-animation-duration: {1 / speed}s;"
	></div>
	<div
		class="absolute{colorClass()} loading5 top-1/2 h-1/4 w-1/4 rounded-full"
		style="left:100%;background: {customColor[0]};animation-duration: {1 / speed}s;-webkit-animation-duration: {1 / speed}s;"
	></div>
</div>

<style>
	.loading1 {
		animation: ball-elastic-dots-anim1 1s infinite;
	}

	.loading2 {
		animation: ball-elastic-dots-anim2 1s infinite;
	}

	.loading3 {
		animation: ball-elastic-dots-anim3 1s infinite;
	}

	.loading4 {
		animation: ball-elastic-dots-anim4 1s infinite;
	}

	.loading5 {
		animation: ball-elastic-dots-anim5 1s infinite;
	}

	@keyframes ball-elastic-dots-anim1 {
		0%,
		100% {
			left: 0;
			transform: translateX(-50%) translateY(-50%) scale(1);
		}

		50% {
			left: -50%;
			transform: translateX(-50%) translateY(-50%) scale(0.67);
		}
	}

	@keyframes ball-elastic-dots-anim2 {
		0%,
		100% {
			left: 25%;
			transform: translateX(-50%) translateY(-50%) scale(1);
		}

		50% {
			left: 0%;
			transform: translateX(-50%) translateY(-50%) scale(0.67);
		}
	}

	@keyframes ball-elastic-dots-anim3 {
		0%,
		100% {
			left: 50%;
			transform: translateX(-50%) translateY(-50%) scale(1);
		}

		50% {
			left: 50%;
			transform: translateX(-50%) translateY(-50%) scale(0.67);
		}
	}

	@keyframes ball-elastic-dots-anim4 {
		0%,
		100% {
			left: 75%;
			transform: translateX(-50%) translateY(-50%) scale(1);
		}

		50% {
			left: 100%;
			transform: translateX(-50%) translateY(-50%) scale(0.67);
		}
	}

	@keyframes ball-elastic-dots-anim5 {
		0%,
		100% {
			left: 100%;
			transform: translateX(-50%) translateY(-50%) scale(1);
		}

		50% {
			left: 150%;
			transform: translateX(-50%) translateY(-50%) scale(0.67);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_16.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} m-auto flex items-center justify-between">
	{#each [0, 1, 2] as i}
		<div
			class="{colorClass()} loading h-2 w-2 rounded-full"
			style="animation-delay: {i * 100 - 300}ms;background: {customColor[0]};animation-duration: {1 /
				speed}s;-webkit-animation-duration: {1 / speed}s;"
		></div>
	{/each}
</div>

<style>
	.loading {
		animation: ball-fall 1s ease-in-out infinite;
	}

	@keyframes ball-fall {
		0% {
			opacity: 0;
			transform: translateY(-145%);
		}

		10% {
			opacity: 0.5;
		}

		20% {
			opacity: 1;
			transform: translateY(0);
		}

		80% {
			opacity: 1;
			transform: translateY(0);
		}

		90% {
			opacity: 0.5;
		}

		100% {
			opacity: 0;
			transform: translateY(145%);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_17.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} m-auto flex items-center justify-between">
	{#each [0, 1, 2] as i}
		<div
			class="{colorClass()} loading h-2 w-2 rounded-full"
			style="animation-delay: {i * 100 - 300}ms;background: {customColor[0]};animation-duration: {1 /
				speed}s;-webkit-animation-duration: {1 / speed}s;"
		></div>
	{/each}
</div>

<style>
	.loading {
		animation: ball-pulse 1s ease infinite;
	}

	@keyframes ball-pulse {
		0%,
		60%,
		100% {
			opacity: 1;
			transform: scale(1);
		}

		30% {
			opacity: 0.1;
			transform: scale(0.1);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_18.svelte
================================================
<script lang="ts">
	type Props = { size?: string; customColor?: any[]; speed?: number; theme?: boolean; inverse?: boolean };
	let { size = 'w-8 h-8', customColor = [], speed = $bindable(1), theme = false, inverse = false }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} relative m-auto rotate-45">
	<div
		class="shape1 absolute left-0 top-0 h-1/3 w-1/3 {colorClass()}"
		style="background: {customColor[0]};animation-duration: {0.5 / speed}s;-webkit-animation-duration: {0.5 / speed}s;"
	></div>
	<div
		class="shape2 absolute right-0 top-0 h-1/3 w-1/3 {colorClass()}"
		style="background: {customColor[0]};animation-duration: {0.5 / speed}s;-webkit-animation-duration: {0.5 / speed}s;"
	></div>
	<div
		class="shape3 absolute bottom-0 right-0 h-1/3 w-1/3 {colorClass()}"
		style="background: {customColor[0]};animation-duration: {0.5 / speed}s;-webkit-animation-duration: {0.5 / speed}s;"
	></div>
	<div
		class="shape4 absolute bottom-0 left-0 h-1/3 w-1/3 {colorClass()}"
		style="background: {customColor[0]};animation-duration: {0.5 / speed}s;-webkit-animation-duration: {0.5 / speed}s;"
	></div>
</div>

<style>
	.shape1 {
		animation: animationShape1 0.5s ease infinite alternate;
	}

	.shape2 {
		animation: animationShape2 0.5s ease infinite alternate;
	}

	.shape3 {
		animation: animationShape3 0.5s ease infinite alternate;
	}

	.shape4 {
		animation: animationShape4 0.5s ease infinite alternate;
	}

	@keyframes animationShape1 {
		0% {
			transform: translate(0, 0);
		}

		100% {
			transform: translate(16px, 16px);
		}
	}

	@keyframes animationShape2 {
		0% {
			transform: translate(0, 0);
		}

		100% {
			transform: translate(-16px, 16px);
		}
	}

	@keyframes animationShape3 {
		0% {
			transform: translate(0, 0);
		}

		100% {
			transform: translate(-16px, -16px);
		}
	}

	@keyframes animationShape4 {
		0% {
			transform: translate(0, 0);
		}

		100% {
			transform: translate(16px, -16px);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_19.svelte
================================================
<script lang="ts">
	type Props = { size?: string; customColor?: any[]; speed?: number; theme?: boolean; inverse?: boolean };
	let { size = 'w-8 h-8', customColor = [], speed = $bindable(1), theme = false, inverse = false }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} loading relative m-auto" style="animation-duration: {1.6 / speed}s;-webkit-animation-duration: {1.6 / speed}s;">
	<div
		class="shape1 absolute h-1/3 w-1/3 rounded-full {colorClass()}"
		style="background: {customColor[0]};animation-duration: {0.8 / speed}s;-webkit-animation-duration: {0.8 / speed}s;"
	></div>
	<div
		class="shape2 absolute h-1/3 w-1/3 rounded-full {colorClass()}"
		style="background: {customColor[0]};animation-duration: {0.8 / speed}s;-webkit-animation-duration: {0.8 / speed}s;"
	></div>
	<div
		class="shape3 absolute h-1/3 w-1/3 rounded-full {colorClass()}"
		style="background: {customColor[0]};animation-duration: {0.8 / speed}s;-webkit-animation-duration: {0.8 / speed}s;"
	></div>
	<div
		class="shape4 absolute h-1/3 w-1/3 rounded-full {colorClass()}"
		style="background: {customColor[0]};animation-duration: {0.8 / speed}s;-webkit-animation-duration: {0.8 / speed}s;"
	></div>
</div>

<style>
	.loading {
		animation: animationContainer 1.6s ease infinite;
	}
	.shape1 {
		animation: animationShape1 0.8s ease infinite alternate;
	}

	.shape2 {
		animation: animationShape2 0.8s ease infinite alternate;
	}

	.shape3 {
		animation: animationShape3 0.8s ease infinite alternate;
	}

	.shape4 {
		animation: animationShape4 0.8s ease infinite alternate;
	}

	@keyframes animationContainer {
		0% {
			transform: rotate(0);
		}

		100% {
			transform: rotate(360deg);
		}
	}

	@keyframes animationShape1 {
		0% {
			top: 0;
			left: 0;
		}
		100% {
			top: 66.6666666667%;
			left: 66.6666666667%;
		}
	}

	@keyframes animationShape2 {
		0% {
			top: 0;
			left: 66.6666666667%;
		}
		100% {
			top: 66.6666666667%;
			left: 0;
		}
	}

	@keyframes animationShape3 {
		0% {
			top: 66.6666666667%;
			left: 66.6666666667%;
		}
		100% {
			top: 0;
			left: 0;
		}
	}

	@keyframes animationShape4 {
		0% {
			top: 66.6666666667%;
			left: 0;
		}
		100% {
			top: 0;
			left: 66.6666666667%;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_2.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: string[]; speed?: number };

	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme
				? ' border-dark/5 border-l-dark/[1] dark:border-primary/5 dark:border-l-primary/[1]'
				: ' border-white/5 border-l-white/[1] dark:border-black/5 dark:border-l-black/[1]';
		} else {
			return theme
				? ' border-primary/5 border-l-primary/[1] dark:border-dark/5 dark:border-l-dark/[1]'
				: ' border-black/5 border-l-black/[1] dark:border-white/5 dark:border-l-white/[1]';
		}
	};
</script>

<div
	class="{size} m-auto animate-spin rounded-full border-2 {colorClass()}"
	style="border-color:{customColor[0] + '0D'};border-left-color:{customColor[0] + 'FF'};animation-duration: {1 /
		speed}s;-webkit-animation-duration: {1 / speed}s;"
></div>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_20.svelte
================================================
<script lang="ts">
	type Props = { size?: string; customColor?: any[]; speed?: number; theme?: boolean; inverse?: boolean };
	let { size = 'w-8 h-8', customColor = [], speed = $bindable(1), theme = false, inverse = false }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme
				? ' border-dark/5 border-l-dark/[1] dark:border-primary/5 dark:border-l-primary/[1] border-r-dark/[1] dark:border-r-primary/[1]'
				: ' border-white/5 border-l-white/[1] dark:border-black/5 dark:border-l-black/[1] border-r-white/[1] dark:border-r-black/[1]';
		} else {
			return theme
				? ' border-primary/5 dark:border-dark/5 border-l-primary/[1] dark:border-l-dark/[1] border-r-primary/[1] dark:border-r-dark/[1]'
				: ' border-black/5 dark:border-white/5 border-l-black/[1] dark:border-l-white/[1] border-r-black/[1] dark:border-r-white/[1]';
		}
	};
</script>

<div
	class="{size} loading m-auto rounded-full border-4 {colorClass()}"
	style="border-color: {customColor[0] + '0D'} {customColor[0] + 'FF'} {customColor[0] + '0D'} {customColor[0] +
		'FF'};animation-duration: {2 / speed}s;-webkit-animation-duration: {2 / speed}s;"
></div>

<style>
	.loading {
		animation: loading-animation 2s ease-in-out infinite alternate;
	}

	@keyframes loading-animation {
		from {
			transform: rotate(0deg);
		}

		to {
			transform: rotate(720deg);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_21.svelte
================================================
<script lang="ts">
	type Props = { size?: string; customColor?: any[]; speed?: number; theme?: boolean; inverse?: boolean };
	let { size = 'w-8 h-8', customColor = [], speed = $bindable(1), theme = false, inverse = false }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} loading relative m-auto" style="animation-duration: {1.2 / speed}s;-webkit-animation-duration: {1.2 / speed}s;">
	<div
		class="shape1 absolute h-1/2 w-1/2 rounded-tl-full {colorClass()}"
		style="background: {customColor[0]};animation-duration: {0.6 / speed}s;-webkit-animation-duration: {0.6 / speed}s;"
	></div>
	<div
		class="shape2 absolute h-1/2 w-1/2 rounded-tr-full {colorClass()}"
		style="background: {customColor[0]};animation-duration: {0.6 / speed}s;-webkit-animation-duration: {0.6 / speed}s;"
	></div>
	<div
		class="shape3 absolute h-1/2 w-1/2 rounded-br-full {colorClass()}"
		style="background: {customColor[0]};animation-duration: {0.6 / speed}s;-webkit-animation-duration: {0.6 / speed}s;"
	></div>
	<div
		class="shape4 absolute h-1/2 w-1/2 rounded-bl-full {colorClass()}"
		style="background: {customColor[0]};animation-duration: {0.6 / speed}s;-webkit-animation-duration: {0.6 / speed}s;"
	></div>
</div>

<style>
	.loading {
		animation: animationContainer 1.2s ease infinite;
	}
	.shape1 {
		animation: animationShape1 0.6s ease infinite alternate;
	}

	.shape2 {
		animation: animationShape2 0.6s ease infinite alternate;
	}

	.shape3 {
		animation: animationShape3 0.6s ease infinite alternate;
	}

	.shape4 {
		animation: animationShape4 0.6s ease infinite alternate;
	}

	@keyframes animationContainer {
		0% {
			transform: rotate(0);
		}

		100% {
			transform: rotate(360deg);
		}
	}
	@keyframes animationShape1 {
		0% {
			top: 0;
			left: 0;
		}
		100% {
			top: -10%;
			left: -10%;
		}
	}

	@keyframes animationShape2 {
		0% {
			top: 0;
			left: 50%;
		}
		100% {
			top: -10%;
			left: 60%;
		}
	}

	@keyframes animationShape3 {
		0% {
			top: 50%;
			left: 50%;
		}
		100% {
			top: 60%;
			left: 60%;
		}
	}

	@keyframes animationShape4 {
		0% {
			top: 50%;
			left: 0;
		}
		100% {
			top: 60%;
			left: -10%;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_22.svelte
================================================
<script lang="ts">
	type Props = { size?: string; customColor?: any[]; speed?: number; theme?: boolean; inverse?: boolean };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' text-dark dark:text-primary' : ' text-white dark:text-black';
		} else {
			return theme ? ' text-primary dark:text-dark' : ' text-black dark:text-white';
		}
	};
</script>

<div class="{size} m-auto" style="animation-duration: {2 / speed}s;-webkit-animation-duration: {2 / speed}s;">
	<svg
		class="container overflow-visible will-change-transform origin-center{colorClass()}"
		viewBox="0 0 40 40"
		style="color: {customColor[0]}"
	>
		<circle class="track stroke-[5px] opacity-0" stroke="currentColor" cx="20" cy="20" r="17.5" fill="none" />
		<circle
			class="car stroke-[5px]"
			style="animation-duration: {(2 / speed) * 0.75}s;-webkit-animation-duration: {(2 / speed) * 0.75}s;"
			stroke="currentColor"
			cx="20"
			cy="20"
			r="17.5"
			fill="none"
		/>
	</svg>
</div>

<style>
	.container {
		animation: rotate 2s linear infinite;
	}

	.car {
		stroke-dasharray: 1, 200;
		stroke-dashoffset: 0;
		stroke-linecap: round;
		animation: stretch 1.5s ease-in-out infinite;
		will-change: stroke-dasharray, stroke-dashoffset;
		transition: stroke 0.5s ease;
	}

	.track {
		transition: stroke 0.5s ease;
	}

	@keyframes rotate {
		100% {
			transform: rotate(360deg);
		}
	}

	@keyframes stretch {
		0% {
			stroke-dasharray: 0, 150;
			stroke-dashoffset: 0;
		}
		50% {
			stroke-dasharray: 75, 150;
			stroke-dashoffset: -25;
		}
		100% {
			stroke-dashoffset: -100;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_23.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} relative m-auto -translate-x-0.5">
	{#each new Array(12) as item, i}
		<div
			class="absolute left-1/2 flex h-8 w-[3px] flex-col gap-5 rounded-full bg-transparent"
			style="transform: rotate(calc(360deg / -12*{i}));"
		>
			<div
				class="h-1/5 rounded-full line{colorClass()}"
				style="background: {customColor[0]};animation-delay: calc( {1 / speed}s / -12 * {i}); animation-duration: {1 /
					speed}s;-webkit-animation-duration: {1 / speed}s;"
			></div>
		</div>
	{/each}
</div>

<style>
	.line {
		animation: pulse ease-in-out infinite;
		transition: background-color 0.3s ease;
		transform-origin: center bottom;
	}

	@keyframes pulse {
		0%,
		80%,
		100% {
			transform: scaleY(0.75);
			opacity: 0;
		}
		20% {
			transform: scaleY(1);
			opacity: 1;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_24.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' stroke-dark dark:stroke-primary' : ' stroke-white dark:stroke-black';
		} else {
			return theme ? ' stroke-primary dark:stroke-dark' : ' stroke-black dark:stroke-white';
		}
	};
</script>

<div class="m-auto">
	<svg class="{size} origin-center overflow-visible" x="0px" y="0px" viewBox="0 0 37 37" preserveAspectRatio="xMidYMid meet">
		<path
			class="opacity-10 {colorClass()}"
			fill="none"
			style="stroke: {customColor[0]};"
			stroke-width="5"
			pathLength="100"
			d="M0.37 18.5 C0.37 5.772 5.772 0.37 18.5 0.37 S36.63 5.772 36.63 18.5 S31.228 36.63 18.5 36.63 S0.37 31.228 0.37 18.5"
		>
		</path>
		<path
			class="car {colorClass()}"
			fill="none"
			style="stroke: {customColor[0]}; animation-duration: {1 / speed}s;-webkit-animation-duration: {1 / speed}s;"
			stroke-width="5"
			pathLength="100"
			d="M0.37 18.5 C0.37 5.772 5.772 0.37 18.5 0.37 S36.63 5.772 36.63 18.5 S31.228 36.63 18.5 36.63 S0.37 31.228 0.37 18.5"
		>
		</path>
	</svg>
</div>

<style>
	.car {
		stroke-dasharray: 15, 85;
		stroke-dashoffset: 0;
		stroke-linecap: round;
		animation: travel linear infinite;
		will-change: stroke-dasharray, stroke-dashoffset;
		transition: stroke 0.5s ease;
	}

	@keyframes travel {
		0% {
			stroke-dashoffset: 0;
		}

		100% {
			stroke-dashoffset: -100;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_25.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' stroke-dark dark:stroke-primary' : ' stroke-white dark:stroke-black';
		} else {
			return theme ? ' stroke-primary dark:stroke-dark' : ' stroke-black dark:stroke-white';
		}
	};
</script>

<div class="m-auto">
	<svg class="{size} origin-center overflow-visible will-change-transform" viewBox="0 0 35 35">
		<rect
			class="opacity-10 {colorClass()}"
			style="stroke: {customColor[0]};"
			x="2.5"
			y="2.5"
			fill="none"
			stroke-width="5px"
			width="32.5"
			height="32.5"
		/>
		<rect
			class="car {colorClass()}"
			style="stroke: {customColor[0]};  animation-duration: {1.2 / speed}s;-webkit-animation-duration: {1.2 / speed}s;"
			x="2.5"
			y="2.5"
			fill="none"
			stroke-width="5px"
			width="32.5"
			height="32.5"
			pathLength="100"
		/>
	</svg>
</div>

<style>
	.car {
		stroke-dasharray: 25, 75;
		stroke-dashoffset: 0;
		animation: travel linear infinite;
		will-change: stroke-dasharray, stroke-dashoffset;
		transition: stroke 0.5s ease;
	}

	@keyframes travel {
		0% {
			stroke-dashoffset: 0;
		}

		100% {
			stroke-dashoffset: -100;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_26.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' stroke-dark dark:stroke-primary' : ' stroke-white dark:stroke-black';
		} else {
			return theme ? ' stroke-primary dark:stroke-dark' : ' stroke-black dark:stroke-white';
		}
	};
</script>

<div class="m-auto">
	<svg
		class="{size} origin-center overflow-visible"
		x="0px"
		y="0px"
		viewBox="0 0 37 37"
		height="37"
		width="37"
		preserveAspectRatio="xMidYMid meet"
	>
		<path
			class="opacity-10{colorClass()}"
			fill="none"
			style="stroke: {customColor[0]};"
			stroke-width="5"
			pathLength="100"
			d="M36.63 31.746 c0 -13.394 -7.3260000000000005 -25.16 -18.13 -31.375999999999998 C7.696 6.66 0.37 18.352 0.37 31.746 c5.328 3.108 11.544 4.8839999999999995 18.13 4.8839999999999995 S31.301999999999996 34.854 36.63 31.746z"
		></path>
		<path
			class="car{colorClass()}"
			fill="none"
			style="stroke: {customColor[0]}; animation-duration: {1 / speed}s;-webkit-animation-duration: {1 / speed}s;"
			stroke-width="5"
			pathLength="100"
			d="M36.63 31.746 c0 -13.394 -7.3260000000000005 -25.16 -18.13 -31.375999999999998 C7.696 6.66 0.37 18.352 0.37 31.746 c5.328 3.108 11.544 4.8839999999999995 18.13 4.8839999999999995 S31.301999999999996 34.854 36.63 31.746z"
		></path>
	</svg>
</div>

<style>
	.car {
		fill: none;
		stroke-dasharray: 15, 85;
		stroke-dashoffset: 0;
		stroke-linecap: round;
		animation: travel linear infinite;
		will-change: stroke-dasharray, stroke-dashoffset;
		transition: stroke 0.5s ease;
	}

	@keyframes travel {
		0% {
			stroke-dashoffset: 0;
		}

		100% {
			stroke-dashoffset: 100;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_27.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} container relative m-auto flex items-center" style="animation-duration: {2 / speed}s;">
	{#each [0, -0.835, -0.668, -0.501, -0.334, -0.167] as item}
		<div
			class="dot absolute left-0 right-0 flex"
			style="animation-duration: {2 / speed}s; animation-delay: calc({2 / speed}s * {item} * 0.5);"
		>
			<div
				class="h-1.5 w-1.5 rounded-full{colorClass()}"
				style="background-color: {customColor[0]}; animation-delay: calc({2 / speed}s * {item} * 0.5);"
			></div>
		</div>
	{/each}
</div>

<style>
	.container {
		animation: smoothRotate linear infinite;
	}

	.dot {
		animation: rotate ease-in-out infinite;
	}

	@keyframes rotate {
		0% {
			transform: rotate(0deg);
		}
		65%,
		100% {
			transform: rotate(360deg);
		}
	}

	@keyframes smoothRotate {
		0% {
			transform: rotate(0deg);
		}
		100% {
			transform: rotate(360deg);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_28.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} relative m-auto flex items-center">
	{#each [0, -0.875, -0.75, -0.625, -0.5, -0.375, -0.25, -0.125] as item, i}
		<div class="absolute left-0 right-0 flex" style="transform: rotate(calc(360deg / 8 * {i})); ">
			<div
				class="dot h-1.5 w-1.5 rounded-full{colorClass()}"
				style="background-color: {customColor[0]};animation-duration: {1 / speed}s ; animation-delay: calc({1 / speed}s * {item});"
			></div>
		</div>
	{/each}
</div>

<style>
	.dot {
		animation: pulse ease-in-out infinite;
	}
	@keyframes pulse {
		0%,
		100% {
			transform: scale(0);
			opacity: 0.5;
		}
		50% {
			transform: scale(1);
			opacity: 1;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_29.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} container relative m-auto flex items-center">
	{#each [0, -0.125, -0.25, -0.375, -0.5, -0.625, -0.75, -0.875] as item, i}
		<div class="absolute left-0 right-0 flex" style="transform: rotate({i * 45}deg); animation-duration: {0.3 / speed}s">
			<div
				class="dot h-1.5 w-1.5 rounded-full{colorClass()}"
				style="background-color: {customColor[0]}; transform: translateX(12px); animation-duration: {0.9 /
					speed}s; animation-delay: calc({0.9 / speed}s * {item});"
			></div>
		</div>
	{/each}
</div>

<style>
	.container {
		animation: rotate linear infinite;
	}

	.dot {
		animation: oscillate ease-in-out infinite alternate;
	}

	@keyframes oscillate {
		0% {
			transform: translateX(12px) scale(0);
			opacity: 0.25;
		}

		100% {
			transform: translateX(0) scale(1);
			opacity: 1;
		}
	}

	@keyframes rotate {
		0% {
			transform: rotate(0deg);
		}
		100% {
			transform: rotate(360deg);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_3.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: string[]; speed?: number };

	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' border-dark dark:border-primary' : ' border-white dark:border-black';
		} else {
			return theme ? ' text-primary dark:text-dark' : ' text-black dark:text-white';
		}
	};
</script>

<div
	class="{size} m-auto border-2 rounded-full{colorClass()} animate-spin border-b-transparent border-t-transparent dark:border-b-transparent dark:border-t-transparent"
	style="border-color: {customColor[0]};border-top-color:transparent;border-bottom-color:transparent;animation-duration: {1 /
		speed}s;-webkit-animation-duration: {1 / speed}s;"
></div>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_30.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} m-auto flex items-end justify-between">
	{#each [0, -0.36, -0.2] as item}
		<div class="cube h-2 w-2" style="animation-duration: {1.75 / speed}s; animation-delay: calc({1.75 / speed}s * {item})">
			<div
				class="cube__inner h-2 w-2 rounded-xs{colorClass()}"
				style="background-color: {customColor[0]}; animation-duration: {1.75 / speed}s; animation-delay: calc({1.75 / speed}s * {item})"
			></div>
		</div>
	{/each}
</div>

<style>
	.cube {
		animation: jump ease-in-out infinite;
	}

	.cube__inner {
		animation: morph ease-in-out infinite;
	}

	@keyframes jump {
		0% {
			transform: translateY(0px);
		}

		30% {
			transform: translateY(0px);
			animation-timing-function: ease-out;
		}

		50% {
			transform: translateY(-200%);
			animation-timing-function: ease-in;
		}

		75% {
			transform: translateY(0px);
			animation-timing-function: ease-in;
		}
	}

	@keyframes morph {
		0% {
			transform: scaleY(1);
		}

		10% {
			transform: scaleY(1);
		}

		20%,
		25% {
			transform: scaleY(0.8) scaleX(1.3);
			animation-timing-function: ease-in-out;
		}

		30% {
			transform: scaleY(1.15) scaleX(0.9);
			animation-timing-function: ease-in-out;
		}

		40% {
			transform: scaleY(1);
		}

		70%,
		85%,
		100% {
			transform: scaleY(1);
		}

		75% {
			transform: scaleY(0.8) scaleX(1.2);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_31.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: string[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} m-auto flex items-center justify-between">
	{#each [-0.45, -0.3, -0.15, 0] as item}
		<div
			class="bar h-full w-[3px]{colorClass()}"
			style="background-color: {customColor[0]}; animation-duration: {1 / speed}s; animation-delay: {1 * item}s"
		></div>
	{/each}
</div>

<style>
	.bar {
		animation: grow ease-in-out infinite;
	}

	@keyframes grow {
		0%,
		100% {
			transform: scaleY(0.3);
		}

		50% {
			transform: scaleY(1);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_32.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} relative m-auto">
	<div
		class="line1 absolute w-1 h-1{colorClass()}"
		style="background-color: {customColor[0]}; top: calc(50% - 2px); left: calc(50% - 2px); animation-duration: {4 / speed}s;"
	></div>
	<div class="line2 absolute w-1 h-1{colorClass()}" style="background-color: {customColor[0]}; animation-duration: {4 / speed}s;"></div>
	<div
		class="line2 absolute w-1 h-1{colorClass()}"
		style="background-color: {customColor[0]}; animation-duration: {4 / speed}s; animation-delay: calc({4 / speed}s * -0.5);"
	></div>
</div>

<style>
	.line1 {
		animation: center-line ease infinite;
	}

	.line2 {
		animation: explore ease infinite;
	}

	@keyframes center-line {
		0%,
		25%,
		50%,
		75%,
		100% {
			transform: scaleX(1) scaleY(1);
		}
		12.5%,
		62.5% {
			transform: scaleX(8) scaleY(1);
		}
		37.5%,
		87.5% {
			transform: scaleX(1) scaleY(8);
		}
	}

	@keyframes explore {
		0%,
		100% {
			transform: scaleX(1) scaleY(1) translate(0%, 0%);
			transform-origin: top left;
			top: 0;
			left: 0;
		}

		12.5% {
			transform: scaleX(8) scaleY(1) translate(0%, 0%);
			transform-origin: top left;
			top: 0;
			left: 0;
		}

		12.50001% {
			transform: scaleX(8) scaleY(1) translate(0%, 0%);
			transform-origin: top right;
			top: 0;
			left: initial;
			right: 0;
		}

		25% {
			transform: scaleX(1) scaleY(1) translate(0%, 0%);
			transform-origin: top right;
			top: 0;
			left: initial;
			right: 0;
		}

		37.5% {
			transform: scaleX(1) scaleY(8) translate(0%, 0%);
			transform-origin: top right;
			top: 0;
			left: initial;
			right: 0;
		}

		37.5001% {
			transform: scaleX(1) scaleY(8) translate(0%, 0%);
			transform-origin: bottom right;
			top: initial;
			bottom: 0;
			left: initial;
			right: 0;
		}

		50% {
			transform: scaleX(1) scaleY(1) translate(0%, 0%);
			transform-origin: bottom right;
			top: initial;
			bottom: 0;
			left: initial;
			right: 0;
		}

		62.5% {
			transform: scaleX(8) scaleY(1) translate(0%, 0%);
			transform-origin: bottom right;
			top: initial;
			bottom: 0;
			left: initial;
			right: 0;
		}

		62.5001% {
			transform: scaleX(8) scaleY(1) translate(0%, 0%);
			transform-origin: bottom left;
			top: initial;
			bottom: 0;
			left: 0;
		}

		75% {
			transform: scaleX(1) scaleY(1) translate(0%, 0%);
			transform-origin: bottom left;
			top: initial;
			bottom: 0;
			left: 0;
		}

		87.5% {
			transform: scaleX(1) scaleY(8) translate(0%, 0%);
			transform-origin: bottom left;
			top: initial;
			bottom: 0;
			left: 0;
		}

		87.5001% {
			transform: scaleX(1) scaleY(8) translate(0%, 0%);
			transform-origin: top left;
			top: 0;
			left: 0;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_33.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} container relative m-auto flex flex-col" style="animation-duration: {3.5 / speed}s;">
	<div
		class="isolation absolute flex h-[13.92px] w-[13.92px] items-center justify-center overflow-hidden"
		style="top: 8.25%; left: 8.25%; border-radius: 50% 50% calc(32px / 15);"
	>
		<div class="absolute left-0 top-0 h-full w-full opacity-10{colorClass()}" style="background-color: {customColor[0]};"></div>
		<div
			class="half1 relative w-full origin-bottom-right h-full{colorClass()}"
			style="background-color: {customColor[0]}; animation-duration: {3.5 / speed}s;"
		></div>
	</div>
	<div
		class="isolation absolute flex h-[13.92px] w-[13.92px] items-center justify-center overflow-hidden"
		style="bottom: 8.25%; right: 8.25%; transform: rotate(180deg); align-self: flex-end; border-radius: 50% 50% calc(32px / 15);"
	>
		<div class="absolute left-0 top-0 h-full w-full opacity-10{colorClass()}" style="background-color: {customColor[0]};"></div>
		<div
			class="half2 relative h-full w-full origin-bottom-right z-10{colorClass()}"
			style="background-color: {customColor[0]}; animation-delay: -{3.5 / speed / 2}s; animation-duration: {3.5 / speed}s;"
		></div>
	</div>
</div>

<style>
	.container {
		animation: rotate ease-in-out infinite;
	}

	.half1 {
		animation: flow linear infinite both;
		border-radius: 0 0 1.6px 0;
		transform: rotate(45deg) translate(-3%, 50%) scaleX(1.2);
	}

	.half2 {
		animation: flow linear infinite both;
		border-radius: 0 0 1.6px 0;
		transform: rotate(45deg) translate(-3%, 50%) scaleX(1.2);
	}

	@keyframes flow {
		0% {
			transform: rotate(45deg) translate(-3%, 50%) scaleX(1.2);
		}
		30% {
			transform: rotate(45deg) translate(115%, 50%) scaleX(1.2);
		}

		30.001%,
		50% {
			transform: rotate(0deg) translate(-85%, -85%) scaleX(1);
		}

		80%,
		100% {
			transform: rotate(0deg) translate(0%, 0%) scaleX(1);
		}
	}

	@keyframes rotate {
		0%,
		30% {
			transform: rotate(45deg);
		}

		50%,
		80% {
			transform: rotate(225deg);
		}

		100% {
			transform: rotate(405deg);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_34.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} flex flex-col justify-center">
	<div class="{size} relative m-auto overflow-hidden rounded-full" style="height:4px">
		<div class="absolute h-full w-full opacity-10{colorClass()}" style="background-color: {customColor[0]};"></div>
		<div
			class="container h-full w-full rounded-full{colorClass()}"
			style="background-color: {customColor[0]}; animation-duration: {1.5 / speed}s"
		></div>
	</div>
</div>

<style>
	.container {
		animation: zoom ease-in-out infinite;
	}

	@keyframes zoom {
		0% {
			transform: translateX(-100%);
		}
		100% {
			transform: translateX(100%);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_35.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} flex flex-col justify-center">
	<div class="{size} relative m-auto overflow-hidden rounded-full" style="height:4px">
		<div class="absolute h-full w-full opacity-10{colorClass()}" style="background-color: {customColor[0]};"></div>
		<div
			class="container h-full w-full rounded-full{colorClass()}"
			style="background-color: {customColor[0]}; animation-duration: {2 / speed}s"
		></div>
	</div>
</div>

<style>
	.container {
		animation: zoom ease-in-out infinite;
	}

	@keyframes zoom {
		0%,
		100% {
			transform: translateX(-95%);
		}
		50% {
			transform: translateX(95%);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_36.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' stroke-dark dark:stroke-primary' : ' stroke-white dark:stroke-black';
		} else {
			return theme ? ' stroke-primary dark:stroke-dark' : ' stroke-black dark:stroke-white';
		}
	};
</script>

<div class="{size} m-auto flex flex-col justify-center">
	<svg
		class="{size} m-auto h-full w-full origin-center overflow-visible"
		x="0px"
		y="0px"
		viewBox="0 0 55 23.1"
		preserveAspectRatio="xMidYMid meet"
	>
		<path
			class="opacity-10{colorClass()}"
			fill="none"
			style="stroke: {customColor[0]};"
			stroke-width="5"
			pathLength="100"
			d="M26.7,12.2c3.5,3.4,7.4,7.8,12.7,7.8c5.5,0,9.6-4.4,9.6-9.5C49,5,45.1,1,39.8,1c-5.5,0-9.5,4.2-13.1,7.8l-3.4,3.3c-3.6,3.6-7.6,7.8-13.1,7.8C4.9,20,1,16,1,10.5C1,5.4,5.1,1,10.6,1c5.3,0,9.2,4.5,12.7,7.8L26.7,12.2z"
		/>
		<path
			class="car{colorClass()}"
			fill="none"
			style="stroke: {customColor[0]}; animation-duration: {1.5 / speed}s;-webkit-animation-duration: {1.5 / speed}s;"
			stroke-width="5"
			pathLength="100"
			d="M26.7,12.2c3.5,3.4,7.4,7.8,12.7,7.8c5.5,0,9.6-4.4,9.6-9.5C49,5,45.1,1,39.8,1c-5.5,0-9.5,4.2-13.1,7.8l-3.4,3.3c-3.6,3.6-7.6,7.8-13.1,7.8C4.9,20,1,16,1,10.5C1,5.4,5.1,1,10.6,1c5.3,0,9.2,4.5,12.7,7.8L26.7,12.2z"
		/>
	</svg>
</div>

<style>
	.car {
		stroke-dasharray: 15, 85;
		stroke-dashoffset: 0;
		stroke-linecap: round;
		animation: travel linear infinite;
		will-change: stroke-dasharray, stroke-dashoffset;
	}

	@keyframes travel {
		0% {
			stroke-dashoffset: 0;
		}

		100% {
			stroke-dashoffset: 100;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_37.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' stroke-dark dark:stroke-primary' : ' stroke-white dark:stroke-black';
		} else {
			return theme ? ' stroke-primary dark:stroke-dark' : ' stroke-black dark:stroke-white';
		}
	};
</script>

<div class="{size} m-auto">
	<svg
		class="h-full w-full origin-center overflow-visible"
		x="0px"
		y="0px"
		viewBox="0 0 40 40"
		height="40"
		width="40"
		preserveAspectRatio="xMidYMid meet"
	>
		<path
			class="opacity-10{colorClass()}"
			style="stroke: {customColor[0]};"
			fill="none"
			stroke-width="4"
			pathLength="100"
			d="M29.760000000000005 18.72 c0 7.28 -3.9200000000000004 13.600000000000001 -9.840000000000002 16.96 c -2.8800000000000003 1.6800000000000002 -6.24 2.64 -9.840000000000002 2.64 c -3.6 0 -6.88 -0.96 -9.76 -2.64 c0 -7.28 3.9200000000000004 -13.52 9.840000000000002 -16.96 c2.8800000000000003 -1.6800000000000002 6.24 -2.64 9.76 -2.64 S26.880000000000003 17.040000000000003 29.760000000000005 18.72 c5.84 3.3600000000000003 9.76 9.68 9.840000000000002 16.96 c -2.8800000000000003 1.6800000000000002 -6.24 2.64 -9.76 2.64 c -3.6 0 -6.88 -0.96 -9.840000000000002 -2.64 c -5.84 -3.3600000000000003 -9.76 -9.68 -9.76 -16.96 c0 -7.28 3.9200000000000004 -13.600000000000001 9.76 -16.96 C25.84 5.120000000000001 29.760000000000005 11.440000000000001 29.760000000000005 18.72z"
		>
		</path>
		<path
			class="car{colorClass()}"
			style="stroke: {customColor[0]}; animation-duration: {1.5 / speed}s;-webkit-animation-duration: {1.5 / speed}s;"
			fill="none"
			stroke-width="4"
			pathLength="100"
			d="M29.760000000000005 18.72 c0 7.28 -3.9200000000000004 13.600000000000001 -9.840000000000002 16.96 c -2.8800000000000003 1.6800000000000002 -6.24 2.64 -9.840000000000002 2.64 c -3.6 0 -6.88 -0.96 -9.76 -2.64 c0 -7.28 3.9200000000000004 -13.52 9.840000000000002 -16.96 c2.8800000000000003 -1.6800000000000002 6.24 -2.64 9.76 -2.64 S26.880000000000003 17.040000000000003 29.760000000000005 18.72 c5.84 3.3600000000000003 9.76 9.68 9.840000000000002 16.96 c -2.8800000000000003 1.6800000000000002 -6.24 2.64 -9.76 2.64 c -3.6 0 -6.88 -0.96 -9.840000000000002 -2.64 c -5.84 -3.3600000000000003 -9.76 -9.68 -9.76 -16.96 c0 -7.28 3.9200000000000004 -13.600000000000001 9.76 -16.96 C25.84 5.120000000000001 29.760000000000005 11.440000000000001 29.760000000000005 18.72z"
		>
		</path>
	</svg>
</div>

<style>
	.car {
		stroke-dasharray: 15, 85;
		stroke-dashoffset: 0;
		stroke-linecap: round;
		animation: travel linear infinite;
		will-change: stroke-dasharray, stroke-dashoffset;
	}

	@keyframes travel {
		0% {
			stroke-dashoffset: 0;
		}

		100% {
			stroke-dashoffset: -100;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_38.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' stroke-dark dark:stroke-primary' : ' stroke-white dark:stroke-black';
		} else {
			return theme ? ' stroke-primary dark:stroke-dark' : ' stroke-black dark:stroke-white';
		}
	};
</script>

<div class="{size} m-auto">
	<svg
		class="h-full w-full origin-center overflow-visible"
		x="0px"
		y="0px"
		viewBox="0 0 50 31.25"
		height="31.25"
		width="50"
		preserveAspectRatio="xMidYMid meet"
	>
		<path
			class="track opacity-10{colorClass()}"
			style="stroke: {customColor[0]};"
			stroke-width="4"
			fill="none"
			pathLength="100"
			d="M0.625 21.5 h10.25 l3.75 -5.875 l7.375 15 l9.75 -30 l7.375 20.875 v0 h10.25"
		/>
		<path
			class="car{colorClass()}"
			style="stroke: {customColor[0]}; animation-duration: {1.5 / speed}s;-webkit-animation-duration: {1.5 / speed}s;"
			stroke-width="4"
			fill="none"
			pathLength="100"
			d="M0.625 21.5 h10.25 l3.75 -5.875 l7.375 15 l9.75 -30 l7.375 20.875 v0 h10.25"
		/>
	</svg>
</div>

<style>
	.car {
		stroke-dasharray: 100;
		stroke-dashoffset: 0;
		stroke-linecap: round;
		stroke-linejoin: round;
		animation:
			travel ease-in-out infinite,
			fade ease-out infinite;
		will-change: stroke-dasharray, stroke-dashoffset;
	}

	.track {
		stroke-linecap: round;
		stroke-linejoin: round;
	}

	@keyframes travel {
		0% {
			stroke-dashoffset: 100;
		}

		75% {
			stroke-dashoffset: 0;
		}
	}

	@keyframes fade {
		0% {
			opacity: 0;
		}

		20%,
		55% {
			opacity: 1;
		}

		100% {
			opacity: 0;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_39.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} m-auto flex flex-col items-center justify-center">
	{#each [0, 1, 2, 3, 4, 5] as item}
		<div class="relative w-full" style="height: calc(32px / 6);">
			<div
				class="slice absolute top-0 h-full rounded-full shrink-0{colorClass()}"
				style="background-color: {customColor[0]};left: calc(50% - 32px / 12);width: calc(100% / 6);animation-duration: {2.5 /
					speed}s;animation-delay: {-(2.5 / speed / 6) * item}s;"
			></div>
			<div
				class="slice absolute top-0 h-full rounded-full shrink-0{colorClass()}"
				style="background-color: {customColor[0]};left: calc(50% - 32px / 12);width: calc(100% / 6);animation-duration: {2.5 /
					speed}s;animation-delay: {-(2.5 / speed / 2) - (2.5 / speed / 6) * item}s;"
			></div>
		</div>
	{/each}
</div>

<style>
	.slice {
		animation: orbit linear infinite;
	}

	@keyframes orbit {
		0% {
			transform: translateX(calc(32px * 0.25)) scale(0.73684);
			opacity: 0.65;
		}
		5% {
			transform: translateX(calc(32px * 0.235)) scale(0.684208);
			opacity: 0.58;
		}
		10% {
			transform: translateX(calc(32px * 0.182)) scale(0.631576);
			opacity: 0.51;
		}
		15% {
			transform: translateX(calc(32px * 0.129)) scale(0.578944);
			opacity: 0.44;
		}
		20% {
			transform: translateX(calc(32px * 0.076)) scale(0.526312);
			opacity: 0.37;
		}
		25% {
			transform: translateX(0%) scale(0.47368);
			opacity: 0.3;
		}
		30% {
			transform: translateX(calc(32px * -0.076)) scale(0.526312);
			opacity: 0.37;
		}
		35% {
			transform: translateX(calc(32px * -0.129)) scale(0.578944);
			opacity: 0.44;
		}
		40% {
			transform: translateX(calc(32px * -0.182)) scale(0.631576);
			opacity: 0.51;
		}
		45% {
			transform: translateX(calc(32px * -0.235)) scale(0.684208);
			opacity: 0.58;
		}
		50% {
			transform: translateX(calc(32px * -0.25)) scale(0.73684);
			opacity: 0.65;
		}
		55% {
			transform: translateX(calc(32px * -0.235)) scale(0.789472);
			opacity: 0.72;
		}
		60% {
			transform: translateX(calc(32px * -0.182)) scale(0.842104);
			opacity: 0.79;
		}
		65% {
			transform: translateX(calc(32px * -0.129)) scale(0.894736);
			opacity: 0.86;
		}
		70% {
			transform: translateX(calc(32px * -0.076)) scale(0.947368);
			opacity: 0.93;
		}
		75% {
			transform: translateX(0%) scale(1);
			opacity: 1;
		}
		80% {
			transform: translateX(calc(32px * 0.076)) scale(0.947368);
			opacity: 0.93;
		}
		85% {
			transform: translateX(calc(32px * 0.129)) scale(0.894736);
			opacity: 0.86;
		}
		90% {
			transform: translateX(calc(32px * 0.182)) scale(0.842104);
			opacity: 0.79;
		}
		95% {
			transform: translateX(calc(32px * 0.235)) scale(0.789472);
			opacity: 0.72;
		}
		100% {
			transform: translateX(calc(32px * 0.25)) scale(0.73684);
			opacity: 0.65;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_4.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: string[]; speed?: number };

	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' border-dark dark:border-primary' : ' border-white dark:border-black';
		} else {
			return theme ? ' border-primary dark:border-dark' : ' border-black dark:border-white';
		}
	};
</script>

<div class="{size} m-auto flex flex-col justify-center">
	<div
		class="relative m-auto h-8 w-8 border-2 rounded-full{colorClass()} animate-spin border-b-transparent border-t-transparent dark:border-b-transparent dark:border-t-transparent"
		style="border-color: {customColor[0]};border-top-color:transparent;border-bottom-color:transparent;animation-duration: {1 /
			speed}s;-webkit-animation-duration: {1 / speed}s;"
	>
		<div
			class="absolute{colorClass()} border-l-[5px] border-r-[5px] border-t-[5px] border-l-transparent border-r-transparent dark:border-l-transparent dark:border-r-transparent"
			style="transform: rotate(225deg);border-color: {customColor[0]};border-right-color:transparent;border-left-color:transparent;"
		></div>
		<div
			class="absolute bottom-0 right-0{colorClass()} border-l-[5px] border-r-[5px] border-t-[5px] border-l-transparent border-r-transparent dark:border-l-transparent dark:border-r-transparent"
			style="transform: rotate(45deg);border-color: {customColor[0]};border-right-color:transparent;border-left-color:transparent;"
		></div>
	</div>
</div>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_40.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
	const brList = [
		[24, -35],
		[16, -6],
		[8, 23],
		[-1, 51],
		[38, -17.5],
		[30, 10],
		[22, 39],
		[14, 67],
		[53, -0.8],
		[44.5, 27],
		[36, 55.7],
		[28.7, 84.3],
		[66.8, 15],
		[58.8, 43],
		[50, 72],
		[42, 100]
	];
</script>

<div class="{size} relative m-auto flex items-center">
	{#each [-0.48, -0.4, -0.32, -0.24, -0.4, -0.32, -0.24, -0.16, -0.32, -0.24, -0.16, -0.08, -0.24, -0.16, -0.08, -0] as item, i}
		<div
			class="dot absolute h-1 w-1 rounded-full{colorClass()}"
			style="background-color: {customColor[0]};bottom: calc({brList[i][0]}% + 1.6px);right: calc({brList[
				i
			][1]}% + 1.6px);animation-duration: {1.5 / speed}s;animation-delay: {(1.5 / speed) * item}s"
		></div>
	{/each}
</div>

<style>
	.dot {
		animation: jump ease-in-out infinite;
	}

	@keyframes jump {
		0%,
		100% {
			transform: translateY(120%);
		}

		50% {
			transform: translateY(-120%);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_41.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} relative m-auto">
	<div
		class="container absolute left-2.5 top-2.5 h-3 w-3 rounded-full{colorClass()}"
		style="background-color: {customColor[0]};animation-duration: {1.5 / speed}s;"
	></div>
	<div
		class="container absolute left-2.5 top-2.5 h-3 w-3 rounded-full{colorClass()}"
		style="background-color: {customColor[0]};animation-duration: {1.5 / speed}s;animation-delay: {0.75 / speed}s"
	></div>
</div>

<style>
	.container {
		animation: orbit linear infinite;
	}

	@keyframes orbit {
		0% {
			transform: translateX(calc(32px * 0.25)) scale(0.73684);
			opacity: 0.65;
		}
		5% {
			transform: translateX(calc(32px * 0.235)) scale(0.684208);
			opacity: 0.58;
		}
		10% {
			transform: translateX(calc(32px * 0.182)) scale(0.631576);
			opacity: 0.51;
		}
		15% {
			transform: translateX(calc(32px * 0.129)) scale(0.578944);
			opacity: 0.44;
		}
		20% {
			transform: translateX(calc(32px * 0.076)) scale(0.526312);
			opacity: 0.37;
		}
		25% {
			transform: translateX(0%) scale(0.47368);
			opacity: 0.3;
		}
		30% {
			transform: translateX(calc(32px * -0.076)) scale(0.526312);
			opacity: 0.37;
		}
		35% {
			transform: translateX(calc(32px * -0.129)) scale(0.578944);
			opacity: 0.44;
		}
		40% {
			transform: translateX(calc(32px * -0.182)) scale(0.631576);
			opacity: 0.51;
		}
		45% {
			transform: translateX(calc(32px * -0.235)) scale(0.684208);
			opacity: 0.58;
		}
		50% {
			transform: translateX(calc(32px * -0.25)) scale(0.73684);
			opacity: 0.65;
		}
		55% {
			transform: translateX(calc(32px * -0.235)) scale(0.789472);
			opacity: 0.72;
		}
		60% {
			transform: translateX(calc(32px * -0.182)) scale(0.842104);
			opacity: 0.79;
		}
		65% {
			transform: translateX(calc(32px * -0.129)) scale(0.894736);
			opacity: 0.86;
		}
		70% {
			transform: translateX(calc(32px * -0.076)) scale(0.947368);
			opacity: 0.93;
		}
		75% {
			transform: translateX(0%) scale(1);
			opacity: 1;
		}
		80% {
			transform: translateX(calc(32px * 0.076)) scale(0.947368);
			opacity: 0.93;
		}
		85% {
			transform: translateX(calc(32px * 0.129)) scale(0.894736);
			opacity: 0.86;
		}
		90% {
			transform: translateX(calc(32px * 0.182)) scale(0.842104);
			opacity: 0.79;
		}
		95% {
			transform: translateX(calc(32px * 0.235)) scale(0.789472);
			opacity: 0.72;
		}
		100% {
			transform: translateX(calc(32px * 0.25)) scale(0.73684);
			opacity: 0.65;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_42.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} container relative m-auto inline-block" style="animation-duration: {1.5 / speed}s;">
	{#each [120, -120, 0] as item}
		<div class="absolute h-full" style="transform: rotate({item}deg);left: 37.5%;width:25%;">
			<div
				class="dot absolute left-0 top-0 h-0 w-full rounded-full{colorClass()}"
				style="background-color: {customColor[0]};padding-bottom: 100%;animation-duration: {1.5 / speed}s;"
			></div>
		</div>
	{/each}
</div>

<style>
	.container {
		animation: spin infinite linear;
	}
	.dot {
		animation: wobble infinite ease-in-out;
	}

	@keyframes spin {
		0% {
			transform: rotate(0deg);
		}
		100% {
			transform: rotate(360deg);
		}
	}

	@keyframes wobble {
		0%,
		100% {
			transform: translateY(0%);
		}
		50% {
			transform: translateY(65%);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_43.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} m-auto flex flex-col justify-center">
	<div class="flex items-center justify-between">
		{#each [-0.45, -0.3, -0.15, 0] as item}
			<div
				class="dot h-1.5 w-1.5 rounded-full{colorClass()}"
				style="background-color: {customColor[0]};animation-duration: {1 / speed}s;animation-delay: {(1 / speed) * item}s"
			></div>
		{/each}
	</div>
</div>

<style>
	.dot {
		animation: jump ease-in-out infinite;
	}

	@keyframes jump {
		0%,
		100% {
			transform: translateY(100%);
		}

		50% {
			transform: translateY(-100%);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_44.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} relative m-auto">
	{#each [0, 0.4, 0.8] as item, i}
		<div
			class="dot absolute left-0 top-0 flex h-full w-full items-center"
			style="animation-duration: {2.5 / speed}s;transform: translateX({32 * item}px);animation-delay: {2.5 / speed / (-1.5 * i)}s"
		>
			<div class="w-2 rounded-full h-2{colorClass()}" style="background-color: {customColor[0]};"></div>
		</div>
	{/each}
</div>

<style>
	.dot {
		animation: leapFrog ease infinite;
	}

	@keyframes leapFrog {
		0% {
			transform: translateX(0) rotate(0deg);
		}

		33.333% {
			transform: translateX(0) rotate(180deg);
		}

		66.666% {
			transform: translateX(calc(32px * -0.38)) rotate(180deg);
		}

		99.999% {
			transform: translateX(calc(32px * -0.78)) rotate(180deg);
		}

		100% {
			transform: translateX(0) rotate(0deg);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_45.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} m-auto flex items-center justify-center">
	{#each [0, 1, 2, 3] as item}
		<div
			class="dot relative flex h-full w-1/4 items-center"
			class:dot1={item === 0}
			class:dot2={item === 3}
			style="transform-origin: center top;animation-duration: {1.5 / speed}s;"
		>
			<div class="h-1/4 w-full rounded-full{colorClass()}" style="background-color: {customColor[0]};"></div>
		</div>
	{/each}
</div>

<style>
	.dot1 {
		animation: swing linear infinite;
	}

	.dot2 {
		animation: swing2 linear infinite;
	}

	@keyframes swing {
		0% {
			transform: rotate(0deg);
			animation-timing-function: ease-out;
		}

		25% {
			transform: rotate(70deg);
			animation-timing-function: ease-in;
		}

		50% {
			transform: rotate(0deg);
			animation-timing-function: linear;
		}
	}

	@keyframes swing2 {
		0% {
			transform: rotate(0deg);
			animation-timing-function: linear;
		}

		50% {
			transform: rotate(0deg);
			animation-timing-function: ease-out;
		}

		75% {
			transform: rotate(-70deg);
			animation-timing-function: ease-in;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_46.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} m-auto flex flex-col justify-center">
	<div class="relative flex h-1/5 w-full -translate-x-[10%] items-center justify-between">
		{#each [0, -0.2, -0.4, -0.6, -0.8] as item}
			<div
				class="dot absolute h-full w-1/5 rounded-full{colorClass()}"
				style="background-color: {customColor[0]};animation-delay: {(2.5 / speed) * item}s;animation-duration: {2.5 / speed}s"
			></div>
		{/each}
	</div>
</div>

<style>
	.dot {
		animation: stream linear infinite both;
	}

	@keyframes stream {
		0%,
		100% {
			transform: translateX(0) scale(0);
		}

		50% {
			transform: translateX(16px) scale(1);
		}

		99.999% {
			transform: translateX(32px) scale(0);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_47.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} m-auto flex flex-col justify-center">
	<div class="relative flex items-center justify-between">
		{#each [-0.375, -0.25, -0.125] as item}
			<div
				class="dot h-2 w-2 rounded-full{colorClass()}"
				style="background-color: {customColor[0]};animation-duration: {1.3 / speed}s;animation-delay: {(1.3 / speed) * item}s"
			></div>
		{/each}
	</div>
</div>

<style>
	.dot {
		animation: pulse ease-in-out infinite both;
	}

	@keyframes pulse {
		0%,
		100% {
			transform: scale(0);
		}

		50% {
			transform: scale(1);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_48.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} relative m-auto flex -rotate-90 items-center">
	{#each [1, 0.9, 0.6, 0.4] as item, i}
		<div
			class="dot absolute left-0 flex h-full w-full flex-col items-center"
			style="animation-duration: {1.6 / speed}s;animation-delay: {(1.6 / speed) * -(0.4 - i * 0.09)}s;"
		>
			<div
				class="h-1/4 w-1/4 rounded-full{colorClass()}"
				style="background-color: {customColor[0]};opacity: {item};transform: scale({1 - 0.1 * i});"
			></div>
		</div>
	{/each}
</div>

<style>
	.dot {
		animation: swing linear infinite;
	}

	@keyframes swing {
		0% {
			transform: rotate(0deg);
		}

		15% {
			transform: rotate(0deg);
		}

		50% {
			transform: rotate(180deg);
		}

		65% {
			transform: rotate(180deg);
		}

		100% {
			transform: rotate(0deg);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_49.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} relative m-auto">
	{#each [0, -2] as item}
		<div
			class="dot absolute left-0 top-0 h-full w-full rounded-full{colorClass()}"
			style="background-color: {customColor[0]};animation-duration: {2 / speed}s;animation-delay: {2 / speed / item}s;"
		></div>
	{/each}
</div>

<style>
	.dot {
		animation: pulse linear infinite;
	}

	@keyframes pulse {
		0% {
			transform: scale(0);
			opacity: 1;
		}
		100% {
			transform: scale(1);
			opacity: 0;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_5.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: string[]; speed?: number };

	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div
	class="{size} m-auto rounded-full{colorClass()}"
	style="background: {customColor[0]};animation-duration: {1 / speed}s;-webkit-animation-duration: {1 / speed}s;"
></div>

<style>
	div {
		animation: ball-scale infinite linear 1s;
	}

	@keyframes ball-scale {
		0% {
			transform: scale(0.1);
			opacity: 1;
		}
		100% {
			transform: scale(1);
			opacity: 0;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_50.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} relative m-auto">
	{#each [0, -2] as item}
		<div
			class="dot absolute left-0 top-0 h-full w-full rounded-full{colorClass()}"
			style="background-color: {customColor[0]};animation-duration: {2 / speed}s;animation-delay: {2 / speed / item}s;"
		></div>
	{/each}
</div>

<style>
	.dot {
		animation: pulse linear infinite;
	}

	@keyframes pulse {
		0%,
		100% {
			transform: scale(0);
			opacity: 1;
		}
		50% {
			transform: scale(1);
			opacity: 0.25;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_51.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} relative m-auto">
	{#each [0, -0.25, -0.5, -0.75] as item}
		<div
			class="dot absolute left-0 top-0 h-full w-full rounded-full{colorClass()}"
			style="background-color: {customColor[0]};animation-duration: {2 / speed}s;animation-delay: {(2 / speed) * item}s"
		></div>
	{/each}
</div>

<style>
	.dot {
		animation: pulse linear infinite;
	}
	@keyframes pulse {
		0% {
			transform: scale(0);
			opacity: 1;
		}
		100% {
			transform: scale(1);
			opacity: 0;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_52.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} relative m-auto">
	{#each [[-0.375, 1], [-0.375, 0.8], [-0.3, 0.6], [-0.225, 0.4], [-0.15, 0.2], [-0.075, 0.1]] as item}
		<div
			class="line absolute left-0 h-1 w-full rounded-full{colorClass()}"
			style="background-color: {customColor[0]};top: calc(50% - 2px);animation-duration: {0.9 / speed}s;animation-delay: {(0.9 / speed) *
				item[0]}s;opacity: {item[1]};"
		></div>
	{/each}
</div>

<style>
	.line {
		animation: rotate ease-in-out infinite alternate;
	}
	@keyframes rotate {
		0% {
			transform: rotate(0deg);
		}

		100% {
			transform: rotate(180deg);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_53.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} relative m-auto">
	{#each [[-0.375, 1], [-0.375, 0.8], [-0.3, 0.6], [-0.225, 0.4], [-0.15, 0.2], [-0.075, 0.1]] as item}
		<div
			class="line absolute left-0 h-1 w-full rounded-full{colorClass()}"
			style="background-color: {customColor[0]};top: 50%;animation-duration: {0.9 / speed}s;animation-delay: {(0.9 / speed) *
				item[0]}s;opacity: {item[1]};"
		></div>
	{/each}
</div>

<style>
	.line {
		animation: rotate ease-in-out infinite;
	}
	@keyframes rotate {
		0% {
			transform: rotate(0deg);
		}

		100% {
			transform: rotate(180deg);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_6.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="relative {size} m-auto">
	<div
		class="absolute{colorClass()} loading1 h-1/3 w-1/3 rounded-full"
		style="background: {customColor[0]};animation-duration: {1.5 / speed}s;-webkit-animation-duration: {1.5 / speed}s;"
	></div>
	<div
		class="absolute{colorClass()} loading2 h-1/3 w-1/3 rounded-full"
		style="background: {customColor[0]};animation-duration: {1.5 / speed}s;-webkit-animation-duration: {1.5 / speed}s;"
	></div>
</div>

<style>
	.loading1 {
		animation: loading1 1.5s infinite;
	}

	.loading2 {
		animation: loading2 1.5s infinite;
	}

	@keyframes loading1 {
		0% {
			transform: translate(200%, 200%);
		}
		25% {
			transform: translate(0, 200%);
		}
		50% {
			transform: translate(0, 0);
		}
		75% {
			transform: translate(200%, 0);
		}
		100% {
			transform: translate(200%, 200%);
		}
	}

	@keyframes loading2 {
		0% {
			transform: translate(0, 0);
		}
		25% {
			transform: translate(200%, 0);
		}
		50% {
			transform: translate(200%, 200%);
		}
		75% {
			transform: translate(0, 200%);
		}
		100% {
			transform: translate(0, 0);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_7.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="{size} m-auto flex items-center">
	<div
		class="flex-1{colorClass()} loading1 h-1/2 w-1/2 rounded-full"
		style="background: {customColor[0]};animation-duration: {1 / speed}s;-webkit-animation-duration: {1 / speed}s;"
	></div>
	<div
		class="flex-1{colorClass()} loading2 h-1/2 w-1/2 rounded-full"
		style="background: {customColor[0]};animation-duration: {1 / speed}s;-webkit-animation-duration: {1 / speed}s;"
	></div>
</div>

<style>
	.loading1 {
		animation: loading infinite 1s -0.4s cubic-bezier(0.2, 0.68, 0.18, 1.08);
	}

	.loading2 {
		animation: loading infinite 1s cubic-bezier(0.2, 0.68, 0.18, 1.08);
	}

	@keyframes loading {
		0% {
			transform: scale(1);
			opacity: 1;
		}
		50% {
			transform: scale(0.1);
			opacity: 0.6;
		}
		100% {
			transform: scale(1);
			opacity: 1;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_8.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: string[]; speed?: number };

	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div
	class="{size} loading m-auto flex items-center justify-between"
	style="animation-duration: {1 / speed}s;-webkit-animation-duration: {1 / speed}s;"
>
	<div class="{colorClass()} h-2 w-2 rounded-full" style="background: {customColor[0]}"></div>
	<div class="{colorClass()} h-2 w-2 rounded-full" style="background: {customColor[0]}"></div>
	<div class="{colorClass()} h-2 w-2 rounded-full" style="background: {customColor[0]}"></div>
</div>

<style>
	.loading {
		animation: loading 1s cubic-bezier(0.7, -0.13, 0.22, 0.86) infinite;
	}

	@keyframes loading {
		0% {
			transform: rotate(0deg) scale(1);
		}
		50% {
			transform: rotate(180deg) scale(0.6);
		}
		100% {
			transform: rotate(360deg) scale(1);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/1_9.svelte
================================================
<script lang="ts">
	type Props = { theme?: boolean; inverse?: boolean; size?: string; customColor?: any[]; speed?: number };

	let { theme = false, inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const colorClass = () => {
		if (inverse) {
			return theme ? ' bg-dark dark:bg-primary' : ' bg-white dark:bg-black';
		} else {
			return theme ? ' bg-primary dark:bg-dark' : ' bg-black dark:bg-white';
		}
	};
</script>

<div class="relative {size} m-auto">
	{#each [0, 1, 2] as i}
		<div
			class="absolute{colorClass()} loading h-1/3 w-1/3 rounded-full"
			style="animation-delay: {i - 2}s;background: {customColor[0]};animation-duration: {1.5 / speed}s;-webkit-animation-duration: {1.5 /
				speed}s;"
		></div>
	{/each}
</div>

<style>
	.loading {
		animation: loading 1.5s linear infinite;
	}

	@keyframes loading {
		0% {
			transform: translate(200%, 200%);
		}
		25% {
			transform: translate(0, 200%);
		}
		50% {
			transform: translate(0, 0);
		}
		75% {
			transform: translate(200%, 0);
		}
		100% {
			transform: translate(200%, 200%);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/oneColor/index.ts
================================================
export { default as Loading1_0 } from './1_0.svelte';
export { default as Loading1_1 } from './1_1.svelte';
export { default as Loading1_2 } from './1_2.svelte';
export { default as Loading1_3 } from './1_3.svelte';
export { default as Loading1_4 } from './1_4.svelte';
export { default as Loading1_5 } from './1_5.svelte';
export { default as Loading1_6 } from './1_6.svelte';
export { default as Loading1_7 } from './1_7.svelte';
export { default as Loading1_8 } from './1_8.svelte';
export { default as Loading1_9 } from './1_9.svelte';
export { default as Loading1_10 } from './1_10.svelte';
export { default as Loading1_11 } from './1_11.svelte';
export { default as Loading1_12 } from './1_12.svelte';
export { default as Loading1_13 } from './1_13.svelte';
export { default as Loading1_14 } from './1_14.svelte';
export { default as Loading1_15 } from './1_15.svelte';
export { default as Loading1_16 } from './1_16.svelte';
export { default as Loading1_17 } from './1_17.svelte';
export { default as Loading1_18 } from './1_18.svelte';
export { default as Loading1_19 } from './1_19.svelte';
export { default as Loading1_20 } from './1_20.svelte';
export { default as Loading1_21 } from './1_21.svelte';
export { default as Loading1_22 } from './1_22.svelte';
export { default as Loading1_23 } from './1_23.svelte';
export { default as Loading1_24 } from './1_24.svelte';
export { default as Loading1_25 } from './1_25.svelte';
export { default as Loading1_26 } from './1_26.svelte';
export { default as Loading1_27 } from './1_27.svelte';
export { default as Loading1_28 } from './1_28.svelte';
export { default as Loading1_29 } from './1_29.svelte';
export { default as Loading1_30 } from './1_30.svelte';
export { default as Loading1_31 } from './1_31.svelte';
export { default as Loading1_32 } from './1_32.svelte';
export { default as Loading1_33 } from './1_33.svelte';
export { default as Loading1_34 } from './1_34.svelte';
export { default as Loading1_35 } from './1_35.svelte';
export { default as Loading1_36 } from './1_36.svelte';
export { default as Loading1_37 } from './1_37.svelte';
export { default as Loading1_38 } from './1_38.svelte';
export { default as Loading1_39 } from './1_39.svelte';
export { default as Loading1_40 } from './1_40.svelte';
export { default as Loading1_41 } from './1_41.svelte';
export { default as Loading1_42 } from './1_42.svelte';
export { default as Loading1_43 } from './1_43.svelte';
export { default as Loading1_44 } from './1_44.svelte';
export { default as Loading1_45 } from './1_45.svelte';
export { default as Loading1_46 } from './1_46.svelte';
export { default as Loading1_47 } from './1_47.svelte';
export { default as Loading1_48 } from './1_48.svelte';
export { default as Loading1_49 } from './1_49.svelte';
export { default as Loading1_50 } from './1_50.svelte';
export { default as Loading1_51 } from './1_51.svelte';
export { default as Loading1_52 } from './1_52.svelte';
export { default as Loading1_53 } from './1_53.svelte';



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/twoColor/2_0.svelte
================================================
<script lang="ts">
	type Props = { inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const outerBorderClass = () => {
		return inverse ? ' border-white/10 dark:border-black/10' : ' border-black/10 dark:border-white/10';
	};
	const innerColorClass = () => {
		return inverse
			? ' border-transparent dark:border-transparent border-l-dark dark:border-l-primary'
			: ' border-transparent dark:border-transparent border-l-primary dark:border-l-dark';
	};
</script>

<div
	class="{size} m-auto rounded-full border-2 p-0.5 animate-spin{outerBorderClass()}"
	style="border-color:{customColor[0]};animation-duration: {1 / speed}s;-webkit-animation-duration: {1 / speed}s;"
>
	<div
		class="h-full w-full border-2 rounded-full{innerColorClass()}"
		style="border-color:{customColor[1] && 'transparent'};border-left-color:{customColor[1]}"
	></div>
</div>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/twoColor/2_1.svelte
================================================
<script lang="ts">
	type Props = { inverse?: boolean; size?: string; customColor?: any[]; speed?: number };
	let { inverse = false, size = 'w-8 h-8', customColor = [], speed = $bindable(1) }: Props = $props();

	const outerBorderClass = () => {
		return inverse ? ' border-white/10 dark:border-black/10' : ' border-black/10 dark:border-white/10';
	};
	const innerColorClass = () => {
		return inverse
			? ' border-transparent dark:border-transparent border-l-dark dark:border-l-primary'
			: ' border-transparent dark:border-transparent border-l-primary dark:border-l-dark';
	};
</script>

<div
	class="{size} m-auto rounded-full border-2 p-0.5 animate-spin{innerColorClass()}"
	style="border-color:{customColor[1] && 'transparent'};border-left-color:{customColor[1]};animation-duration: {1 /
		speed}s;-webkit-animation-duration: {1 / speed}s;"
>
	<div class="h-full w-full border-2 rounded-full{outerBorderClass()}" style="border-color:{customColor[0]};"></div>
</div>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/twoColor/2_2.svelte
================================================
<script lang="ts">
	type Props = { size?: string; customColor?: any[]; speed?: number; inverse?: boolean };
	let { size = 'w-8 h-8', customColor = [], speed = $bindable(1), inverse = false }: Props = $props();

	const borderClass = () => {
		return inverse
			? 'border-white/5 dark:border-black/5 border-l-dark dark:border-l-primary border-r-dark dark:border-r-primary'
			: 'border-black/5 dark:border-white/5 border-l-primary dark:border-l-dark border-r-primary dark:border-r-dark';
	};
</script>

<div
	class="{size} loading m-auto rounded-full border-4 {borderClass()}"
	style="border-color: {customColor[0] || (inverse ? '' : '')} {customColor[1] || (inverse ? '' : '')} {customColor[0] ||
		(inverse ? '' : '')} {customColor[1] || (inverse ? '' : '')};animation-duration: {2 / speed}s;-webkit-animation-duration: {2 / speed}s;"
></div>

<style>
	.loading {
		animation: loading-animation 2s ease-in-out infinite alternate;
	}

	@keyframes loading-animation {
		from {
			transform: rotate(0deg);
		}

		to {
			transform: rotate(720deg);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/twoColor/2_3.svelte
================================================
<script lang="ts">
	type Props = { size?: string; customColor?: any[]; speed?: number; inverse?: boolean };
	let { size = 'w-8 h-8', customColor = [], speed = $bindable(1), inverse = false }: Props = $props();

	const bgClass = () => {
		return inverse ? 'bg-dark dark:bg-primary' : 'bg-primary dark:bg-dark';
	};
	const bgClass2 = () => {
		return inverse ? 'bg-white/50 dark:bg-black/50' : 'bg-black/50 dark:bg-white/50';
	};
</script>

<div class="{size} relative m-auto rotate-45">
	<div
		class="shape1 absolute left-0 top-0 h-1/3 w-1/3 {bgClass()}"
		style="background: {customColor[0]};animation-duration: {0.5 / speed}s;-webkit-animation-duration: {0.5 / speed}s;"
	></div>
	<div
		class="shape2 absolute right-0 top-0 h-1/3 w-1/3 {bgClass2()}"
		style="background: {customColor[1]};animation-duration: {0.5 / speed}s;-webkit-animation-duration: {0.5 / speed}s;"
	></div>
	<div
		class="shape3 absolute bottom-0 right-0 h-1/3 w-1/3 {bgClass()}"
		style="background: {customColor[0]};animation-duration: {0.5 / speed}s;-webkit-animation-duration: {0.5 / speed}s;"
	></div>
	<div
		class="shape4 absolute bottom-0 left-0 h-1/3 w-1/3 {bgClass2()}"
		style="background: {customColor[1]};animation-duration: {0.5 / speed}s;-webkit-animation-duration: {0.5 / speed}s;"
	></div>
</div>

<style>
	.shape1 {
		animation: animationShape1 0.5s ease infinite alternate;
	}

	.shape2 {
		animation: animationShape2 0.5s ease infinite alternate;
	}

	.shape3 {
		animation: animationShape3 0.5s ease infinite alternate;
	}

	.shape4 {
		animation: animationShape4 0.5s ease infinite alternate;
	}

	@keyframes animationShape1 {
		0% {
			transform: translate(0, 0);
		}

		100% {
			transform: translate(16px, 16px);
		}
	}

	@keyframes animationShape2 {
		0% {
			transform: translate(0, 0);
		}

		100% {
			transform: translate(-16px, 16px);
		}
	}

	@keyframes animationShape3 {
		0% {
			transform: translate(0, 0);
		}

		100% {
			transform: translate(-16px, -16px);
		}
	}

	@keyframes animationShape4 {
		0% {
			transform: translate(0, 0);
		}

		100% {
			transform: translate(16px, -16px);
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/twoColor/2_4.svelte
================================================
<script lang="ts">
	type Props = { size?: string; customColor?: any[]; speed?: number; inverse?: boolean };
	let { size = 'w-8 h-8', customColor = [], speed = $bindable(1), inverse = false } = $props();

	const bgClass = () => {
		return inverse ? 'bg-dark dark:bg-primary' : 'bg-primary dark:bg-dark';
	};
	const bgClass2 = () => {
		return inverse ? 'bg-white/50 dark:bg-black/50' : 'bg-black/50 dark:bg-white/50';
	};
</script>

<div class="{size} loading relative m-auto" style="animation-duration: {1.6 / speed}s;-webkit-animation-duration: {1.6 / speed}s;">
	<div
		class="shape1 absolute h-1/3 w-1/3 rounded-full {bgClass()}"
		style="background: {customColor[0]};animation-duration: {0.8 / speed}s;-webkit-animation-duration: {0.8 / speed}s;"
	></div>
	<div
		class="shape2 absolute h-1/3 w-1/3 rounded-full {bgClass2()}"
		style="background: {customColor[1]};animation-duration: {0.8 / speed}s;-webkit-animation-duration: {0.8 / speed}s;"
	></div>
	<div
		class="shape3 absolute h-1/3 w-1/3 rounded-full {bgClass()}"
		style="background: {customColor[0]};animation-duration: {0.8 / speed}s;-webkit-animation-duration: {0.8 / speed}s;"
	></div>
	<div
		class="shape4 absolute h-1/3 w-1/3 rounded-full {bgClass2()}"
		style="background: {customColor[1]};animation-duration: {0.8 / speed}s;-webkit-animation-duration: {0.8 / speed}s;"
	></div>
</div>

<style>
	.loading {
		animation: animationContainer 1.6s ease infinite;
	}
	.shape1 {
		animation: animationShape1 0.8s ease infinite alternate;
	}

	.shape2 {
		animation: animationShape2 0.8s ease infinite alternate;
	}

	.shape3 {
		animation: animationShape3 0.8s ease infinite alternate;
	}

	.shape4 {
		animation: animationShape4 0.8s ease infinite alternate;
	}

	@keyframes animationContainer {
		0% {
			transform: rotate(0);
		}

		100% {
			transform: rotate(360deg);
		}
	}

	@keyframes animationShape1 {
		0% {
			top: 0;
			left: 0;
		}
		100% {
			top: 66.6666666667%;
			left: 66.6666666667%;
		}
	}

	@keyframes animationShape2 {
		0% {
			top: 0;
			left: 66.6666666667%;
		}
		100% {
			top: 66.6666666667%;
			left: 0;
		}
	}

	@keyframes animationShape3 {
		0% {
			top: 66.6666666667%;
			left: 66.6666666667%;
		}
		100% {
			top: 0;
			left: 0;
		}
	}

	@keyframes animationShape4 {
		0% {
			top: 66.6666666667%;
			left: 0;
		}
		100% {
			top: 0;
			left: 66.6666666667%;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/twoColor/2_5.svelte
================================================
<script lang="ts">
	type Props = { size?: string; customColor?: any[]; speed?: number; inverse?: boolean };
	let { size = 'w-8 h-8', customColor = [], speed = $bindable(1), inverse = false } = $props();

	const bgClass = () => {
		return inverse ? 'bg-dark dark:bg-primary' : 'bg-primary dark:bg-dark';
	};
	const bgClass2 = () => {
		return inverse ? 'bg-white/50 dark:bg-black/50' : 'bg-black/50 dark:bg-white/50';
	};
</script>

<div class="{size} loading relative m-auto" style="animation-duration: {1.2 / speed}s;-webkit-animation-duration: {1.2 / speed}s;">
	<div
		class="shape1 absolute h-1/2 w-1/2 rounded-tl-full {bgClass()}"
		style="background: {customColor[0]};animation-duration: {0.6 / speed}s;-webkit-animation-duration: {0.6 / speed}s;"
	></div>
	<div
		class="shape2 absolute h-1/2 w-1/2 rounded-tr-full {bgClass2()}"
		style="background: {customColor[1]};animation-duration: {0.6 / speed}s;-webkit-animation-duration: {0.6 / speed}s;"
	></div>
	<div
		class="shape3 absolute h-1/2 w-1/2 rounded-br-full {bgClass()}"
		style="background: {customColor[0]};animation-duration: {0.6 / speed}s;-webkit-animation-duration: {0.6 / speed}s;"
	></div>
	<div
		class="shape4 absolute h-1/2 w-1/2 rounded-bl-full {bgClass2()}"
		style="background: {customColor[1]};animation-duration: {0.6 / speed}s;-webkit-animation-duration: {0.6 / speed}s;"
	></div>
</div>

<style>
	.loading {
		animation: animationContainer 1.2s ease infinite;
	}
	.shape1 {
		animation: animationShape1 0.6s ease infinite alternate;
	}

	.shape2 {
		animation: animationShape2 0.6s ease infinite alternate;
	}

	.shape3 {
		animation: animationShape3 0.6s ease infinite alternate;
	}

	.shape4 {
		animation: animationShape4 0.6s ease infinite alternate;
	}

	@keyframes animationContainer {
		0% {
			transform: rotate(0);
		}

		100% {
			transform: rotate(360deg);
		}
	}
	@keyframes animationShape1 {
		0% {
			top: 0;
			left: 0;
		}
		100% {
			top: -10%;
			left: -10%;
		}
	}

	@keyframes animationShape2 {
		0% {
			top: 0;
			left: 50%;
		}
		100% {
			top: -10%;
			left: 60%;
		}
	}

	@keyframes animationShape3 {
		0% {
			top: 50%;
			left: 50%;
		}
		100% {
			top: 60%;
			left: 60%;
		}
	}

	@keyframes animationShape4 {
		0% {
			top: 50%;
			left: 0;
		}
		100% {
			top: 60%;
			left: -10%;
		}
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/loading/loadings/twoColor/index.ts
================================================
export { default as Loading2_0 } from './2_0.svelte';
export { default as Loading2_1 } from './2_1.svelte';
export { default as Loading2_2 } from './2_2.svelte';
export { default as Loading2_3 } from './2_3.svelte';
export { default as Loading2_4 } from './2_4.svelte';
export { default as Loading2_5 } from './2_5.svelte';



================================================
FILE: packages/stdf/src/lib/components/mask/Mask.svelte
================================================
<script lang="ts">
	import { fade } from 'svelte/transition';
	import type { MaskProps } from '../../types/index.js';

	let {
		visible = false,
		opacity = '0.5',
		clickable = false,
		inverse = false,
		backdropBlur = 'none',
		duration = 150,
		outDuration = 0,
		zIndex = 500,
		children,
		onclickMask
	}: MaskProps = $props();

	//遮罩模糊度样式
	// Mask blur style
	const backdropBlurClass = {
		none: '',
		xs: ' backdrop-blur-xs',
		sm: ' backdrop-blur-sm',
		md: ' backdrop-blur-md',
		lg: ' backdrop-blur-lg',
		xl: ' backdrop-blur-xl',
		'2xl': ' backdrop-blur-2xl',
		'3xl': ' backdrop-blur-3xl'
	};

	// 遮罩背景色
	// Mask background color
	const bgClass = {
		'0': ' bg-transparent',
		'0.1': ' bg-black/10 dark:bg-white/10',
		'0.2': ' bg-black/20 dark:bg-white/20',
		'0.3': ' bg-black/30 dark:bg-white/30',
		'0.4': ' bg-black/40 dark:bg-white/40',
		'0.5': ' bg-black/50 dark:bg-white/50',
		'0.6': ' bg-black/60 dark:bg-white/60',
		'0.7': ' bg-black/70 dark:bg-white/70',
		'0.8': ' bg-black/80 dark:bg-white/80',
		'0.9': ' bg-black/90 dark:bg-white/90',
		'1': ' bg-black dark:bg-white'
	};

	// 遮罩背景色反色
	// Mask background color reverse color
	const bgClassInverse = {
		'0': ' bg-transparent',
		'0.1': ' bg-white/10 dark:bg-black/10',
		'0.2': ' bg-white/20 dark:bg-black/20',
		'0.3': ' bg-white/30 dark:bg-black/30',
		'0.4': ' bg-white/40 dark:bg-black/40',
		'0.5': ' bg-white/50 dark:bg-black/50',
		'0.6': ' bg-white/60 dark:bg-black/60',
		'0.7': ' bg-white/70 dark:bg-black/70',
		'0.8': ' bg-white/80 dark:bg-black/80',
		'0.9': ' bg-white/90 dark:bg-black/90',
		'1': ' bg-white dark:bg-black'
	};
</script>

{#if visible}
	<button
		in:fade|global={{ duration }}
		out:fade|global={{ duration: outDuration }}
		onclick={() => onclickMask && onclickMask?.()}
		class="fixed h-screen w-screen inset-0{inverse
			? bgClassInverse[opacity] || bgClassInverse['0.5']
			: bgClass[opacity] || bgClass['0.5']}{clickable ? ' pointer-events-none' : ''}{backdropBlurClass[backdropBlur] ||
			backdropBlurClass['none']}"
		style="z-index:{zIndex}"
	>
		{@render children?.()}
	</button>
{/if}



================================================
FILE: packages/stdf/src/lib/components/modal/Modal.svelte
================================================
<script lang="ts">
	import { getContext } from 'svelte';
	import Popup from '../popup/Popup.svelte';
	import Button from '../button/Button.svelte';
	import Icon from '../icon/Icon.svelte';
	import { zh_CN, type LangProps } from '../../lang/index.js';
	import type { ModalProps } from '../../types/index.js';

	// 当前语言
	// current language
	const currentLang = (getContext('STDF_lang') || zh_CN) as LangProps;
	const modalLang: LangProps['modal'] = currentLang.modal;

	let {
		visible = $bindable(false),
		title = modalLang.title,
		titleAlign = 'center',
		content = modalLang.content,
		popup = {},
		showIcon = false,
		icon = {},
		showBtn = true,
		btnText = modalLang.btnText,
		button = {},
		contentChild,
		onclose
	}: ModalProps = $props();

	// 标题对齐方式样式
	// Title alignment style
	const titleAlignClass = { left: ' text-left', center: ' text-center', right: ' text-right' };

	// 关闭并派发事件
	// Close and dispatch events
	const closeModalFunc = () => {
		visible = false;
		onclose?.();
	};
</script>

<Popup
	bind:visible
	size={0}
	duration={300}
	outDuration={150}
	maskClosable={!showBtn}
	position="center"
	radiusPosition="all"
	radius="lg"
	px="8"
	{...popup}
>
	<div class="px-4 pt-4 {showBtn ? 'pb-2' : 'pb-4'} space-y-4 text-center">
		<div class="font-bold{titleAlignClass[titleAlign] || titleAlignClass['center']}">{title}</div>
		{#if showIcon}
			<div><Icon {...icon} /></div>
		{/if}
		<div>
			{#if contentChild}
				{@render contentChild()}
			{:else}
				{content}
			{/if}
		</div>
		{#if showBtn}
			<div><Button size="full" {...button} onclick={closeModalFunc}>{btnText}</Button></div>
		{/if}
	</div>
</Popup>



================================================
FILE: packages/stdf/src/lib/components/navBar/NavBar.svelte
================================================
<script lang="ts">
	import { getContext } from 'svelte';
	import Icon from '../icon/Icon.svelte';
	import type { NavBarProps } from '../../types/index.js';
	import { zh_CN, type LangProps } from '../../lang/index.js';

	// 当前语言
	// current language
	const currentLang = (getContext('STDF_lang') || zh_CN) as LangProps;
	const navBarLang: LangProps['navBar'] = currentLang.navBar;

	let {
		title = navBarLang.title,
		titleAlign = 'left',
		left = 'back',
		rights = [],
		line = true,
		injClass = '',
		love = false,
		onclickLeft,
		onclickRight,
		titleChild,
		leftChild,
		rightChild
	}: NavBarProps = $props();

	//图标大小
	//Icon size
	const iconSize = love ? 30 : 24;

	// 标题对齐方式
	// Title alignment
	const titleAlignClass = { left: 'text-left', center: 'text-center', right: 'text-right' };
</script>

<div
	class="flex h-12 w-full justify-between border-black/10 leading-[3rem] dark:border-white/10 {line
		? 'border-b '
		: ' '}bg-white dark:bg-black/50{love ? ' text-xl' : ''}{injClass === '' ? '' : ' ' + injClass}"
>
	{#if leftChild}
		{@render leftChild()}
	{:else if left === 'back'}
		<button class="min-w-[3rem] text-center lining-nums active:opacity-80" onclick={() => onclickLeft && onclickLeft()}>
			<Icon name="ri-arrow-left-s-line" size={iconSize} top={-2} />
		</button>
	{:else if left === null}
		<div class="h-full w-4"></div>
	{:else}
		<button class="min-w-[3rem] text-center lining-nums active:opacity-80" onclick={() => onclickLeft && onclickLeft()}>
			<Icon {...left} />
		</button>
	{/if}
	<div class="flex-1 truncate" class:pl-2={left === null}>
		{#if titleChild}
			{@render titleChild()}
		{:else}
			<div class={titleAlignClass[titleAlign] || titleAlignClass['left']}>{title}</div>
		{/if}
	</div>
	<div class="flex">
		{#if rightChild}
			{@render rightChild()}
		{:else if rights.length > 0}
			{#each rights as icon, i}
				<button class="w-12 text-center active:opacity-80" onclick={() => onclickRight && onclickRight(i)}>
					<Icon {...icon} size={iconSize} />
				</button>
			{/each}
		{:else}{/if}
	</div>
</div>



================================================
FILE: packages/stdf/src/lib/components/noticeBar/NoticeBar.svelte
================================================
<script lang="ts">
	import { onMount } from 'svelte';
	import Icon from '../icon/Icon.svelte';
	import type { NoticeBarProps } from '../../types/index.js';

	let {
		textList = [],
		leftIcon = {},
		rightIcon = 'close',
		fontSize = 'sm',
		space = 100,
		speed = 30,
		vertical = false,
		duration = 500,
		interval = 4,
		injClass = '',
		leftChild,
		rightChild,
		onclickRight
	}: NoticeBarProps = $props();

	// 如果 textList 不是数组给出中英文报错
	// If textList is not an array, give Chinese and English error
	if (!Array.isArray(textList)) {
		console.error('[STDF NoticeBar error]textList 必须是数组。(textList must be an array.)');
	}

	// 如果 textList 为空数组给出中英文报错
	// If textList is an empty array, give Chinese and English error
	if (textList.length === 0) {
		console.error('[STDF NoticeBar error]textList must not be empty.');
	}

	// 字体大小样式
	// Font size style
	const fontSizeClass = { xs: ' text-xs', sm: ' text-sm', base: ' text-base', lg: ' text-lg' };

	// 动画时长样式
	// Animation duration style
	const durationClass = {
		'100': ' duration-100',
		'300': ' duration-300',
		'500': ' duration-500',
		'700': ' duration-700',
		'1000': ' duration-1000'
	};

	let left = $state(speed);
	let boxDom = $state<HTMLDivElement | null>(null);
	let outBoxDom = $state<HTMLDivElement | null>(null);
	let boxWidth = $state(0);
	let outBoxWidth = $state(0);
	let outBoxHeight = $state(0);
	let requestAnimationFrameFlag = $state<number | undefined>(undefined);
	let startTime = 0;
	let fps = 0;

	//垂直滚动时的处理
	//Processing when scrolling vertically
	let times: ReturnType<typeof setInterval>;
	let currentIndex = $state(0);
	let textListVertical = [...textList, textList[0]];
	let isTransition = $state(true);
	const stepFun = (time: number) => {
		fps = time - startTime;
		startTime = time;
		left -= (speed * fps) / 1000;
		requestAnimationFrameFlag = requestAnimationFrame(stepFun);
		if (left < -boxWidth / 2) {
			left = 0;
		}
	};
	let newTextList = $state([...textList, ...textList]);
	onMount(() => {
		if (!vertical) {
			boxWidth = boxDom?.getBoundingClientRect().width || 0;
		}
		outBoxWidth = outBoxDom?.getBoundingClientRect().width || 0;
		outBoxHeight = outBoxDom?.getBoundingClientRect().height || 0;
		if (!vertical && boxWidth / 2 - space < outBoxWidth) {
			newTextList = textList;
			left = 0;
			return;
		}
		requestAnimationFrameFlag = requestAnimationFrame(stepFun);
		if (vertical) {
			if (textListVertical.length > 1) {
				times = setInterval(() => {
					currentIndex++;
					if (currentIndex === textListVertical.length - 1) {
						setTimeout(() => {
							currentIndex = 0;
							isTransition = false;
						}, duration);
					} else {
						isTransition = true;
					}
				}, interval * 1000);
			}
		}
		return () => {
			if (vertical && times !== null) {
				clearInterval(times);
			} else if (requestAnimationFrameFlag) {
				cancelAnimationFrame(requestAnimationFrameFlag);
			}
		};
	});
	let isShow = $state(true);
	let isShowClose = $state(true);
	const clickFun = () => {
		if (rightIcon === 'close') {
			isShow = false;
			setTimeout(() => {
				isShowClose = false;
			}, 200);
		}
		onclickRight?.();
	};
</script>

{#if isShowClose}
	<div
		class="bg-primary/10 text-primary dark:bg-dark/10 flex justify-between dark:text-dark{fontSizeClass[fontSize] ||
			fontSizeClass['sm']} p-2{!rightIcon ? ' pr-2' : ' pr-0'} transition-all duration-300{isShow ? '' : ' scale-0'}{injClass === ''
			? ''
			: ` ${injClass}`}"
	>
		<div class={!leftIcon ? '' : 'mr-1'}>
			{#if leftChild}
				{@render leftChild()}
			{:else if !leftIcon}{:else}
				<Icon name="ri-volume-down-line" size={20} top={-1} {...leftIcon} />
			{/if}
		</div>
		{#if vertical}
			<div class="grow" bind:this={outBoxDom}>
				<div class="relative overflow-hidden" style="height:{outBoxHeight}px;">
					{#each textListVertical as item, i}
						<div
							class="absolute truncate{isTransition ? ' transition-all' : ' transition-none'}{durationClass[duration] ||
								durationClass['500']}"
							style="top:{-(currentIndex - i) * outBoxHeight}px;width:{outBoxWidth}px"
						>
							{item}
						</div>
					{/each}
				</div>
			</div>
		{:else}
			<div class="relative grow overflow-hidden" bind:this={outBoxDom}>
				<div class="absolute whitespace-nowrap" style="left:{left}px" bind:this={boxDom}>
					{#each newTextList as item}
						<div class="inline-block" style="margin-right:{space}px">{item}</div>
					{/each}
				</div>
			</div>
		{/if}
		<button class={!rightIcon ? '' : 'pl-2 pr-4'} onclick={clickFun}>
			{#if rightChild}
				{@render rightChild()}
			{:else if !rightIcon}{:else if rightIcon === 'close'}
				<Icon name="ri-close-line" size={20} top={-1} />
			{:else if rightIcon === 'arrow'}
				<Icon name="ri-arrow-right-s-line" size={20} top={-1} />
			{/if}
		</button>
	</div>
{/if}



================================================
FILE: packages/stdf/src/lib/components/numKeyboard/NumKeyboard.svelte
================================================
<script lang="ts">
	import { getContext } from 'svelte';
	import Popup from '../popup/Popup.svelte';
	import Icon from '../icon/Icon.svelte';
	import { zh_CN, type LangProps } from '../../lang/index.js';
	import type { NumKeyboardProps } from '../../types/index.js';

	// 当前语言
	// current language
	const currentLang = (getContext('STDF_lang') || zh_CN) as LangProps;
	const commonLang: LangProps['common'] = currentLang.common;

	let {
		type = 'button',
		value = $bindable(''),
		visible = $bindable(true),
		height = '12',
		space = '2',
		p = '2',
		reverse = false,
		done = true,
		dot = true,
		close = false,
		doneText = commonLang.done,
		doneDisabled = $bindable(false),
		radius = 'sm',
		clear = false,
		panelClass = '',
		keyClass = '',
		doneClass = '',
		popup = {},
		onclick,
		onopen,
		onclose
	}: NumKeyboardProps = $props();

	// 高度 class
	// Height class
	const heightClass = { '8': 'h-8', '10': 'h-10', '12': 'h-12', '14': 'h-14', '16': 'h-16', '20': 'h-20' };

	// 根据高度动态数字大小
	// Dynamic number size based on height
	const fontSizeClass = { '8': 'text-sm', '10': 'text-base', '12': 'text-xl', '14': 'text-2xl', '16': 'text-2xl', '20': 'text-2xl' };

	// 间距 class
	// spacing class
	const gapClass = { '0': 'gap-0', '1': 'gap-1', '2': 'gap-2', '3': 'gap-3', '4': 'gap-4' };

	// 内边距 class
	// padding class
	const pClass = { '0': 'p-0', '1': 'p-1', '2': 'p-2', '3': 'p-3', '4': 'p-4' };

	// 圆角 class
	// radius class
	const radiusClass = {
		none: 'rounded-none',
		sm: 'rounded-sm',
		md: 'rounded-md',
		lg: 'rounded-lg',
		xl: 'rounded-xl',
		'2xl': 'rounded-2xl',
		'3xl': 'rounded-3xl',
		full: 'rounded-full'
	};

	// 根据 p、gap、height 计算出键盘高度
	// Calculate the keyboard height based on p, gap, height
	const keyboardHeight = () => {
		const pNum = parseInt(p);
		const gapNum = type === 'button' ? parseInt(space) : 0;
		const heightNum = parseInt(height);
		return (pNum * 2 + gapNum * 3 + heightNum * 4) * 4 + (type === 'block' ? 4 : 0);
	};

	// 按钮式 class
	// Button type class
	const buttonClass = `flex flex-col justify-center items-center shadow-xs font-bold active:scale-95 transition-all duration-100 ${
		heightClass[height] || 'h-12'
	} ${fontSizeClass[height] || 'text-base'} ${radiusClass[radius] || 'rounded-sm'}${keyClass ? ' ' + keyClass : ''}`;

	// 块式 class
	// Block type class
	const blockClass = `flex flex-col justify-center items-center font-bold active:opacity-40 transition-all duration-100 ${
		heightClass[height] || 'h-12'
	} ${fontSizeClass[height] || 'text-base'}${keyClass ? ' ' + keyClass : ''}`;

	// 根据 type 类型，生成不同的基础样式
	// Generate different basic styles based on type type
	const baseClassFunc = (key: string | number) => {
		if (type === 'button') {
			return key === 'done' ? buttonClass : 'bg-white dark:bg-gray-700 ' + buttonClass;
		} else {
			return key === 'done' ? blockClass : 'bg-white dark:bg-gray-700 ' + blockClass;
		}
	};

	// 处理 0 占据的格数
	// Handle the number of grids occupied by 0
	const zeroColFunc = () => {
		// 不显示完成，右下角显示删除按钮，0 最多占 2 格
		// If you don't show it, the delete button will be displayed in the lower right corner, and 0 will occupy up to 2 grids
		if (!done) {
			return dot || close ? 'col-span-1' : 'col-span-2';
		} else {
			return dot && close ? 'col-span-1' : dot || close ? 'col-span-2' : 'col-span-3';
		}
	};

	// 点击按键事件
	// Click the button event
	const clickFunc = (key: string) => {
		// 当 key 不是 close 或 done 时，拼接字符串，是删除时，删除最后一个字符
		// When key is not close or done, splice the string, delete the last character when it is deleted
		if (key !== 'close' && key !== 'done') {
			if (key === 'delete') {
				value = value.slice(0, value.length - 1);
			} else {
				value += key;
			}
		}
		// close 和 done 事件都会关闭
		// Both close and done events will be closed
		if (key === 'close' || (key === 'done' && !doneDisabled)) {
			visible = false;
		}
		// 派发事件，传递出两个参数，输入的数字字符串和本次点击的类型
		// Dispatch events, pass out two parameters, the input number string and the type of this click
		onclick?.(key);
	};

	// 激活与关闭键盘事件
	// Activate and close the keyboard event
	$effect(() => {
		if (visible) {
			if (clear) {
				value = '';
			}
			onopen?.(keyboardHeight());
		} else {
			onclose?.();
		}
	});
</script>

<Popup bind:visible size={0} mask={{ opacity: '0' }} transitionDistance={keyboardHeight()} {...popup}>
	<div
		class="bg-gray-100 text-center dark:bg-gray-950 {type === 'block' ? 'border-t border-gray-100 dark:border-gray-950' : ''} {pClass[p] ||
			'p-2'}{panelClass ? ' ' + panelClass : ''}"
	>
		<div class="grid {type === 'button' ? gapClass[space] || 'gap-2' : 'gap-px'} {done ? 'grid-cols-4' : 'grid-cols-3'}">
			{#each reverse ? ['7', '8', '9'] : ['1', '2', '3'] as item}
				<button class={baseClassFunc(item)} onclick={() => clickFunc(item)}>{item} </button>
			{/each}
			{#if done}
				<button class={baseClassFunc('delete')} onclick={() => clickFunc('delete')}>
					<Icon name="ri-delete-back-2-line" size={Number(height) * 2} />
				</button>
			{/if}
			{#each ['4', '5', '6'] as item}
				<button class={baseClassFunc(item)} onclick={() => clickFunc(item)}>{item} </button>
			{/each}
			{#if done}
				<button
					class="{baseClassFunc('done')} bg-primary dark:bg-dark row-span-3 h-full text-white dark:text-black {doneDisabled
						? '!opacity-50 transition-none active:!scale-100'
						: ''}{doneClass ? '' + doneClass : ''}"
					onclick={() => clickFunc('done')}
				>
					{doneText}
				</button>
			{/if}
			{#each reverse ? ['1', '2', '3'] : ['7', '8', '9'] as item}
				<button class={baseClassFunc(item)} onclick={() => clickFunc(item)}>{item} </button>
			{/each}
			{#if dot}
				<button class={baseClassFunc('.')} onclick={() => clickFunc('.')}>.</button>
			{/if}
			{#if done ? close : !dot && close}
				<button class={baseClassFunc('close')} onclick={() => clickFunc('close')}>
					<Icon name="ri-skip-down-line" size={Number(height) * 2} />
				</button>
			{/if}
			<button class={baseClassFunc('0') + ' ' + zeroColFunc()} onclick={() => clickFunc('0')}>0</button>
			{#if !done}
				<button class={baseClassFunc('delete')} onclick={() => clickFunc('delete')}>
					<Icon name="ri-delete-back-2-line" size={Number(height) * 2} />
				</button>
			{/if}
		</div>
	</div>
</Popup>



================================================
FILE: packages/stdf/src/lib/components/pagination/Page.svelte
================================================
<script lang="ts">
	import type { Snippet } from 'svelte';

	type Props = {
		active?: boolean;
		radius?: 'sm' | 'md' | 'lg' | 'xl' | 'full' | 'none';
		type?: 'border' | 'block' | 'bold';
		children?: Snippet;
		onclick?: () => void;
	};
	let { active = false, radius = 'md', type = 'border', children, onclick }: Props = $props();

	const typeClass = {
		border: 'border-primary dark:border-dark text-primary dark:text-dark',
		block: 'bg-primary text-white dark:bg-dark dark:text-black',
		bold: 'font-bold text-primary dark:text-dark border-transparent'
	};

	const radiusClass = {
		sm: 'rounded-sm',
		md: 'rounded-md',
		lg: 'rounded-lg',
		xl: 'rounded-xl',
		full: 'rounded-full',
		none: 'rounded-none'
	};
</script>

<button
	{onclick}
	class="flex-1 border py-2 {active
		? typeClass[type] || typeClass.border
		: 'border-transparent' + (type === 'bold' ? ' opacity-50' : '')} {radiusClass[radius] || radiusClass.md}"
>
	{@render children?.()}
</button>



================================================
FILE: packages/stdf/src/lib/components/pagination/Pagination.svelte
================================================
<script lang="ts">
	import { getContext } from 'svelte';
	import Icon from '../icon/Icon.svelte';
	import Page from './Page.svelte';
	import SecondPageNext from './SecondPageNext.svelte';
	import SecondPagePre from './SecondPagePre.svelte';
	import { zh_CN, type LangProps } from '../../lang/index.js';
	import type { PaginationProps } from '../../types/index.js';

	// 当前语言
	// current language
	const currentLang = (getContext('STDF_lang') || zh_CN) as LangProps;
	const commonLang: LangProps['common'] = currentLang.common;
	const paginationLang: LangProps['pagination'] = currentLang.pagination;

	let {
		total = 0,
		pageSize = 10,
		current = $bindable(1),
		maxShowPage = 7,
		radius = 'md',
		type = 'bold',
		pageCol = 3,
		showNextOmitPage = $bindable(false),
		showPreOmitPage = $bindable(false),
		injClass = '',
		noDataText = commonLang.noData,
		onePageText = paginationLang.defaultOnlyOnePage,
		continuous = false,
		onchange,
		onnext,
		onpre
	}: PaginationProps = $props();

	// 总页数
	// totalPage
	let totalPage = $derived(Math.ceil(total / pageSize));

	// 当前页码大于等于 maxShowPage-3 时，不显示前面的省略号
	// current >= maxShowPage-3, not show pre ellipsis
	let showPreEllipsis = $derived(current > maxShowPage - 2);

	// 当前页码小于等于 totalPage - (maxShowPage-3) 时，不显示后面的省略号
	// current <= totalPage - (maxShowPage-3), not show next ellipsis
	let showNextEllipsis = $derived(current <= maxShowPage - 2 || current <= totalPage - (maxShowPage - 3));

	// 当显示前面的省略号时，中间显示的页码数 middleShowPage 个数为 maxShowPage - 4，内容为当前页码（maxShowPage为5）或者当前页码和前后一项（maxShowPage为7）或者当前页码和前后两项（maxShowPage为9）
	// when show pre ellipsis, middleShowPage length is maxShowPage - 4, content is current page (maxShowPage is 5) or current page and pre/next one (maxShowPage is 7) or current page and pre/next two (maxShowPage is 9)
	let middleShowPage = $state<number[]>([]);

	// 前省略号内页码数组
	// pre ellipsis page array
	let preEllipsisPages = $state<number[]>([]);

	// 后省略号内页码数组
	// next ellipsis page array
	let nextEllipsisPages = $state<number[]>([]);

	$effect(() => {
		// 当页码变化时对一系列数据动态计算
		// Dynamic calculation of a series of data when the page number changes
		if (showPreEllipsis && showNextEllipsis) {
			if (maxShowPage === 5) {
				middleShowPage = [current];
			} else if (maxShowPage === 7) {
				middleShowPage = [current - 1, current, current + 1];
			} else if (maxShowPage === 9) {
				middleShowPage = [current - 2, current - 1, current, current + 1, current + 2];
			} else if (maxShowPage === 11) {
				middleShowPage = [current - 3, current - 2, current - 1, current, current + 1, current + 2, current + 3];
			}
		} else {
			middleShowPage = [];
		}
	});

	$effect(() => {
		// 当仅显示后省略号时
		// when only show next ellipsis
		if (!showPreEllipsis && showNextEllipsis) {
			// 此时 nextEllipsisPages 为 maxShowPage - 2 到 总页码数 - 1
			// nextEllipsisPages is maxShowPage - 2 to total page - 1
			nextEllipsisPages = Array.from({ length: totalPage }, (v, k) => k + 1).slice(maxShowPage - 2, totalPage - 1);
		}
	});
	$effect(() => {
		// 当仅显示前省略号时
		// when only show pre ellipsis
		if (showPreEllipsis && !showNextEllipsis) {
			// 此时 preEllipsisPages 为 2 到 总页码数 - (maxShowPage-2)
			// preEllipsisPages is 2 to total page - (maxShowPage-2)
			preEllipsisPages = Array.from({ length: totalPage }, (v, k) => k + 1).slice(1, totalPage - (maxShowPage - 2));
		}
	});
	$effect(() => {
		// 当显示前后省略号时
		// when show pre and next ellipsis
		if (showPreEllipsis && showNextEllipsis) {
			// 此时 nextEllipsisPages 为 middleShowPage 最后一项 +1，到总页码数组的最后第二项
			// nextEllipsisPages is middleShowPage last item +1, to total page array last second item
			nextEllipsisPages = Array.from({ length: totalPage }, (v, k) => k + 1).slice(
				middleShowPage[middleShowPage.length - 1],
				totalPage - 1
			);
			// 此时 preEllipsisPages 为 2 到 middleShowPage 第一项 -1
			// preEllipsisPages is 2 to middleShowPage first item -1
			preEllipsisPages = Array.from({ length: totalPage }, (v, k) => k + 1).slice(1, middleShowPage[0] - 1);
		}
	});

	$effect(() => {
		// 特殊情况处理
		// Special case handling
		if (totalPage <= maxShowPage) {
			showNextOmitPage = false;
		}
	});

	// 点击后省略号事件
	// click next ellipsis event
	const clickNextEllipsisFunc = () => {
		if (nextEllipsisPages.length > 0) {
			showNextOmitPage = !showNextOmitPage;
		}
	};

	// 点击前省略号事件
	// click pre ellipsis event
	const clickPreEllipsisFunc = () => {
		if (preEllipsisPages.length > 0) {
			showPreOmitPage = !showPreOmitPage;
		}
	};

	// 页码改变的回调，参数是改变后的页码及每页条数
	// onChange
	const onChangeFn = () => {
		showNextOmitPage = false;
		showPreOmitPage = false;
		onchange?.(current);
	};

	// 点击下一页
	// click next page
	const nextFunc = () => {
		if (current < totalPage) {
			current++;
			onnext?.(current);
			onChangeFn();
		}
	};

	// 点击上一页
	// click pre page
	const preFunc = () => {
		if (current > 1) {
			current--;
			onpre?.(current);
			onChangeFn();
		}
	};

	// 点击页码
	// click page
	const clickItemFunc = (index: number) => {
		current = index;
		onChangeFn();
	};

	// 点击省略页码事件
	// click second page item event
	const clickSecondPageItemFunc = (index: number) => {
		current = index;
		showNextOmitPage = false;
		showPreOmitPage = false;
		onChangeFn();
	};

	// 类型样式
	// type class
	const typeClass = {
		border: 'border-primary dark:border-dark text-primary dark:text-dark',
		block: 'bg-primary text-white dark:bg-dark dark:text-black',
		bold: 'font-bold text-primary dark:text-dark border-transparent'
	};

	// 圆角样式
	// radius class
	const radiusClass = {
		sm: 'rounded-sm',
		md: 'rounded-md',
		lg: 'rounded-lg',
		xl: 'rounded-xl',
		full: 'rounded-full',
		none: 'rounded-none'
	};
</script>

<div class="relative flex justify-between bg-white py-1 text-center text-sm dark:bg-black {injClass}">
	<button
		class="flex-1 border border-transparent py-2 transition-all {current > 1
			? 'text-primary dark:text-dark'
			: 'text-primary/30 dark:text-dark/30'} {radiusClass[radius] || radiusClass.md} active:scale-75"
		onclick={preFunc}
	>
		<Icon name="ri-arrow-left-s-line" size={18} />
	</button>
	{#if totalPage === 0}
		<div class="flex-1 border border-transparent py-2">{noDataText}</div>
	{:else if totalPage === 1}
		<div class="flex-1 border border-transparent py-2">{onePageText}</div>
	{:else if totalPage > 1 && totalPage <= maxShowPage}
		<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
		{#each new Array(totalPage) as _, index}
			<Page active={current === index + 1} {type} {radius} onclick={() => !continuous && clickItemFunc(index + 1)}>
				{index + 1}
			</Page>
		{/each}
	{:else}
		<Page active={current === 1} {type} {radius} onclick={() => !continuous && clickItemFunc(1)}>1</Page>
		{#if showPreEllipsis}
			<button
				class="flex-1 border py-2 {showPreOmitPage
					? typeClass[type] || typeClass.border
					: 'border-transparent' + (type === 'bold' ? ' opacity-50' : '')} {radiusClass[radius] || radiusClass.md}"
				onclick={() => !continuous && clickPreEllipsisFunc()}
			>
				{#if type === 'bold' && showPreOmitPage}
					<Icon name="ri-more-fill" size={18} />
				{:else}
					<Icon name="ri-more-line" size={18} />
				{/if}
			</button>
		{/if}
		{#if !showPreEllipsis && current <= maxShowPage - 1}
			<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
			{#each new Array(maxShowPage - 3) as _, index}
				<Page active={current === index + 2} {type} {radius} onclick={() => !continuous && clickItemFunc(index + 2)}>
					{index + 2}
				</Page>
			{/each}
		{/if}
		{#if middleShowPage.length > 0}
			{#each middleShowPage as item, index}
				<Page active={index === (middleShowPage.length - 1) / 2} {type} {radius} onclick={() => !continuous && clickItemFunc(item)}>
					{item}
				</Page>
			{/each}
		{/if}
		{#if !showNextEllipsis && current > totalPage - (maxShowPage - 3)}
			<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
			{#each new Array(maxShowPage - 3) as _, index}
				<Page
					active={current === totalPage + index + 3 - maxShowPage}
					{type}
					{radius}
					onclick={() => !continuous && clickItemFunc(totalPage + index + 3 - maxShowPage)}
				>
					{totalPage + index + 3 - maxShowPage}
				</Page>
			{/each}
		{/if}
		{#if showNextEllipsis}
			<button
				class="flex-1 border py-2 {showNextOmitPage
					? typeClass[type] || typeClass.border
					: 'border-transparent' + (type === 'bold' ? ' opacity-50' : '')} {radiusClass[radius] || radiusClass.md}"
				onclick={() => !continuous && clickNextEllipsisFunc()}
			>
				{#if type === 'bold' && showNextOmitPage}
					<Icon name="ri-more-fill" size={18} />
				{:else}
					<Icon name="ri-more-line" size={18} />
				{/if}
			</button>
		{/if}
		<Page active={current === totalPage} {type} {radius} onclick={() => !continuous && clickItemFunc(totalPage)}>{totalPage}</Page>
	{/if}
	<button
		class="flex-1 border border-transparent py-2 transition-all {current < totalPage
			? 'text-primary dark:text-dark'
			: 'text-primary/30 dark:text-dark/30'} {radiusClass[radius] || radiusClass.md} active:scale-75"
		onclick={nextFunc}
	>
		<Icon name="ri-arrow-right-s-line" size={20} />
	</button>
	{#if showNextOmitPage}
		<SecondPageNext {pageCol} Pages={nextEllipsisPages} {type} {radius} onclickItem={clickSecondPageItemFunc} {maxShowPage} />
	{/if}
	{#if showPreOmitPage}
		<SecondPagePre {pageCol} Pages={preEllipsisPages} {type} {radius} onclickItem={clickSecondPageItemFunc} {maxShowPage} />
	{/if}
</div>



================================================
FILE: packages/stdf/src/lib/components/pagination/SecondPageNext.svelte
================================================
<script lang="ts">
	import Page from './Page.svelte';

	type Props = {
		pageCol: number;
		Pages: number[];
		maxShowPage: number;
		radius: 'sm' | 'md' | 'lg' | 'xl' | 'full' | 'none';
		type: 'border' | 'block' | 'bold';
		onclickItem: (index: number) => void;
	};
	let { pageCol = 3, Pages = [], maxShowPage = 9, radius = 'md', type = 'bold', onclickItem }: Props = $props();
</script>

{#if Pages.length > 0}
	<div
		class="second-page-contents absolute -top-3 grid max-h-[7.25rem] -translate-y-full translate-x-1/2 gap-y-2 divide-x overflow-y-auto rounded-lg bg-white p-1 shadow-sm dark:bg-black dark:shadow-white/10"
		style="width: calc({(pageCol / (maxShowPage + 2)) * 100}% + 8px);right:{(2.5 / (maxShowPage + 2)) *
			100}%;grid-template-columns: repeat({pageCol}, minmax(0, 1fr));"
	>
		{#each Pages as item}
			<Page onclick={() => onclickItem && onclickItem(item)} {type} {radius}>{item}</Page>
		{/each}
	</div>
	<div
		class="absolute -top-3 h-0 w-0 translate-x-1/2 border-8 border-t-8 border-transparent border-t-white dark:border-t-black"
		style="right:{(2.5 / (maxShowPage + 2)) * 100}%;"
	></div>
{/if}

<style>
	.second-page-contents::-webkit-scrollbar {
		display: none; /* Chrome Safari */
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/pagination/SecondPagePre.svelte
================================================
<script lang="ts">
	import Page from './Page.svelte';

	type Props = {
		pageCol: number;
		Pages: number[];
		maxShowPage: number;
		radius: 'sm' | 'md' | 'lg' | 'xl' | 'full' | 'none';
		type: 'border' | 'block' | 'bold';
		onclickItem: (index: number) => void;
	};
	let { pageCol = 3, Pages = [], maxShowPage = 7, radius = 'md', type = 'bold', onclickItem }: Props = $props();
</script>

{#if Pages.length > 0}
	<div
		class="second-page-contents absolute -top-3 grid max-h-[7.25rem] -translate-x-1/2 -translate-y-full gap-y-2 overflow-y-auto rounded-lg bg-white p-1 shadow-sm dark:bg-black dark:shadow-white/10"
		style="width: calc({(pageCol / (maxShowPage + 2)) * 100}% + 8px);left:{(2.5 / (maxShowPage + 2)) *
			100}%;grid-template-columns: repeat({pageCol}, minmax(0, 1fr));"
	>
		{#each Pages as item}
			<Page onclick={() => onclickItem && onclickItem(item)} {type} {radius}>{item}</Page>
		{/each}
	</div>
	<div
		class="absolute -top-3 h-0 w-0 -translate-x-1/2 border-8 border-t-8 border-transparent border-t-white dark:border-t-black"
		style="left:{(2.5 / (maxShowPage + 2)) * 100}%;"
	></div>
{/if}

<style>
	.second-page-contents::-webkit-scrollbar {
		display: none; /* Chrome Safari */
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/picker/Picker.svelte
================================================
<script lang="ts">
	import { getContext } from 'svelte';
	import Popup from '../popup/Popup.svelte';
	import ScrollRadio from '../scrollRadio/ScrollRadio.svelte';
	import { zh_CN, type LangProps } from '../../lang/index.js';
	import type { PickerProps, PickerDatasProps, PickerDataChildProps } from '../../types/index.js';

	// 当前语言
	// current language
	const currentLang: LangProps = getContext('STDF_lang') || zh_CN;
	const pickerLang: LangProps['picker'] = currentLang.picker;

	let {
		visible = $bindable(false),
		datas = [],
		autoScrollToLast = true,
		cancelText = pickerLang.defaultCancel,
		confirmText = pickerLang.defaultConfirm,
		title = pickerLang.defaultTitle,
		isLinkage = false,
		linkageInitIndexs = [],
		linkageShowRows = [],
		linkageFlexs = [],
		linkageLabelKeys = [],
		linkageAligns = [],
		linkageChildrenKey = 'children',
		popup = {},
		onclose,
		onconfirm,
		oncancel
	}: PickerProps = $props();

	// 内部使用的 datas
	// Datas used internally
	let newDatas: PickerDatasProps[] | PickerDataChildProps[] = $state(datas);
	// $effect(() => {
	// 	newDatas = datas;
	// });

	// 如果是多级联动，对 newDatas 进行处理，使其结构符合 ScrollRadio 组件的结构
	// If it is multi-level linkage, process newDatas to make its structure conform to the structure of the ScrollRadio component
	if (isLinkage) {
		const newLinkageData: PickerDatasProps[] = [];
		// 多级联动时递归处理 newDatas，取原始数据每一级的第一条数据，组成新的数据结构
		// When multi-level linkage, recursively process newDatas to take the first piece of data in each level of the original data to form a new data structure
		const newDatasFormatFunc = (data: PickerDatasProps[] | PickerDataChildProps[], index: number) => {
			if (data && data.length > 0) {
				const newData = data.map((item: PickerDatasProps | PickerDataChildProps) => {
					const label = linkageLabelKeys[index]
						? (item as Record<string, string>)[linkageLabelKeys[index]]
						: (item as { label: string }).label;
					return { label };
				});
				newLinkageData.push({ data: newData, showRow: 5, labelKey: 'label' });
				if (data[0] && typeof data[0] === 'object' && linkageChildrenKey in data[0]) {
					const children = (data[0] as { [key: string]: PickerDataChildProps[] })[linkageChildrenKey];
					newDatasFormatFunc(children, index + 1);
				}
			}
		};
		if (datas.length > 0) {
			newDatasFormatFunc(datas, 0);
			newDatas = newLinkageData;
		}
	}
	let scrollEndIndexs: number[] = [];
	let lastSelectedIndexs: number[] = $state([]);
	let showRowsArr: number[] = [];

	const initFn = () => {
		// 对 datas 处理，如果没有设置 initIndex 则默认为 0，如果没有设置 showRow 则默认为 5
		// Process datas, if initIndex is not set, it is default to 0, if showRow is not set, it is default to 5
		newDatas = newDatas.map((item, index) => {
			if (!item.initIndex) {
				(item as PickerDatasProps).initIndex = 0;
			}
			if (!item.showRow) {
				item.showRow = 5;
			}
			if (!(item as PickerDatasProps).lastSelectedIndex) {
				(item as PickerDatasProps).lastSelectedIndex = 0;
			}
			if (!item.flex) {
				item.flex = 1;
			}
			if (!item.align) {
				item.align = 'center';
			}
			if (isLinkage) {
				if (linkageInitIndexs[index]) {
					item.initIndex = linkageInitIndexs[index];
				} else {
					item.initIndex = 0;
				}
				if (linkageShowRows[index]) {
					(item as PickerDatasProps).showRow = linkageShowRows[index] as 3 | 5 | 7;
				}
				if (linkageFlexs[index]) {
					item.flex = linkageFlexs[index];
				}
				if (linkageAligns[index]) {
					item.align = linkageAligns[index];
				}
				if (!item.lastSelectedIndex) {
					item.lastSelectedIndex = 0;
				}
			}
			return item;
		}) as PickerDatasProps[];
		// 滚动结束时选中项组成的数组
		// An array of selected items when scrolling ends
		scrollEndIndexs = newDatas.map((item: PickerDatasProps | PickerDataChildProps) => item.initIndex as number);

		// 上次所有选中项，由上次单列选中项组成的数组，初始值为 datas 中每项的 initIndex
		// All last selected items, an array of last single column selected items, the initial value is the initIndex of each item in datas
		lastSelectedIndexs = newDatas.map((item) => item.initIndex as number);

		// 循环 newDatas，将 每项的 showRow 组成一个数组 showRowsArr
		// Loop newDatas to form an array showRowsArr of each item's showRow
		showRowsArr = newDatas.map((item) => item.showRow as number);
	};
	initFn();

	// 找出 showRowsArr 中最大值
	// Find the maximum value in showRowsArr
	const maxShowRows = showRowsArr.length > 0 ? Math.max(...showRowsArr.filter((n): n is number => typeof n === 'number')) : 5;

	// 多级联动时，根据当前选中项的索引，需要知道滚动的上级、当前级、下级以及所有级的数据
	// When multi-level linkage, according to the index of the currently selected item, you need to know the data of the scrolling upper level, current level, next level and all levels
	let preLevelData: PickerDataChildProps[] | PickerDatasProps[] = [];
	let currentLevelData: PickerDataChildProps[] | PickerDatasProps[] = [];
	// let nextLevelData = [];
	let allLevelData: (PickerDataChildProps[] | PickerDatasProps[])[] = [];

	// 根据原始数据 datas 的层级，allLevelData 的长度为 datas 的层级，递归处理 datas 中每一级直至没有 children，将每一级的第一项取出，放到 allLevelData 中
	// According to the level of the original data datas, the length of allLevelData is the level of datas, and the data in each level of datas is processed recursively until there is no children, and the first item of each level is taken out and placed in allLevelData
	const getAllLevelDataFunc = (data: PickerDatasProps[] | PickerDataChildProps[], level: number) => {
		if (data && data.length > 0) {
			if (!allLevelData[level]) {
				allLevelData[level] = [];
			}
			// 使用类型断言确保类型安全
			const firstItem = data[0] as PickerDatasProps & PickerDataChildProps;
			allLevelData[level].push(firstItem);
			if (linkageChildrenKey in firstItem && firstItem[linkageChildrenKey]) {
				getAllLevelDataFunc(firstItem[linkageChildrenKey] as PickerDataChildProps[], level + 1);
			}
		}
	};
	if (isLinkage) {
		getAllLevelDataFunc(datas, 0);
	}

	// 点击取消按钮
	// Click cancel button
	const clickCancelFunc = () => {
		visible = false;
		oncancel?.();
		onclose?.();
	};

	// 点击确定按钮
	// Click confirm button
	const clickConfirmFunc = () => {
		visible = false;
		onclose?.();
		lastSelectedIndexs = scrollEndIndexs;
		let items: { [key: string]: string }[] = [];
		if (isLinkage) {
			// 获取 lastSelectedIndexs 的长度为 n，取 allLevelData 前面的 n 项，作为暂时数组 tempItems
			// Get the length of lastSelectedIndexs as n, take the first n items of allLevelData as the temporary array tempItems
			const tempItems = allLevelData.slice(0, lastSelectedIndexs.length);
			// 将 tempItems 中的每一项按照 lastSelectedIndexs 的索引取出，组成一个新数组 items
			// Take each item in tempItems out according to the index of lastSelectedIndexs to form a new array items
			items = tempItems.map((item: PickerDatasProps[] | PickerDataChildProps[], index: number) => {
				const selectedIndex = lastSelectedIndexs[index];
				if (Array.isArray(item)) {
					return item[selectedIndex] as { [key: string]: string };
				}
				return item;
			});
		} else {
			// 循环 datas 与 scrollEndIndexs，按照 scrollEndIndexs 将 datas 中的 data 对应的��组成一个新数组
			// Loop datas and scrollEndIndexs to form a new array of values corresponding to data in datas according to scrollEndIndexs
			items = datas.map((item: PickerDatasProps | PickerDataChildProps, index: number) => {
				const data = (item as PickerDatasProps).data;
				if (Array.isArray(data)) {
					return data[scrollEndIndexs[index]] as { [key: string]: string };
				}
				return data as { [key: string]: string };
			}) as { [key: string]: string }[];
		}
		onconfirm?.(items, lastSelectedIndexs);
	};

	// 滚动结束
	// Scroll end
	const scrollEndFunc = (i: number, col: number) => {
		// col 为当前滚动结束的列的索引
		// index 为当前滚动结束的列的选中项的索引
		const index = i;
		scrollEndIndexs[col] = index;
		if (isLinkage) {
			// 任何列滚动之后，使传入的 linkageInitIndexs 都会失效，将所有下级的初始选中项设置为 0
			// After any column scrolls, the linkageInitIndexs passed in will all be invalid, and set the initial selected item of all lower levels to 0
			for (let i = col + 1; i < newDatas.length; i++) {
				newDatas[i].initIndex = 0;
			}
			// 递归计算当前列的数据
			// Recursively calculate the data of the current column
			if (col === 0) {
				preLevelData = [];
				currentLevelData = datas as PickerDatasProps[];
				allLevelData[0] = datas as PickerDatasProps[];
			} else {
				preLevelData = allLevelData[col - 1] as PickerDatasProps[];
				if (preLevelData[scrollEndIndexs[col - 1]]) {
					const children = preLevelData[scrollEndIndexs[col - 1]][linkageChildrenKey as keyof PickerDatasProps] as PickerDataChildProps[];
					currentLevelData = Array.isArray(children) ? (children as PickerDataChildProps[]) : [];
				} else {
					currentLevelData = [];
				}
			}
			// 递归计算后面的所有列数据
			// Tail recursion to calculate the data of all columns behind
			const recursionFunc = (col: number, currentLevelData: PickerDataChildProps[] | PickerDatasProps[]) => {
				const nextCol = col + 1;
				if (nextCol < newDatas.length) {
					const nextLevelData =
						currentLevelData.length === 1
							? currentLevelData[0]
								? (currentLevelData[0] as PickerDatasProps)[linkageChildrenKey as keyof PickerDatasProps]
								: []
							: currentLevelData[index]
								? ((currentLevelData[index] as PickerDatasProps)[linkageChildrenKey as keyof PickerDatasProps] as PickerDataChildProps[])
								: [];
					if (nextLevelData && Array.isArray(nextLevelData) && nextLevelData.length > 0) {
						const nextData = (nextLevelData as PickerDataChildProps[]).map((item: PickerDataChildProps) =>
							linkageLabelKeys[col + 1] ? { label: item[linkageLabelKeys[col + 1]] } : { label: item.label }
						);
						// 将数据置空，此列数据为空，此列将立即消失，然后通过 setTimeout 立即设置数据，使得数据更新后，此列才会出现
						// Set the data to empty, the data of this column is empty, this column will disappear immediately, and then set the data immediately through setTimeout, so that the data is updated, this column will appear
						newDatas[nextCol].data = [];
						setTimeout(() => {
							newDatas[nextCol].data = nextData;
						});
						allLevelData[nextCol] = nextLevelData;
						recursionFunc(nextCol, nextLevelData);
					} else {
						// 如果下一级没数据，则将下一级的数据置空
						// If there is no data in the next level, set the data of the next level to empty
						// 也可以用来解决数据层级超级大的时候，递归计算数据的性能问题，暂时将后面的数据置空，等到有数据的时候再设置，避免选择数据与视图不同步的问题
						// It can also be used to solve the performance problem of recursive calculation of data when the data hierarchy is super large. Temporarily set the data behind to empty, and set it when there is data, to avoid the problem that the selected data and the view are not synchronized
						newDatas[nextCol].data = [];
					}
				}
			};
			recursionFunc(col, currentLevelData);
		}
	};
</script>

<Popup
	bind:visible
	size={0}
	maskClosable
	transitionDistance={(maxShowRows === 3 ? 64 : maxShowRows === 5 ? 48 : 32) * maxShowRows + 41}
	{...popup}
>
	<div class="flex items-center justify-between border-b border-black/10 bg-white dark:border-white/20 dark:bg-black">
		<button class="h-10 cursor-pointer px-4 leading-10 text-black/60 dark:text-white/60" onclick={clickCancelFunc}>{cancelText}</button>
		<div>{title}</div>
		<button class="h-10 cursor-pointer px-4 leading-10 text-primary dark:text-dark" onclick={clickConfirmFunc}>{confirmText}</button>
	</div>
	<div class="flex items-center justify-around gap-1 bg-white dark:bg-black">
		{#each newDatas as item, col}
			<div class="truncate" style="flex:{item.flex || 1}">
				{#if (item as PickerDatasProps).data.length > 0}
					<ScrollRadio
						{...item}
						lastSelectedIndex={lastSelectedIndexs[col]}
						{autoScrollToLast}
						onscrollEnd={(index) => scrollEndFunc(index, col)}
					/>
				{/if}
			</div>
		{/each}
	</div>
</Popup>



================================================
FILE: packages/stdf/src/lib/components/placeholder/Placeholder.svelte
================================================
<script lang="ts">
	import type { PlaceholderProps } from '../../types/index.js';

	let { py = '4', height = 'full', radius = 'md', shadow = 'none', injClass = '', children }: PlaceholderProps = $props();

	// 上下内边距样式
	// up down padding style
	const pyObj = { '0': ' py-0', '1': ' py-1', '2': ' py-2', '3': ' py-3', '4': ' py-4', '8': ' py-8' };

	// 阴影样式
	// shadow style
	const shadowObj = {
		none: ' shadow-none',
		xs: ' shadow-xs dark:shadow-white/5',
		sm: 'shadow-sm dark:shadow-white/10',
		md: ' shadow-md dark:shadow-white/10',
		lg: ' shadow-lg dark:shadow-white/10',
		xl: ' shadow-xl dark:shadow-white/10',
		'2xl': ' shadow-2xl dark:shadow-white/20'
	};

	// 圆角样式
	// radius style
	const radiusObj = {
		none: ' rounded-none',
		sm: ' rounded-sm',
		md: ' rounded-md',
		xl: ' rounded-xl',
		'2xl': ' rounded-2xl',
		'3xl': ' rounded-3xl',
		full: ' rounded-full'
	};

	// 高度样式
	// height style
	const heightObj = {
		full: ' h-full',
		'1': ' h-1',
		'2': ' h-2',
		'4': ' h-4',
		'8': ' h-8',
		'16': ' h-16',
		'24': ' h-24',
		'32': ' h-32',
		'48': ' h-48',
		'64': ' h-64',
		'96': ' h-96'
	};
</script>

<div
	class="flex flex-col justify-center bg-black/5 dark:bg-white/5 text-center{heightObj[height] || heightObj.full}{pyObj[py] ||
		pyObj['4']}{radiusObj[radius] || radiusObj.md}{shadowObj[shadow] || shadowObj.none}{injClass === '' ? '' : ` ${injClass}`}"
>
	{@render children?.()}
</div>



================================================
FILE: packages/stdf/src/lib/components/popup/Popup.svelte
================================================
<script lang="ts">
	import * as eases from 'svelte/easing';
	import Mask from '../mask/Mask.svelte';
	import Transition from './Transition.svelte';
	import type { PopupProps } from '../../types/index.js';

	let {
		visible = $bindable(false),
		size = 40,
		position = 'bottom',
		duration = 450,
		outDuration = 240,
		easeType = 'cubicOut',
		easeOutType = 'cubicOut',
		px = '0',
		py = '0',
		mask = {},
		maskClosable = true,
		radiusPosition = 'top',
		radius = 'none',
		transitionDistance = 0,
		transparent = false,
		allowBodyScroll = false,
		zIndex = 600,
		dynamicFixed = true,
		hideScrollbar = false,
		children,
		onclose,
		onclickMask
	}: PopupProps = $props();

	// 通过不同位置结合圆角参数，生成不同的 class
	// Generate different classes by combining different positions and corner parameters
	const radiusFun = () => {
		const radioMap = {
			none: 'rounded-none',
			sm: 'rounded-sm',
			md: 'rounded-md',
			lg: 'rounded-lg',
			xl: 'rounded-xl',
			'2xl': 'rounded-2xl',
			'3xl': 'rounded-3xl',
			full: 'rounded-full'
		};
		const radiusTopMap = {
			none: 'rounded-t-none',
			sm: 'rounded-t-sm',
			md: 'rounded-t-md',
			lg: 'rounded-t-lg',
			xl: 'rounded-t-xl',
			'2xl': 'rounded-t-2xl',
			'3xl': 'rounded-t-3xl',
			full: 'rounded-t-full'
		};
		const radiusBottomMap = {
			none: 'rounded-b-none',
			sm: 'rounded-b-sm',
			md: 'rounded-b-md',
			lg: 'rounded-b-lg',
			xl: 'rounded-b-xl',
			'2xl': 'rounded-b-2xl',
			'3xl': 'rounded-b-3xl',
			full: 'rounded-b-full'
		};
		const radiusLeftMap = {
			none: 'rounded-l-none',
			sm: 'rounded-l-sm',
			md: 'rounded-l-md',
			lg: 'rounded-l-lg',
			xl: 'rounded-l-xl',
			'2xl': 'rounded-l-2xl',
			'3xl': 'rounded-l-3xl',
			full: 'rounded-l-full'
		};
		const radiusRightMap = {
			none: 'rounded-r-none',
			sm: 'rounded-r-sm',
			md: 'rounded-r-md',
			lg: 'rounded-r-lg',
			xl: 'rounded-r-xl',
			'2xl': 'rounded-r-2xl',
			'3xl': 'rounded-r-3xl',
			full: 'rounded-r-full'
		};
		if (radiusPosition === 'all') {
			return radioMap[radius];
		} else if (radiusPosition === 'top') {
			return radiusTopMap[radius];
		} else if (radiusPosition === 'bottom') {
			return radiusBottomMap[radius];
		} else if (radiusPosition === 'left') {
			return radiusLeftMap[radius];
		} else if (radiusPosition === 'right') {
			return radiusRightMap[radius];
		} else {
			return '';
		}
	};

	// 通过不同位置，生成不同的布局 class
	// Generate different layout classes by different positions
	const positionClass = {
		bottom: ' flex-col justify-end',
		top: ' flex-col justify-start',
		left: ' justify-start',
		right: ' justify-end',
		center: ' flex-col justify-center'
	};

	// 点击遮罩时派发事件
	// Dispatch events when clicking the mask
	const clickMask = () => {
		onclickMask?.();
		if (maskClosable) {
			visible = false;
			onclose?.();
		}
	};

	// 根据不同位置，生成不同的出现动画参数
	// Generate different transition parameters by different positions
	const transitionParamsFun = () => {
		if (position === 'bottom') {
			return {
				y: size === 0 ? transitionDistance : (window.innerHeight * size) / 100,
				duration,
				easing: eases[easeType],
				opacity: 1
			};
		} else if (position === 'top') {
			return {
				y: -(size === 0 ? transitionDistance : (window.innerHeight * size) / 100),
				duration,
				easing: eases[easeType],
				opacity: 1
			};
		} else if (position === 'left') {
			return {
				x: -(size === 0 ? transitionDistance : (window.innerWidth * size) / 100),
				duration,
				easing: eases[easeType],
				opacity: 1
			};
		} else if (position === 'right') {
			return { x: size === 0 ? transitionDistance : (window.innerWidth * size) / 100, duration, easing: eases[easeType], opacity: 1 };
		} else {
			return { easing: eases[easeType], duration, opacity: 1 };
		}
	};

	// 根据不同位置，生成不同的消失动画参数
	// Generate different transition parameters by different positions
	const transitionOutParamsFun = () => {
		if (position === 'bottom') {
			return {
				y: size === 0 ? transitionDistance : (window.innerHeight * size) / 100,
				duration: outDuration,
				easing: eases[easeOutType],
				opacity: 1
			};
		} else if (position === 'top') {
			return {
				y: -(size === 0 ? transitionDistance : (window.innerHeight * size) / 100),
				duration: outDuration,
				easing: eases[easeOutType],
				opacity: 1
			};
		} else if (position === 'left') {
			return {
				x: -(size === 0 ? transitionDistance : (window.innerWidth * size) / 100),
				duration: outDuration,
				easing: eases[easeOutType],
				opacity: 1
			};
		} else if (position === 'right') {
			return {
				x: size === 0 ? transitionDistance : (window.innerWidth * size) / 100,
				duration: outDuration,
				easing: eases[easeOutType],
				opacity: 1
			};
		} else {
			return { duration: outDuration, easing: eases[easeOutType], opacity: 1 };
		}
	};

	// 监听 visible 与是否允许 body 滚动，动态控制 body 滚动
	// Listen to the change of visible and allowBodyScroll, and dynamically control the body scroll
	$effect(() => {
		if (visible && !allowBodyScroll) {
			const top = document.documentElement.scrollTop || document.body.scrollTop;
			document.body.style.cssText += `
            position: fixed;
            width: 100vw;
            left: 0;
            top: ${-top}px;
            touch-action:none;
        `;
		} else {
			const top = document.body.style.top;
			document.body.style.cssText += `
            position: static;
            touch-action:auto;
        `;
			window.scrollTo(0, Math.abs(parseFloat(top)));
		}
	});

	// 页面滚动时，动态计算窗口高度
	// Dynamically calculate the window height when the page scrolls
	let innerHeight = $state(0);
	$effect(() => {
		innerHeight = window.innerHeight;
	});
	if (dynamicFixed) {
		//解决 Safari 和 Chrome 或其他浏览器滚动时工具栏隐藏与显示引发的窗口高度变化问题
		//Solve the problem of window height change caused by Safari and Chrome or other browsers hiding and showing the toolbar when scrolling
		window.addEventListener('resize', () => {
			innerHeight = window.innerHeight;
		});
	}
</script>

{#if visible}
	<Mask visible {duration} {outDuration} {...mask} onclickMask={clickMask} />
{/if}

{#if visible}
	<div
		class="fixed inset-0 h-screen w-screen flex{positionClass[position] || positionClass['bottom']} pointer-events-none px-0"
		style="z-index:{zIndex};height:{innerHeight}px"
	>
		<Transition
			{visible}
			{size}
			{position}
			{px}
			{py}
			transitionParams={transitionParamsFun()}
			transitionOutParams={transitionOutParamsFun()}
		>
			<div
				class="w-full h-full{transparent ? ' bg-transparent' : ' bg-white dark:bg-gray-950'} {radiusFun()} overflow-y-auto"
				class:popup-container={hideScrollbar}
			>
				{@render children?.()}
			</div>
		</Transition>
	</div>
{/if}

<style>
	.popup-container::-webkit-scrollbar {
		display: none; /* Chrome Safari */
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/popup/Transition.svelte
================================================
<script lang="ts">
	import type { Snippet } from 'svelte';
	import { fly, scale, type ScaleParams, type FlyParams } from 'svelte/transition';

	type Props = {
		visible?: boolean;
		size?: number;
		transitionParams?: ScaleParams | FlyParams;
		transitionOutParams?: ScaleParams | FlyParams;
		position?: string;
		px?: string;
		py?: string;
		children?: Snippet;
	};
	let {
		visible = false,
		size = 40,
		transitionParams = {},
		transitionOutParams = {},
		position = 'bottom',
		px = '0',
		py = '0',
		children
	}: Props = $props();

	const sizeClass = { bottom: 'w-full', top: 'w-full', left: 'h-full', right: 'h-full', center: 'w-full' };
	const sizeStyle = {
		bottom: `height:${size === 0 ? 'auto' : size + '%'}`,
		top: `height:${size === 0 ? 'auto' : size + '%'}`,
		left: `width:${size === 0 ? 'auto' : size + '%'}`,
		right: `width:${size === 0 ? 'auto' : size + '%'}`,
		center: `height:${size === 0 ? 'auto' : size + '%'}`
	};
	const pxClass = {
		'0': ' px-0',
		'1': ' px-1',
		'2': ' px-2',
		'3': ' px-3',
		'4': ' px-4',
		'5': ' px-5',
		'6': ' px-6',
		'8': ' px-8',
		'10': ' px-10',
		'12': ' px-12',
		'16': ' px-16',
		'20': ' px-20'
	};
	const pyClass = {
		'0': ' py-0',
		'1': ' py-1',
		'2': ' py-2',
		'3': ' py-3',
		'4': ' py-4',
		'5': ' py-5',
		'6': ' py-6',
		'8': ' py-8',
		'10': ' py-10',
		'12': ' py-12',
		'16': ' py-16',
		'24': ' py-24',
		'32': ' py-32',
		'48': ' py-48',
		'64': ' py-64'
	};
</script>

{#if visible}
	{#if position === 'center'}
		<div
			out:scale|global={transitionOutParams}
			in:scale|global={transitionParams}
			class="{sizeClass[position as keyof typeof sizeClass] || sizeClass['bottom']}{pxClass[px as keyof typeof pxClass] ||
				pxClass['0']}{pyClass[py as keyof typeof pyClass] || pyClass['0']} pointer-events-auto"
			style={sizeStyle[position as keyof typeof sizeStyle] || sizeStyle['bottom']}
		>
			{@render children?.()}
		</div>
	{:else}
		<div
			in:fly|global={transitionParams}
			out:fly|global={transitionOutParams}
			class="{sizeClass[position as keyof typeof sizeClass] || sizeClass['bottom']}{pxClass[px as keyof typeof pxClass] ||
				pxClass['0']}{pyClass[py as keyof typeof pyClass] || pyClass['0']} pointer-events-auto"
			style={sizeStyle[position as keyof typeof sizeStyle] || sizeStyle['bottom']}
		>
			{@render children?.()}
		</div>
	{/if}
{/if}



================================================
FILE: packages/stdf/src/lib/components/progress/Progress.svelte
================================================
<script lang="ts">
	import type { ProgressProps } from '../../types/index.js';

	let {
		percent = 66,
		percentPosition = 'right',
		height = '2',
		radius = 'full',
		inactive = false,
		overflowPercent = 10,
		duration = '300',
		injClass = '',
		trackInjClass = '',
		children
	}: ProgressProps = $props();

	// 高度样式
	// height class
	const heightClass = { '1': ' h-1', '2': ' h-2', '3': ' h-3', '4': ' h-4' };

	// 圆角样式
	// radius class
	const radiusClass = { full: ' rounded-full', middle: ' rounded-sm', none: ' rounded-none' };

	// 动画时间样式
	// duration class
	const durationClass = {
		'150': ' duration-150',
		'300': ' duration-300',
		'500': ' duration-500',
		'700': ' duration-700',
		'1000': ' duration-1000'
	};
</script>

<div class="flex items-center justify-between space-x-2">
	<div
		class="relative w-full bg-black/10 dark:bg-white/20{percentPosition === 'inner'
			? ''
			: heightClass[height] || heightClass['2']}{radiusClass[radius] || radiusClass['full']}{trackInjClass === ''
			? ''
			: ` ${trackInjClass}`}"
	>
		<div
			class="{inactive ? 'bg-primary-300 dark:bg-dark-800' : 'bg-primary dark:bg-dark'} transition-all{durationClass[duration] ||
				durationClass['300']}{percentPosition === 'inner' ? '' : heightClass[height] || heightClass['2']}{radiusClass[radius] ||
				radiusClass['full']}{injClass === '' ? '' : ` ${injClass}`}"
			style="width:{percent}%;"
		>
			{#if percentPosition === 'inner'}
				<div
					class="px-1 py-0.5 text-right text-xs whitespace-nowrap{percent < overflowPercent
						? ' translate-x-full text-black dark:text-white'
						: ' text-white dark:text-black'}"
				>
					{#if children}
						{@render children?.()}
					{:else}
						{percent}%
					{/if}
				</div>
			{/if}
		</div>
		{#if percentPosition === 'block'}
			<div
				class="absolute top-1/2 {inactive
					? ' bg-primary-300 dark:bg-dark-800'
					: ' bg-primary dark:bg-dark'} px-1 py-0.5 text-xs text-white transition-all dark:text-black duration-300{radiusClass[radius] ||
					radiusClass['full']} -translate-y-1/2 -translate-x-1/2{injClass === '' ? '' : ` ${injClass}`}"
				style="left:{percent}%;"
			>
				{#if children}
					{@render children?.()}
				{:else}
					{percent}%
				{/if}
			</div>
		{/if}
	</div>
	{#if percentPosition === 'right'}
		{#if children}
			{@render children?.()}
		{:else}
			<div class="text-xs">{percent}%</div>
		{/if}
	{/if}
</div>



================================================
FILE: packages/stdf/src/lib/components/progressLoop/ProgressLoop.svelte
================================================
<script lang="ts">
	import type { ProgressLoopProps } from '../../types/index.js';

	let {
		percent = 66,
		strokeWidth = 2,
		butt = false,
		reverse = false,
		duration = '300',
		gradient = null,
		injClass = '',
		trackInjClass = '',
		children
	}: ProgressLoopProps = $props();

	// 通过百分比计算半径
	// calculate radius by percent
	const r = 12 - strokeWidth / 2;

	// 计算圆周长
	// calculate circle length
	const circleLen = 2 * Math.PI * r;

	// 动画时间 class
	// animation duration class
	const durationClass = {
		'150': ' duration-150',
		'300': ' duration-300',
		'500': ' duration-500',
		'700': ' duration-700',
		'1000': ' duration-1000'
	};
</script>

<div class="relative">
	<svg viewBox="0 0 24 24" class="-rotate-90{reverse ? ' -scale-y-100' : ''}">
		<circle
			cx="12"
			cy="12"
			{r}
			stroke-width={strokeWidth}
			fill="none"
			class="stroke-black/5 dark:stroke-white/5{trackInjClass === '' ? '' : ` ${trackInjClass}`}"
		></circle>
		{#if gradient && gradient.length === 2}
			<defs>
				<linearGradient id="gradient_ProgressLoop">
					<stop offset="0%" style="stop-color: {gradient[1]};" />
					<stop offset="100%" style="stop-color: {gradient[0]};" />
				</linearGradient>
			</defs>
		{/if}
		<circle
			cx="12"
			cy="12"
			{r}
			stroke-width={strokeWidth}
			class="{!gradient || gradient.length < 2 ? 'stroke-primary dark:stroke-dark ' : ''}transition-all {durationClass[duration] ||
				durationClass['300']}{injClass === '' ? '' : ` ${injClass}`}"
			fill="none"
			stroke-dashoffset={circleLen - (percent / 100) * circleLen || 0}
			stroke-dasharray={circleLen}
			stroke-linecap={butt ? 'butt' : 'round'}
			stroke="url(#gradient_ProgressLoop)"
		></circle>
	</svg>
	<div class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2">
		{#if children}
			{@render children?.()}
		{:else}
			<div class="text-xs">{percent}%</div>
		{/if}
	</div>
</div>



================================================
FILE: packages/stdf/src/lib/components/radio/Radio.svelte
================================================
<script lang="ts">
	import RadioItem from './RadioItem.svelte';
	import type { RadioProps } from '../../types/index.js';

	let {
		data = [],
		value = $bindable(''),
		layout = 'v',
		textPosition = 'r',
		icon = 'default',
		iconChecked = 'default',
		radioChild,
		onchange
	}: RadioProps = $props();

	const clickItemFn = (name: string) => {
		value = name;
		onchange?.(value);
	};
</script>

<div class={layout === 'inline' ? 'flex flex-wrap' : `flex ${layout === 'h' ? 'justify-between' : 'w-full flex-col space-y-2'}`}>
	{#each data as item}
		{#if radioChild}
			{@render radioChild({ item })}
		{:else}
			<RadioItem
				{layout}
				{...item}
				{textPosition}
				{icon}
				{iconChecked}
				checked={value === item.name}
				onclick={() => clickItemFn(item.name)}
			>
				{item.label}
			</RadioItem>
		{/if}
	{/each}
</div>



================================================
FILE: packages/stdf/src/lib/components/radio/RadioItem.svelte
================================================
<script lang="ts">
	import Icon from '../icon/Icon.svelte';
	import type { RadioItemProps } from '../../types/index.js';

	let {
		name = '',
		textPosition = 'r',
		layout = 'v',
		checked = false,
		icon = 'default',
		iconChecked = 'default',
		children,
		onclick
	}: RadioItemProps = $props();

	// 点击选项事件
	// Click option event
	const clickRadioFun = () => {
		onclick?.(name);
	};
</script>

<button
	onclick={() => clickRadioFun()}
	class="{layout === 'inline' ? 'inline-block' : 'flex'} grow active:opacity-80 {textPosition === 'l' && layout === 'v'
		? 'justify-between'
		: ''} {textPosition === 'b' || textPosition === 't' ? 'flex-col items-center' : layout === 'h' ? 'justify-center' : 'items-center'}"
>
	{#if textPosition === 'l' || textPosition === 't'}
		<div class="{textPosition === 'l' && icon !== null ? 'mr-0.5 text-left' : ''} {layout === 'v' ? 'grow' : ''}">
			{@render children?.()}
			{#if layout === 'v'}
				<div class="mt-1 h-px bg-black/10 dark:bg-white/10"></div>
			{/if}
		</div>
	{/if}
	<div class:hidden={!checked}>
		{#if iconChecked === null}{:else if iconChecked === 'default'}
			<Icon name="ri-radio-button-line" theme top={textPosition === 't' || textPosition === 'b' ? 0 : -1} />
		{:else}
			<Icon {...iconChecked} theme />
		{/if}
	</div>
	<div class:hidden={checked}>
		{#if icon === null}{:else if icon === 'default'}
			<Icon name="ri-checkbox-blank-circle-line" alpha={0.2} top={textPosition === 't' || textPosition === 'b' ? 0 : -1} />
		{:else}
			<Icon alpha={0.2} {...icon} />
		{/if}
	</div>
	{#if textPosition === 'r' || textPosition === 'b'}
		<div class={textPosition === 'r' && icon !== null ? 'ml-0.5 text-left' : ''}>
			{@render children?.()}
		</div>
	{/if}
</button>



================================================
FILE: packages/stdf/src/lib/components/rate/Rate.svelte
================================================
<script lang="ts">
	import { getContext } from 'svelte';
	import Icon from '../icon/Icon.svelte';
	import type { RateProps } from '../../types/index.js';
	import { zh_CN, type LangProps } from '../../lang/index.js';

	// 当前语言
	// current language
	const currentLang = (getContext('STDF_lang') || zh_CN) as LangProps;
	const rateLang: LangProps['rate'] = currentLang.rate;

	let {
		value = $bindable(4),
		total = 5,
		height = 24,
		width = 24,
		opacity = '0.2',
		space = '3',
		half = false,
		zero = false,
		vertical = false,
		disabled = false,
		readonly = false,
		animation = 'current',
		children,
		onclick
	}: RateProps = $props();

	// 对传入数据进行一些报错或警告处理
	// some error or warning processing for the incoming data
	if (value > total) {
		console.error(rateLang.error1);
	}
	if (total % 1 !== 0) {
		console.error(rateLang.error2);
	}
	if (!half && value % 1 !== 0) {
		console.error(rateLang.error3);
	}
	if (half && value % 0.5 !== 0) {
		console.error(rateLang.error4);
	}
	if (width < 20 || height < 20) {
		console.error(rateLang.error5);
	}

	// 间距样式
	// space style
	const spaceObj = { '0': ' gap-0', '1': ' gap-1', '2': ' gap-2', '3': ' gap-3', '4': ' gap-4', '8': ' gap-8' };

	// 透明度样式
	// opacity style
	const opacityObj = {
		'0.05': ' opacity-5',
		'0.1': ' opacity-10',
		'0.2': ' opacity-20',
		'0.3': ' opacity-30',
		'0.4': ' opacity-40',
		'0.5': ' opacity-50',
		'0.6': ' opacity-60',
		'0.7': ' opacity-70',
		'0.8': ' opacity-80',
		'0.9': ' opacity-90',
		'1': ' opacity-100'
	};

	// 是否缩放
	// whether to scale
	let isScale = $state(false);

	// 点击索引
	// click index
	let clickIndex = $state(0);

	// 点击事件
	// click event
	const clickFun = (index: number) => {
		if (disabled || readonly) {
			return;
		}
		isScale = true;
		clickIndex = index;
		setTimeout(() => {
			isScale = false;
		}, 80);
		if (half) {
			if (index === 0) {
				if (zero) {
					if (value === 0 || value > 1) {
						value = 0.5;
					} else if (value === 0.5) {
						value = 1;
					} else {
						value = 0;
					}
				} else {
					if (value === 0 || value >= 1) {
						value = 0.5;
					} else {
						value = 1;
					}
				}
			} else {
				value = value === index + 0.5 ? index + 1 : index + 0.5;
			}
		} else {
			if (zero && index === 0) {
				value = value !== 1 ? 1 : 0;
			} else {
				value = index + 1;
			}
		}
		// 派发事件
		// dispatch event
		onclick?.(value);
	};

	// 处理允许半选情况时的样式
	// handle the style when half selection is allowed
	const isActiveFun = (index: number, value: number, half: boolean, vertical: boolean, i: number) => {
		if (half) {
			if (vertical) {
				if (i === 0) {
					return index + 0.5 < value;
				}
				if (i === 1) {
					return index + 0.5 < value;
				}
				if (i === 2) {
					return index + 0.5 <= value;
				}
				if (i === 3) {
					return index + 0.5 <= value;
				}
			} else {
				if (i === 0) {
					return index + 0.5 <= value;
				}
				if (i === 1) {
					return index + 0.5 < value;
				}
				if (i === 2) {
					return index + 0.5 <= value;
				}
				if (i === 3) {
					return index + 0.5 < value;
				}
			}
		} else {
			return index + 1 <= value;
		}
	};
</script>

<div class="inset-0 inline-flex flex-wrap{spaceObj[space] || spaceObj['4']}{disabled ? ' opacity-50' : ''}">
	<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
	{#each new Array(Math.floor(total)) as _, index}
		<button
			class="flex flex-wrap transition-all{disabled ? ' cursor-not-allowed' : ' cursor-pointer'}{animation === 'active'
				? clickIndex >= index && isScale
					? ' scale-75'
					: ''
				: animation === 'current'
					? clickIndex === index && isScale
						? ' scale-75'
						: ''
					: ''}"
			style="height:{height}px;width:{width}px;"
			onclick={() => clickFun(index)}
		>
			{#each [0, 1, 2, 3] as i}
				<div
					class="overflow-hidden{isActiveFun(index, value, half, vertical, i) ? '' : ` grayscale${opacityObj[opacity] || ' opacity-30'}`}"
					style="height:{height / 2}px;width:{width / 2}px;"
				>
					<div style="transform:translateX({i === 0 || i === 2 ? 0 : -(width / 2)}px) translateY({i < 2 ? 0 : -(height / 2)}px)">
						{#if children}
							{@render children?.()}
						{:else}
							<Icon name="ri-star-fill" theme size={height} top={height < 24 ? height - 24 : 0} />
						{/if}
					</div>
				</div>
			{/each}
		</button>
	{/each}
</div>



================================================
FILE: packages/stdf/src/lib/components/scrollRadio/ScrollRadio.svelte
================================================
<script lang="ts">
	import { onMount } from 'svelte';

	type Props = {
		data?: Record<string, string>[];
		showRow?: 3 | 5 | 7;
		initIndex?: number;
		labelKey?: string;
		autoScrollToLast?: boolean;
		useAnimation?: boolean;
		lastSelectedIndex?: number;
		align?: 'center' | 'left' | 'right';
		onscrollEnd?: (index: number, isTouch: boolean) => void;
	};
	let {
		data = [],
		showRow = 5,
		initIndex = 0,
		labelKey = 'label',
		autoScrollToLast = true,
		useAnimation = true,
		lastSelectedIndex = 0,
		align = 'center',
		onscrollEnd
	}: Props = $props();

	// 是否触摸
	// Whether to touch
	let isTouch = $state(false);

	// 对齐方式样式
	// Alignment style
	const alignClass = { center: 'text-center', left: 'text-left', right: 'text-right' };

	// 单条高度对象
	// Single height object
	const itemHeightObj = { '3': 4, '5': 3, '7': 2 };

	// 实际显示行数
	// Actual number of rows displayed
	const showRowsInner = showRow === 3 || showRow === 5 || showRow === 7 ? showRow : 5;

	// 单条高度
	// Single height
	const itemHeight = itemHeightObj[showRowsInner];

	// 定义空对象 emptyObj，当 showRowsInner 为 3 时，newData 前后各补足一条 emptyObj，当 showRowsInner 为 5 时，newData 前后各补足两条 emptyObj，当 showRowsInner 为 7 时，newData 前后各补足三条 emptyObj
	// Define empty object emptyObj, when showRowsInner is 3, newData is supplemented with one emptyObj at the front and back, when showRowsInner is 5, newData is supplemented with two emptyObj at the front and back, when showRowsInner is 7, newData is supplemented with three emptyObj at the front and back
	const emptyObj: Record<string, string> = {};
	emptyObj[labelKey] = '';
	const newData =
		showRowsInner === 3
			? [...[emptyObj], ...data, ...[emptyObj]]
			: showRowsInner === 5
				? [...[emptyObj, emptyObj], ...data, ...[emptyObj, emptyObj]]
				: [...[emptyObj, emptyObj, emptyObj], ...data, ...[emptyObj, emptyObj, emptyObj]];

	// 滚动元素
	// Scroll element
	let scrollElement = $state<HTMLDivElement | null>(null);

	// 当前选中项索引
	// Current selected item index
	let currentIndex = 0;
	onMount(() => {
		if (scrollElement) {
			// 监听 scrollElement 的滚动事件，同时考虑节流，滚动结束时，计算当前最中间的元素的索引
			// Listen to the scroll event of scrollElement, and consider throttling at the same time. The index of the element in the middle is calculated when the scroll ends
			let scrollTimer: ReturnType<typeof setTimeout>;
			scrollElement.addEventListener('scroll', (e: Event) => {
				if (scrollTimer) clearTimeout(scrollTimer);
				scrollTimer = setTimeout(() => {
					const scrollTop = (e.target as HTMLElement)?.scrollTop;
					currentIndex = Math.round(scrollTop / (itemHeight * 16));
					onscrollEnd?.(currentIndex, isTouch);
				});
			});
		}
	});
	$effect(() => {
		if (scrollElement) {
			if (autoScrollToLast) {
				scrollElement.scrollTop = lastSelectedIndex * itemHeight * 16;
			} else {
				scrollElement.scrollTop = initIndex * itemHeight * 16;
			}
		}
	});
</script>

<div class="picker-contents relative overflow-auto" style="height:{itemHeight * showRowsInner}rem;">
	<div
		class="picker-contents snap-y overflow-auto {useAnimation ? 'scroll-smooth' : 'scroll-auto'}"
		style="height:{itemHeight * showRowsInner}rem;"
		bind:this={scrollElement}
		onscroll={() => {
			isTouch = true;
		}}
	>
		{#each newData as item}
			<div class="{alignClass[align] || alignClass.center} flex snap-center flex-col justify-center px-2" style="height:{itemHeight}rem;">
				<div class="truncate">{item[labelKey]}</div>
			</div>
		{/each}
		<div
			class="pointer-events-none absolute inset-0 w-full border-b border-t border-white dark:border-black"
			style="height:{itemHeight * showRowsInner}rem"
		>
			<div
				class="border-b border-black/10 bg-gradient-to-b from-white to-white/60 dark:border-white/20 dark:from-black dark:to-black/60"
				style="height:{itemHeight * ((showRowsInner - 1) / 2)}rem;"
			></div>
			<div style="height:{itemHeight}rem;"></div>
			<div
				class="border-t border-black/10 bg-gradient-to-t from-white to-white/60 dark:border-white/20 dark:from-black dark:to-black/60"
				style="height:{itemHeight * ((showRowsInner - 1) / 2)}rem;"
			></div>
		</div>
	</div>
</div>

<style>
	.picker-contents::-webkit-scrollbar {
		display: none; /* Chrome Safari */
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/skeleton/Skeleton.svelte
================================================
<script lang="ts">
	import Icon from '../icon/Icon.svelte';
	import type { SkeletonProps } from '../../types/index.js';

	let { type = 'div', width = '6', height = '6', radius = 'sm', space = '1', lines = 3, iconRatio = 0.6 }: SkeletonProps = $props();

	const radiusObj = {
		none: ' rounded-none',
		sm: ' rounded-sm',
		md: ' rounded-md',
		xl: ' rounded-xl',
		'2xl': ' rounded-2xl',
		'3xl': ' rounded-3xl',
		full: ' rounded-full'
	};
	const widthObj = {
		full: ' w-full',
		'2': ' w-2',
		'4': ' w-4',
		'6': ' w-6',
		'8': ' w-8',
		'12': ' w-12',
		'16': ' w-16',
		'24': ' w-24',
		'32': ' w-32',
		'48': ' w-48',
		'64': ' w-64',
		'96': ' w-96'
	};
	const heightObj = {
		'1': ' h-1',
		'2': ' h-2',
		'4': ' h-4',
		'6': ' h-6',
		'8': ' h-8',
		'12': ' h-12',
		'16': ' h-16',
		'24': ' h-24',
		'32': ' h-32',
		'48': ' h-48',
		'64': ' h-64',
		'96': ' h-96'
	};
	const paddingObj = { '0.5': ' p-0.5', '1': ' p-1', '2': ' p-2', '4': ' p-4' };
	const randomArr = ['w-1/2', 'w-1/3', 'w-2/3', 'w-1/4', 'w-3/4', 'w-2/5', 'w-3/5', 'w-4/5', 'w-5/6'];
	const typeIconFun = (type: string) => {
		const typeMap = {
			img: 'ri-image-2-fill',
			video: 'ri-movie-2-fill',
			code: 'ri-code-box-fill',
			qrcode: 'ri-qr-code-fill',
			barcode: 'ri-barcode-fill'
		};
		return typeMap[type as keyof typeof typeMap] || typeMap.qrcode;
	};
</script>

<div
	class="animate-pulse {type === 'p' || width === 'full' ? 'block' : 'inline-block'}{paddingObj[space as keyof typeof paddingObj] ||
		paddingObj['1']}"
>
	{#if type === 'p'}
		<div class="flex flex-col space-y-2">
			<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
			{#each new Array(lines - 1) as _}
				<div class="bg-black/20 dark:bg-white/20 w-full{heightObj[height] || heightObj['6']}{radiusObj[radius] || radiusObj.sm}"></div>
			{/each}
			<div
				class="bg-black/20 dark:bg-white/20 {randomArr[Math.floor(Math.random() * randomArr.length)]}{heightObj[height] ||
					heightObj['6']}{radiusObj[radius] || radiusObj.sm}"
			></div>
		</div>
	{:else}
		<div
			class="bg-black/20 dark:bg-white/20{widthObj[width] || widthObj.full}{heightObj[height] || heightObj['6']}{radiusObj[radius] ||
				radiusObj.sm} flex flex-col justify-center"
		>
			{#if type === 'img' || type === 'video' || type === 'code' || type === 'qrcode' || type === 'barcode'}
				<div class="m-auto" style="width:{iconRatio * 100 + '%'}">
					<Icon name={typeIconFun(type)} size="full" alpha={0.2} />
				</div>
			{/if}
		</div>
	{/if}
</div>



================================================
FILE: packages/stdf/src/lib/components/slider/Slider.svelte
================================================
<script lang="ts">
	import { onMount } from 'svelte';
	import { fly } from 'svelte/transition';
	import { throttleWithRAF, debounce, stepNumberFun } from '../utils/index.js';
	import type { SliderProps } from '../../types/index.js';

	let {
		value = $bindable(40),
		step = 1,
		minRange = 0,
		maxRange = 100,
		isRange = false,
		valueRange = $bindable([20, 60]),
		startValue = $bindable(20),
		endValue = $bindable(60),
		showTip = 'touch',
		radius = 'full',
		lineBlock = false,
		disabled = false,
		readonly = false,
		children,
		onchange
	}: SliderProps = $props();

	//滑动条 dom slider dom
	let lineDom = $state<HTMLDivElement | null>(null);
	//滑块 dom block dom
	let blockDom = $state<HTMLDivElement | null>(null);
	//滑块宽度 block width
	let blockWidth = $state(0);
	//滑块条起始位置 slider start position
	let lineDomStartX = $state(0);
	//滑块条结束位置 slider end position
	let lineDomEndX = $state(0);
	//滑块条宽度 slider width
	let lineDomWidth = $state(0);
	//初始位置 initial position
	let currentX = $state(0);
	$effect(() => {
		currentX = ((value - minRange) / (maxRange - minRange)) * lineDomWidth;
	});
	//区间选择时开始位置 start position
	let currentStartX = $state(0);
	$effect(() => {
		currentStartX = ((startValue - minRange) / (maxRange - minRange)) * lineDomWidth;
	});
	//区间选择时结束位置 end position
	let currentEndX = $state(0);
	$effect(() => {
		currentEndX = ((endValue - minRange) / (maxRange - minRange)) * lineDomWidth;
	});
	//当前移动的滑块 current move block
	let currentMove = $state('none');

	//是否按下 is down
	let isDown = false;
	const radiusObj = { none: ' rounded-none', sm: ' rounded-sm', xl: ' rounded-xl', full: ' rounded-full' };

	const touchLineStart = (e: PointerEvent) => {
		if (disabled || readonly) {
			return;
		}
		isDown = true;
		const clientX = e.clientX;
		if (isRange) {
			//判断点击位置距离哪一个更近
			// Determine which one is closer to the click position
			if (startValue === endValue) {
				if (clientX - lineDomStartX <= currentStartX) {
					// 点击的是开始滑块
					// Click on the start block
					currentMove = 'start';
					currentStartX = clientX - lineDomStartX;
				} else {
					// 点击的是结束滑块
					// Click on the end block
					currentMove = 'end';
					currentEndX = clientX - lineDomStartX;
				}
			} else if (Math.abs(clientX - currentStartX - lineDomStartX) < Math.abs(clientX - currentEndX - lineDomStartX)) {
				// 点击的是开始滑块
				// Click on the start block
				currentMove = 'start';
				currentStartX = clientX - lineDomStartX;
			} else {
				// 点击的是结束滑块
				// Click on the end block
				currentMove = 'end';
				currentEndX = clientX - lineDomStartX;
			}
			startValue = stepNumberFun(minRange + (currentStartX / lineDomWidth) * (maxRange - minRange), step);
			endValue = stepNumberFun(minRange + (currentEndX / lineDomWidth) * (maxRange - minRange), step);
			onchange?.(0, [startValue, endValue]);
		} else {
			currentMove = 'one';
			currentX = clientX - lineDomStartX;
			value = stepNumberFun((currentX / lineDomWidth) * (maxRange - minRange), step);
			onchange?.(value);
		}
	};
	const touchLineMove = (e: PointerEvent) => {
		if (!lineDom?.hasPointerCapture(e.pointerId)) {
			lineDom?.setPointerCapture(e.pointerId);
		}
		if (disabled || readonly) {
			return;
		}
		if (!isDown) {
			return;
		}
		const clientX = e.clientX;
		if (isRange) {
			if (currentMove === 'start') {
				if (clientX <= lineDomStartX) {
					currentStartX = 0;
				} else if (clientX >= currentEndX + blockWidth / 2) {
					currentStartX = currentEndX;
				} else {
					currentStartX = clientX - lineDomStartX;
				}
			} else {
				if (clientX <= currentStartX + blockWidth / 2) {
					currentEndX = currentStartX;
				} else if (clientX >= lineDomEndX) {
					currentEndX = lineDomEndX - lineDomStartX;
				} else {
					currentEndX = clientX - lineDomStartX;
					//由于开启了防抖，有极短时间内会出现 currentEndX 大于 lineDomEndX 的情况，所以这里做了一个判断
					//Due to the opening of the anti-shake, there will be a situation where currentEndX is greater than lineDomEndX in a very short time, so a judgment is made here
					currentEndX = currentEndX < currentStartX ? currentStartX : currentEndX;
				}
			}
			startValue = stepNumberFun(minRange + (currentStartX / lineDomWidth) * (maxRange - minRange), step);
			endValue = stepNumberFun(minRange + (currentEndX / lineDomWidth) * (maxRange - minRange), step);
			onchange?.(0, [startValue, endValue]);
		} else {
			if (clientX <= lineDomStartX) {
				currentX = 0;
			} else if (clientX >= lineDomEndX) {
				currentX = lineDomEndX - lineDomStartX;
			} else {
				currentX = clientX - lineDomStartX;
			}
			value = stepNumberFun(minRange + (currentX / lineDomWidth) * (maxRange - minRange), step);
			onchange?.(value);
		}
	};
	const touchLineEnd = (e: PointerEvent) => {
		if (lineDom?.hasPointerCapture(e.pointerId)) {
			lineDom?.releasePointerCapture(e.pointerId);
		}
		currentMove = 'none';
		isDown = false;
	};
	const handleResize = () => {
		if (!lineDom) return;
		lineDomStartX = lineDom.getBoundingClientRect().left;
		lineDomEndX = lineDom.getBoundingClientRect().right;
		lineDomWidth = lineDom.getBoundingClientRect().width;
		currentX = ((value - minRange) / (maxRange - minRange)) * lineDomWidth; //挂载完成之后初始位置 initial position after mounting
		currentStartX = ((startValue - minRange) / (maxRange - minRange)) * lineDomWidth; //区间选择开始位置 initial position after mounting
		currentEndX = ((endValue - minRange) / (maxRange - minRange)) * lineDomWidth; //区间选择结束位置 initial position after mounting
		if (isRange && blockDom) {
			blockWidth = blockDom.getBoundingClientRect().width;
		}
	};
	onMount(() => {
		handleResize();
		window.addEventListener('resize', debounce(handleResize, 200));
	});
</script>

<div class="relative h-7{disabled ? ' opacity-50' : ''}">
	<div
		onpointerdown={touchLineStart}
		onpointermove={(e) => throttleWithRAF(touchLineMove)(e)}
		onpointerup={touchLineEnd}
		class="absolute flex h-7 w-full cursor-move touch-none flex-col justify-center"
		bind:this={lineDom}
	>
		{#if children}
			{@render children()}
		{:else}
			<div class="h-1 w-full bg-black/10 dark:bg-white/20{radiusObj[radius] || radiusObj['full']}">
				{#if isRange}
					<div
						class="bg-primary dark:bg-dark h-1{radiusObj[radius] || radiusObj['full']}"
						style="width:{currentEndX - currentStartX}px;transform: translateX({currentStartX}px);"
					></div>
				{:else}
					<div class="bg-primary dark:bg-dark h-1{radiusObj[radius] || radiusObj['full']}" style="width:{currentX}px"></div>
				{/if}
			</div>
		{/if}
	</div>
	{#if isRange}
		<div class="pointer-events-none absolute flex h-7 w-full flex-col justify-center">
			<div
				class="{lineBlock
					? 'border-primary dark:border-dark h-6 w-6 border bg-white dark:bg-black'
					: 'bg-primary ring-primary/10 dark:bg-dark dark:ring-dark/10 h-5 w-5 ring-4'}{radiusObj[radius] || radiusObj['full']}"
				style="transform: translateX(calc({currentStartX}px - 50%));"
			>
				{#if showTip === 'always' || (currentMove === 'start' && showTip !== 'never')}
					<div
						class="absolute -top-9 bg-black/90 py-1 text-xs text-white dark:bg-white dark:text-black px-2{radius === 'none'
							? ' rounded-none'
							: ' rounded-sm'}"
						style="left: 50%;transform: translateX(-50%);"
						in:fly={{ y: 8, duration: 500 }}
						out:fly={{ y: 8, duration: 300 }}
					>
						{startValue}
						<div
							class="absolute h-0 w-0 border-4 border-t-4 border-transparent border-t-black/90 dark:border-t-white"
							style="top:100%;left:50%;transform: translateX(-50%)"
						></div>
					</div>
				{/if}
			</div>
		</div>
		<div class="pointer-events-none absolute flex h-7 w-full flex-col justify-center">
			<div
				class="{lineBlock
					? 'border-primary dark:border-dark h-6 w-6 border bg-white dark:bg-black'
					: 'bg-primary ring-primary/10 dark:bg-dark dark:ring-dark/10 h-5 w-5 ring-4'}{radiusObj[radius] || radiusObj['full']}"
				style="transform: translateX(calc({currentEndX}px - 50%));"
				bind:this={blockDom}
			>
				{#if showTip === 'always' || (currentMove === 'end' && showTip !== 'never')}
					<div
						class="absolute -top-9 bg-black/90 py-1 text-xs text-white dark:bg-white dark:text-black px-2{radius === 'none'
							? ' rounded-none'
							: ' rounded-sm'}"
						style="left: 50%;transform: translateX(-50%);"
						in:fly={{ y: 8, duration: 500 }}
						out:fly={{ y: 8, duration: 300 }}
					>
						{endValue}
						<div
							class="absolute h-0 w-0 border-4 border-t-4 border-transparent border-t-black/90 dark:border-t-white"
							style="top:100%;left:50%;transform: translateX(-50%)"
						></div>
					</div>
				{/if}
			</div>
		</div>
	{:else}
		<div class="pointer-events-none absolute flex h-7 w-full flex-col justify-center">
			<div
				class="{lineBlock
					? 'border-primary dark:border-dark h-6 w-6 border bg-white dark:bg-black'
					: 'bg-primary ring-primary/10 dark:bg-dark dark:ring-dark/10 h-5 w-5 ring-4'}{radiusObj[radius] || radiusObj['full']}"
				style="transform: translateX(calc({currentX}px - 50%));"
			>
				{#if showTip === 'always' || (currentMove === 'one' && showTip !== 'never')}
					<div
						class="absolute -top-9 bg-black/90 py-1 text-xs text-white dark:bg-white dark:text-black px-2{radius === 'none'
							? ' rounded-none'
							: ' rounded-sm'}"
						style="left: 50%;transform: translateX(-50%);"
						in:fly={{ y: 8, duration: 500 }}
						out:fly={{ y: 8, duration: 300 }}
					>
						{value}
						<div
							class="absolute h-0 w-0 border-4 border-t-4 border-transparent border-t-black/90 dark:border-t-white"
							style="top:100%;left:50%;transform: translateX(-50%)"
						></div>
					</div>
				{/if}
			</div>
		</div>
	{/if}
</div>



================================================
FILE: packages/stdf/src/lib/components/stepper/Stepper.svelte
================================================
<script lang="ts">
	import Icon from '../icon/Icon.svelte';
	import Loading from '../loading/Loading.svelte';
	import type { StepperProps } from '../../types/index.js';

	let {
		value = $bindable(10),
		min = 0,
		max = 100,
		step = 1,
		vertical = false,
		numberHighlight = false,
		theme = true,
		radius = 'sm',
		decimal = 0,
		async = false,
		asyncLoading = false,
		loading = {},
		padding = true,
		injClassOut = '',
		injClassBtn = '',
		injClassNum = '',
		onchange,
		ondecrease,
		onincrease
	}: StepperProps = $props();

	// 圆角
	// Round
	const roundObj = { none: 'rounded-none', sm: 'rounded-sm', xl: 'rounded-xl', full: 'rounded-full' };

	// 减少
	// Decrease
	const decreaseFn = () => {
		if (!async) {
			if (value > min) {
				value = Math.max(min, value - step);
				onchange?.(value);
			}
		}
		ondecrease?.();
	};

	// 增加
	// Increase
	const increaseFn = () => {
		if (!async) {
			if (value < max) {
				value = Math.min(max, value + step);
				onchange?.(value);
			}
		}
		onincrease?.();
	};
</script>

<div
	class="inline-flex items-center bg-gray-100 dark:bg-gray-800 {roundObj[radius] || 'rounded-sm'} {padding
		? 'p-1'
		: 'p-0'} overflow-hidden {injClassOut} {vertical ? 'flex-col-reverse' : 'flex-row'}"
>
	<button
		onclick={decreaseFn}
		class="{vertical ? 'w-full' : 'w-9'} h-9 {roundObj[radius] ||
			'rounded-sm'} flex flex-col items-center {injClassBtn} justify-center{numberHighlight
			? ''
			: theme
				? ' bg-primary/5 dark:bg-dark/10'
				: ' bg-white dark:bg-black'}"
		disabled={async || value === min}
		aria-label="decrease"
	>
		<span class={async || value === min ? 'opacity-20' : ''}>
			<Icon name="ri-subtract-line" theme={theme && (numberHighlight ? false : true)} />
		</span>
	</button>

	{#if async && asyncLoading}
		<div class="h-9 px-2 {roundObj[radius] || 'rounded-sm'} flex flex-col items-center justify-center">
			<Loading width="6" height="6" {...loading} />
		</div>
	{:else}
		<div
			class="h-9 px-4 {roundObj[radius] || 'rounded-sm'} flex flex-col items-center {injClassNum} justify-center{numberHighlight
				? theme
					? ' bg-primary/5 text-primary dark:bg-dark/10 dark:text-dark'
					: ' bg-white dark:bg-black'
				: ''}"
		>
			{value.toFixed(decimal)}
		</div>
	{/if}

	<button
		onclick={increaseFn}
		class="{vertical ? 'w-full' : 'w-9'} h-9 {roundObj[radius] ||
			'rounded-sm'} flex flex-col items-center {injClassBtn} justify-center{numberHighlight
			? ''
			: theme
				? ' bg-primary/5 dark:bg-dark/10'
				: ' bg-white dark:bg-black'}"
		aria-label="increase"
		disabled={async || value === max}
	>
		<span class={async || value === max ? 'opacity-20' : ''}>
			<Icon name="ri-add-line" theme={theme && (numberHighlight ? false : true)} />
		</span>
	</button>
</div>



================================================
FILE: packages/stdf/src/lib/components/steps/Steps.svelte
================================================
<script lang="ts">
	import Icon from '../icon/Icon.svelte';
	import type { StepsProps } from '../../types/index.js';

	let { steps = [], current = 1, radius = 'sm', barBorder = true, vertical = false }: StepsProps = $props();

	const radiusObj = { none: 'rounded-none', sm: 'rounded-sm', xl: 'rounded-xl', full: 'rounded-full' };
	let width = $state(0);

	let heightList = $state<number[]>([]);
	const getClientHeight = (node: HTMLElement) => {
		heightList.push(node.clientHeight);
	};
</script>

{#if vertical}
	<div class="flex flex-col justify-between">
		{#each steps as item, i}
			<div class="relative flex items-center py-3" use:getClientHeight>
				{#if item.step?.bar || item.finishStep?.bar}
					<div class="my-4 mr-10 pl-4">
						<div
							class="absolute w-0.5 transition-all {i < current - 1 ? 'bg-primary dark:bg-dark' : 'bg-black/30 dark:bg-white/30'}"
							style="height:{i === steps.length - 1 ? '0px' : heightList[i] - 30 + 'px'};top:42px;left:30px"
						></div>
						<div
							class="absolute box-border h-[30px] w-[30px] overflow-hidden border transition-all duration-300 {i < current - 1
								? 'border-primary dark:border-dark text-primary dark:text-dark'
								: i === current - 1
									? 'border-primary dark:border-dark bg-primary dark:bg-dark text-white dark:text-black'
									: 'border-black/30 text-black/30 dark:border-white/30 dark:text-white/30'} {radiusObj[radius] || radiusObj.sm} {!barBorder
								? '!border-transparent'
								: ''}"
							style="top:12px"
						>
							{#if item.step?.bar?.type === 'icon' || item.finishStep?.bar?.type === 'icon'}
								<div class="m-auto h-4 w-4">
									<Icon
										{...item.step?.bar?.type === 'icon' ? item.step?.bar : {}}
										name={item.finishStep && i < current && item.finishStep?.bar?.type === 'icon'
											? item.finishStep?.bar?.content?.name
											: item.step?.bar?.type === 'icon'
												? item.step?.bar?.content?.name
												: ''}
										size={16}
										top={0}
									/>
								</div>
							{/if}
							{#if item.step?.bar?.type === 'image' || item.finishStep?.bar?.type === 'image'}
								<img
									class="object-cover"
									src={item.step?.bar?.type === 'image'
										? item.step?.bar?.content || ''
										: item.finishStep?.bar?.type === 'image'
											? item.finishStep?.bar?.content || ''
											: ''}
									alt=""
								/>
							{/if}
							{#if item.step?.bar?.type === 'string' || item.finishStep?.bar?.type === 'string'}
								<div class="m-auto mt-1 h-5 w-5 text-center text-sm leading-5">
									{(item.step?.bar?.type === 'string' && item.step?.bar?.content) ||
										(item.finishStep?.bar?.type === 'string' && item.finishStep?.bar?.content)}
								</div>
							{/if}
						</div>
					</div>
				{:else}
					<div class="mr-6 pl-4">
						<div
							class="absolute w-0.5 transition-all {i < current - 1 ? 'bg-primary dark:bg-dark' : 'bg-black/30 dark:bg-white/30'}"
							style="height:{i === steps.length - 1 ? '0px' : heightList[i] - 10 + 'px'};top:26px;left:20px"
						></div>
						<div
							class="absolute h-2.5 w-2.5 border transition-all duration-300 {i < current - 1
								? 'border-primary dark:border-dark'
								: i === current - 1
									? 'border-primary dark:border-dark bg-primary dark:bg-dark'
									: 'border-black/30 dark:border-white/30'} {radiusObj[radius] || radiusObj.sm}"
							style="top:16px"
						></div>
					</div>
				{/if}
				<div class="pr-4">
					<div
						class="font-medium transition-all duration-300 {i < current - 1
							? 'text-black dark:text-white'
							: i === current - 1
								? 'text-primary dark:text-dark'
								: 'text-black/30 dark:text-white/30'}"
					>
						{item.finishStep && i < current - 1 ? item.finishStep.title : item.step.title}
					</div>
					{#if item.step?.desc || item.finishStep?.desc}
						<div class="text-xs transition-all duration-300{i <= current - 1 ? '' : ' text-black/30 dark:text-white/30'}">
							{item.finishStep && i < current - 1
								? item.finishStep.desc
									? item.finishStep.desc
									: ''
								: item.step?.desc
									? item.step?.desc
									: ''}
						</div>
					{/if}
					{#if item.step?.injComponent || item.finishStep?.injComponent}
						{@const SvelteComponent = item.step?.injComponent || item.finishStep?.injComponent}
						<SvelteComponent />
					{/if}
				</div>
			</div>
		{/each}
	</div>
{:else}
	<div class="mt-4 flex justify-between" bind:clientWidth={width}>
		{#each steps as item, i}
			<div class="flex flex-1 flex-col items-center space-y-2">
				{#if item.step?.bar || item.finishStep?.bar}
					<div class="relative w-full pb-8">
						<div
							class="relative h-0.5 transition-all {i < current - 1 ? 'bg-primary dark:bg-dark' : 'bg-black/30 dark:bg-white/30'}"
							style="top:16px;width:{i === steps.length - 1 ? '0' : width / steps.length - 30}px;left:calc(50% + 15px)"
						></div>
						<div
							class="absolute box-border h-[30px] w-[30px] overflow-hidden border transition-all duration-300 {i < current - 1
								? 'border-primary dark:border-dark text-primary dark:text-dark'
								: i === current - 1
									? 'border-primary dark:border-dark bg-primary dark:bg-dark text-white dark:text-black'
									: 'border-black/30 text-black/30 dark:border-white/30 dark:text-white/30'} {radiusObj[radius] || radiusObj.sm} {!barBorder
								? '!border-transparent'
								: ''}"
							style="left:calc(50% - 15px)"
						>
							{#if item.step?.bar?.type === 'icon' || item.finishStep?.bar?.type === 'icon'}
								<div class="m-auto h-4 w-4">
									<Icon
										{...item.step?.bar?.type === 'icon' ? item.step?.bar : {}}
										name={item.finishStep && i < current && item.finishStep?.bar?.type === 'icon'
											? item.finishStep?.bar?.content?.name
											: item.step?.bar?.type === 'icon'
												? item.step?.bar?.content?.name
												: ''}
										size={16}
										top={0}
									/>
								</div>
							{/if}
							{#if item.step?.bar?.type === 'image' || item.finishStep?.bar?.type === 'image'}
								<img
									class=" object-cover"
									src={item.step?.bar?.type === 'image'
										? item.step?.bar?.content || ''
										: item.finishStep?.bar?.type === 'image'
											? item.finishStep?.bar?.content || ''
											: ''}
									alt=""
								/>
							{/if}
							{#if item.step?.bar?.type === 'string' || item.finishStep?.bar?.type === 'string'}
								<div class="m-auto mt-1 h-5 w-5 text-center text-sm leading-5">
									{(item.step?.bar?.type === 'string' && item.step?.bar?.content) ||
										(item.finishStep?.bar?.type === 'string' && item.finishStep?.bar?.content)}
								</div>
							{/if}
						</div>
					</div>
				{:else}
					<div class="relative w-full py-2">
						<div
							class="relative h-0.5 transition-all {i < current - 1 ? 'bg-primary dark:bg-dark' : 'bg-black/30 dark:bg-white/30'} {i ===
							steps.length - 1
								? 'w-px'
								: ''}"
							style="width:{i === steps.length - 1 ? '0' : width / steps.length - 9}px;top:0;left:calc(50% + 5px)"
						></div>
						<div
							class="absolute top-1 h-2.5 w-2.5 border transition-all duration-300 {i < current - 1
								? 'border-primary dark:border-dark'
								: i === current - 1
									? 'border-primary dark:border-dark bg-primary dark:bg-dark'
									: 'border-black/30 dark:border-white/30'} {radiusObj[radius] || radiusObj.sm}"
							style="left:calc(50% - 5px)"
						></div>
					</div>
				{/if}
				<div
					class="text-center text-sm font-medium transition-all duration-300 {i < current - 1
						? 'text-black dark:text-white'
						: i === current - 1
							? 'text-primary dark:text-dark'
							: 'text-black/30 dark:text-white/30'}"
				>
					{item.finishStep && i < current - 1 ? item.finishStep.title : item.step?.title}
				</div>
			</div>
		{/each}
	</div>
{/if}



================================================
FILE: packages/stdf/src/lib/components/swiper/Swiper.svelte
================================================
<script lang="ts">
	import { onMount } from 'svelte';
	import type { SwiperProps, SwiperImgProps, SwiperComponentProps } from '../../types/index.js';

	let {
		data = [],
		interval = 4,
		duration = 1000,
		autoplay = true,
		lazyplay = true,
		initActive = 0,
		indicatePosition = 'inner',
		indicateAlign = 'center',
		indicateStyle = 'pointLine',
		indicateRadius = true,
		indicateInjClass = '',
		indicateColor = '',
		indicateActiveColor = '',
		aspectRatio = [16, 9],
		containerWidth = 0,
		px = '0',
		py = '0',
		translateX = 0,
		translateZ = 0,
		rotateX = 0,
		rotateY = 0,
		rotateZ = 0,
		activeInjClass = '',
		notActiveInjClass = '',
		radius = 'none',
		innerInjClass = '',
		triggerLong = 30,
		notTriggerLong = 10,
		triggerSpeed = 0.5,
		onchange,
		onclick
	}: SwiperProps = $props();

	let width = containerWidth === 0 ? document.body.clientWidth : containerWidth; //宽度 width
	let active = $state(data.length > 1 ? initActive + 1 : 1); //当前激活的 item current active item
	let currentIndicate = $state(data.length > 1 ? initActive : 0); //当前激活的指示器  current active indicate
	let longTransition = $state(true); //长线指示器过渡 long line indicate transition
	let long = $state(false); //长线指示器是否较长状态 long line indicate is long
	let once = $state(true); //是否是第首次轮播，处理轮播间隔与过渡时间的差异 is first time play, handle interval and duration difference
	let translateXTransition = $state(true); //是否进行过渡动画 is transition animation
	let initialState = true; //是否是初始状态 is initial state
	let startX = 0; //滑动开始 X 坐标 when start touch x position
	let moveX = $state(0); //滑动移动 X 坐标 when move touch x position
	let startTime = 0; //滑动开始时间 when start touch time
	let endTime = 0; //滑动结束时间 when end touch time
	let isMove = false; //是否滑动 is touch move
	// let transition = true;
	let swiperDom = $state<HTMLElement | null>(null); //Swiper 容器
	let movePercent = $derived(moveX / width); //滑动距离占总宽度的百分比 touch width percent

	//实现无限轮播，复制一个新数组，防止改变原数组
	//	implement infinite loop, copy a new array to prevent change original array
	const dataNew: (SwiperComponentProps | SwiperImgProps)[] =
		data.length > 1
			? [data[data.length - 1], ...data, data[0], data[1]]
			: data.length === 1
				? [data[data.length - 1], ...data, data[0]]
				: data;
	const indicateAlignObj = { left: 'justify-start', center: 'justify-center', right: 'justify-end' };
	const pxObj = { '0': '', '1': 'px-1', '2': 'px-2', '4': 'px-4', '6': 'px-6', '8': 'px-8', '12': 'px-12', '16': 'px-16', '24': 'px-24' };
	const pyObj = { '0': '', '1': 'py-1', '2': 'py-2', '4': 'py-4', '6': 'py-6', '8': 'py-8', '12': 'py-12' };
	const radiusObj = { none: 'rounded-none', sm: 'rounded-sm', xl: 'rounded-xl', '2xl': 'rounded-2xl', full: 'rounded-full' };
	//根据 indicateStyle 和是否激活生成不同样式的 indicate
	//generate different style indicate according to indicateStyle and isActive
	const indicateStyleInnerFun = (indicateStyle: string, isActive: boolean, indicateColor: string, indicateActiveColor: string) => {
		switch (indicateStyle) {
			case 'point':
				return isActive
					? `w-1.5 h-1.5 ${indicateActiveColor === '' ? 'bg-white' : indicateActiveColor}`
					: `w-1.5 h-1.5 ${indicateColor === '' ? 'bg-white/40' : indicateColor}`;
			case 'line':
				return isActive
					? `w-6 h-1 ${indicateActiveColor === '' ? 'bg-white' : indicateActiveColor}`
					: `w-6 h-1 ${indicateColor === '' ? 'bg-white/40' : indicateColor}`;
			case 'pointLine':
				return isActive
					? `w-6 h-1 ${indicateActiveColor === '' ? 'bg-white' : indicateActiveColor}`
					: `w-1 h-1 ${indicateColor === '' ? 'bg-white' : indicateColor}`;
			case 'longLine':
				return isActive
					? `w-16 h-1 ${indicateColor === '' ? 'bg-white/40' : indicateColor}`
					: `w-1 h-1 ${indicateColor === '' ? 'bg-white/40' : indicateColor}`;
			default:
				console.log('传入的 indicateStyle 不在备选参数之内，将使用默认值！');
				return isActive
					? `w-6 h-1 ${indicateActiveColor === '' ? 'bg-white' : indicateActiveColor}`
					: `w-1 h-1 ${indicateColor === '' ? 'bg-white' : indicateColor}`;
		}
	};
	const indicateStyleOutFun = (indicateStyle: string, isActive: boolean, indicateColor: string, indicateActiveColor: string) => {
		switch (indicateStyle) {
			case 'point':
				return isActive
					? `w-1.5 h-1.5 ${indicateActiveColor === '' ? 'bg-primary dark:bg-dark' : indicateActiveColor}`
					: `w-1.5 h-1.5 ${indicateColor === '' ? 'bg-black/20 dark:bg-white/40' : indicateColor}`;
			case 'line':
				return isActive
					? `w-6 h-1 ${indicateActiveColor === '' ? 'bg-primary dark:bg-dark' : indicateActiveColor}`
					: `w-6 h-1 ${indicateColor === '' ? 'bg-black/20 dark:bg-white/40' : indicateColor}`;
			case 'pointLine':
				return isActive
					? `w-6 h-1 ${indicateActiveColor === '' ? 'bg-primary dark:bg-dark' : indicateActiveColor}`
					: `w-1 h-1 ${indicateColor === '' ? 'bg-primary dark:bg-dark' : indicateColor}`;
			case 'longLine':
				return isActive
					? `w-16 h-1 ${indicateColor === '' ? 'bg-black/5 dark:bg-white/10' : indicateColor}`
					: `w-1 h-1 ${indicateColor === '' ? 'bg-black/20 dark:bg-white/40' : indicateColor}`;
			default:
				console.log('传入的 indicateStyle 不在备选参数之内，将使用默认值！');
				return isActive
					? `w-6 h-1 ${indicateActiveColor === '' ? 'bg-primary dark:bg-dark' : indicateActiveColor}`
					: `w-1 h-1 ${indicateColor === '' ? 'bg-primary dark:bg-dark' : indicateColor}`;
		}
	};
	//对需要处理的偏移与旋转数值进行处理
	//process the offset and rotate value that need to be processed
	const translateXFun = (i: number, active: number, translateX: number) => {
		if (i === active) {
			return '0px';
		}
		if (i < active) {
			return `${translateX}px`;
		}
		if (i > active) {
			return `${-translateX}px`;
		}
	};
	const translateZFun = (i: number, active: number, translateZ: number, movePercent: number) =>
		i === active
			? `${0 - Math.abs(translateZ * (isMove ? movePercent : 0))}px`
			: `${-translateZ + Math.abs(translateZ * (isMove ? movePercent : 0))}px`;

	const rotateXFun = (i: number, active: number, rotateX: number, movePercent: number) => {
		if (i === active) {
			return `${-rotateX * (isMove ? movePercent : 0)}deg`;
		}
		if (i < active) {
			return `${rotateX - rotateX * (isMove ? movePercent : 0)}deg`;
		}
		if (i > active) {
			return `${-rotateX - rotateX * (isMove ? movePercent : 0)}deg`;
		}
	};
	const rotateYFun = (i: number, active: number, rotateY: number, movePercent: number) => {
		if (i === active) {
			return `${-rotateY * (isMove ? movePercent : 0)}deg`;
		}
		if (i < active) {
			return `${rotateY - rotateY * (isMove ? movePercent : 0)}deg`;
		}
		if (i > active) {
			return `${-rotateY - rotateY * (isMove ? movePercent : 0)}deg`;
		}
	};
	const rotateZFun = (i: number, active: number, rotateZ: number, movePercent: number) => {
		if (i === active) {
			return `${-rotateZ * (isMove ? movePercent : 0)}deg`;
		}
		if (i < active) {
			return `${rotateZ - rotateZ * (isMove ? movePercent : 0)}deg`;
		}
		if (i > active) {
			return `${-rotateZ - rotateZ * (isMove ? movePercent : 0)}deg`;
		}
	};
	const zIndexFun = (i: number, active: number, dataNew: (SwiperComponentProps | SwiperImgProps)[]) => {
		if (i === active) {
			return i + 2;
		}
		if (i < active) {
			return -(dataNew.length - i - 1) + dataNew.length;
		}
		if (i > active) {
			return 2 * active - i + 2;
		}
	};
	//定时器
	// timer
	let intervalTime: ReturnType<typeof setInterval>;
	//定时器执行函数
	// timer function
	const intervalTimeFun = () => {
		intervalTime = setInterval(() => {
			once = false;
			initialState = false;
			active++;
			currentIndicate++;
			long = false;
			longTransition = false;
			setTimeout(() => {
				long = autoplay;
				longTransition = true;
			}, duration);
			if (active === dataNew.length - 2) {
				//最后一个
				// the last one
				currentIndicate = 0;
				setTimeout(() => {
					// 切换动画完成后，关闭过渡动画，同时将展示的部分偷偷替换为最开始的样子。
					// After the switching animation is completed, turn off the transition animation, and at the same time, the displayed part is secretly replaced with the original appearance.
					active = 1;
					// transition = false;
					translateXTransition = false;
				}, duration);
			} else {
				//开启过渡
				// turn on transition
				// transition = true;
				translateXTransition = !initialState;
			}
			//派发 Swiper 容器 change 事件，i 表示当前容器索引值
			// dispatch the Swiper container change event, i indicates the current container index value
			onchange?.(currentIndicate);
		}, interval * 1000);
	};
	//判断 Swiper 容器是否在可视区域内，如果在，则开启定时器，否则不开启定时器
	// Determine whether the Swiper container is in the visible area. If it is, start the timer, otherwise do not start the timer
	const io = new IntersectionObserver((entries) => {
		entries.forEach((item) => {
			// isIntersecting 是一个 Boolean 值，判断目标元素当前是否可见
			// isIntersecting is a Boolean value that determines whether the target element is currently visible
			if (item.isIntersecting) {
				if (autoplay) {
					if (intervalTime) {
						clearInterval(intervalTime); //清除定时器 clear timer
					}
					intervalTimeFun();
				}
			} else {
				if (intervalTime) {
					clearInterval(intervalTime); //清除定时器 clear timer
				}
			}
		});
	});
	onMount(() => {
		if (duration >= interval * 1000) {
			console.log('间隔时间必须大于过渡时间');
			return false;
		}
		// 加载完成后，通过定时器使 item 自动轮播。
		// After loading, use the timer to make the item automatically rotate.
		if (data.length < 2 || !autoplay) return false;
		long = false;
		longTransition = false;
		setTimeout(() => {
			long = autoplay;
			longTransition = true;
		}, 0);
		//懒轮播
		if (lazyplay) {
			if (swiperDom) {
				io.observe(swiperDom);
			}
		} else {
			if (autoplay && intervalTime) {
				clearInterval(intervalTime); //清除定时器 clear timer
				intervalTimeFun();
			}
		}
		return () => {
			if (intervalTime) {
				clearInterval(intervalTime); //清除定时器 clear timer
			}
		};
	});
	//点击事件
	// click event
	const clickImgFun = () => {
		//派发 Swiper 容器点击事件，currentIndicate 表示点击的容器索引值
		// dispatch the Swiper container click event, currentIndicate indicates the index value of the clicked container
		onclick?.(currentIndicate);
	};
	//滑动开始
	// slide start
	const touchstartFun = (e: PointerEvent) => {
		// 阻止默认事件
		// prevent default event
		e.preventDefault();
		isMove = true;
		startTime = new Date().getTime();
		translateXTransition = false;
		startX = e.clientX;
	};
	//滑动中
	// slideing
	const touchmoveFun = (e: PointerEvent) => {
		if (!isMove) return false;
		if (swiperDom) {
			swiperDom.setPointerCapture(e.pointerId);
		}
		if (intervalTime) {
			clearInterval(intervalTime); //清除定时器 clear timer
		}
		moveX = e.clientX - startX;
	};

	//滑动结束
	// slide end
	const touchendFun = () => {
		endTime = new Date().getTime();
		const moveXABS = Math.abs(moveX); //滑动距离，moveX 绝对值。slide distance, moveX absolute value
		const timeLong = endTime - startTime; //滑动时间  slide time
		const speed = moveXABS / timeLong; //滑动速度阈值  slide speed threshold

		//滑动距离大于等于容器宽度 triggerLong/100 不用考虑滑动速度，都触发切换。
		//滑动距离小于等于容器宽度 notTriggerLong/100，无论速度快慢都不触发切换。
		//滑动距离大于容器宽度 notTriggerLong/100 且小于 triggerLong/100，需要判断滑动速度，用一个速度阈值来判断。阈值大于等于 triggerSpeed 切换，否则不切换。
		// The sliding distance is greater than or equal to the container width triggerLong/100, and the sliding speed does not need to be considered, and the switching is triggered.
		// The sliding distance is less than or equal to the container width notTriggerLong/100, and the switching is not triggered regardless of the speed.
		// The sliding distance is greater than the container width notTriggerLong/100 and less than triggerLong/100, the sliding speed needs to be judged, and a speed threshold is used to judge. The threshold is greater than or equal to triggerSpeed to switch, otherwise it will not switch.

		isMove = false;
		translateXTransition = true;

		long = false;
		longTransition = false;
		setTimeout(() => {
			long = autoplay;
			longTransition = true;
		}, duration);
		if (moveX <= -(width * (triggerLong / 100))) {
			//左滑
			// slide left
			moveX = 0;
			currentIndicate++;
			active++;
			if (active === dataNew.length - 2) {
				//最后一个
				// the last one
				currentIndicate = 0;
				setTimeout(() => {
					// 切换动画完成后，关闭过渡动画，同时将展示的部分偷偷替换为最开始的样子。
					// After the switching animation is completed, turn off the transition animation, and at the same time, replace the displayed part with the original appearance.
					active = 1;
					translateXTransition = false;
				}, duration);
			}
		} else if (moveX >= width * (triggerLong / 100)) {
			moveX = 0;
			currentIndicate--;
			active--;
			if (active === 0) {
				//第 0 个
				// the first one
				currentIndicate = dataNew.length - 4;
				setTimeout(() => {
					// 切换动画完成后，关闭过渡动画，同时将展示的部分偷偷替换为最开始的样子。
					// After the switching animation is completed, turn off the transition animation, and at the same time, replace the displayed part with the original appearance.
					active = dataNew.length - 3;
					translateXTransition = false;
				}, duration);
			}
		} else if (moveXABS > (notTriggerLong / 100) * width && moveXABS < width * (triggerLong / 100)) {
			if (moveX < 0 && speed >= triggerSpeed) {
				//左滑
				// slide left
				moveX = 0;
				currentIndicate++;
				active++;
				if (active === dataNew.length - 2) {
					//最后一个
					// last one
					currentIndicate = 0;
					setTimeout(() => {
						// 切换动画完成后，关闭过渡动画，同时将展示的部分偷偷替换为最开始的样子。
						// After the switching animation is completed, turn off the transition animation, and at the same time, replace the displayed part with the original appearance.
						active = 1;
						translateXTransition = false;
					}, duration);
				}
			} else if (moveX > 0 && speed >= triggerSpeed) {
				//右滑
				// slide right
				moveX = 0;
				currentIndicate--;
				active--;
				if (active === 0) {
					//第 0 个
					// the first one
					currentIndicate = dataNew.length - 4;
					setTimeout(() => {
						// 切换动画完成后，关闭过渡动画，同时将展示的部分偷偷替换为最开始的样子。
						// After the switching animation is completed, turn off the transition animation, and at the same time, replace the displayed part with the original appearance.
						active = dataNew.length - 3;
						translateXTransition = false;
					}, duration);
				}
			} else {
				moveX = 0;
			}
		} else {
			moveX = 0;
		}
		if (autoplay) {
			if (intervalTime) {
				clearInterval(intervalTime); //清除定时器 clear timer
			}
			intervalTimeFun();
		} else {
			//派发 Swiper 容器 change 事件，i 表示当前容器索引值
			// Dispatch the Swiper container change event, i indicates the current container index value
			onchange?.(currentIndicate);
		}
	};
</script>

<div
	bind:this={swiperDom}
	onpointerdown={touchstartFun}
	onpointermove={touchmoveFun}
	onpointerup={touchendFun}
	class="cursor-move touch-none"
>
	<!-- 轮播容器 -->
	<!-- Carousel container -->
	<div class="relative overflow-hidden" style="width:{width}px;height:{(width * aspectRatio[1]) / aspectRatio[0]}px;perspective:{width}px;">
		<!-- 通过循环 dataNew 渲染多个 item -->
		<!-- Render multiple item through loop dataNew -->
		{#each dataNew as item, i}
			<div
				class="absolute {pxObj[px] || ''} {pyObj[py] || ''} {translateXTransition ? 'transition-all' : 'transition-none'} {i === active
					? activeInjClass
					: notActiveInjClass}"
				style="width:{width}px;height:{(width * aspectRatio[1]) / aspectRatio[0]}px;left:{width * (i - active) +
					moveX}px;transition-duration: {duration}ms;z-index:{zIndexFun(i, active, dataNew)};transform:translateX({translateXFun(
					i,
					active,
					translateX
				)}) translateZ({translateZFun(i, active, translateZ, movePercent)}) rotateX({rotateXFun(
					i,
					active,
					rotateX,
					movePercent
				)}) rotateY({rotateYFun(i, active, rotateY, movePercent)}) rotateZ({rotateZFun(i, active, rotateZ, movePercent)});"
			>
				{#if item.type === 'img'}
					<button type="button" onclick={clickImgFun} class="h-full w-full">
						<img class="h-full w-full object-cover {radiusObj[radius] || ''} {innerInjClass}" src={item.url} alt="" />
					</button>
				{/if}
				{#if item.type === 'component'}
					<div class="h-full w-full {radiusObj[radius] || ''} {innerInjClass}">
						<item.component />
					</div>
				{/if}
			</div>
		{/each}
		<!-- 轮播指示器 (内部) -->
		<!-- Carousel indicator (inner) -->
		<div
			class:hidden={data.length < 2 || indicatePosition === 'out' || indicatePosition === null}
			class="absolute bottom-0 z-50 flex w-full space-x-2 bg-gradient-to-b from-black/0 to-black/40 px-4 pb-2 pt-4 {indicateInjClass} {indicateAlignObj[
				indicateAlign
			] || indicateAlignObj.center}"
		>
			<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
			{#each data as _, i}
				<div
					class="{indicateStyleInnerFun(indicateStyle, currentIndicate === i, indicateColor, indicateActiveColor)} {indicateRadius &&
						'rounded-full'} transition-all"
					style="transition-duration: {duration}ms;"
				>
					{#if indicateStyle === 'longLine'}
						<div
							class="absolute h-1 transition-all {long ? 'ease-linear' : ''} {indicateRadius && 'rounded-full'} {long &&
							currentIndicate === i
								? 'w-16'
								: 'w-1'} {indicateActiveColor === '' ? 'bg-white' : indicateActiveColor}"
							style={longTransition
								? `transition-duration: ${currentIndicate === 0 && once ? interval * 1000 : interval * 1000 - duration}ms`
								: `transition-duration:${duration}ms`}
						></div>
					{/if}
				</div>
			{/each}
		</div>
	</div>
	<!-- 轮播指示器 (外部) -->
	<!-- Carousel indicator (outer) -->
	<div
		class:hidden={data.length < 2 || indicatePosition === 'inner' || indicatePosition === null}
		class="flex w-full space-x-2 px-4 py-3 {indicateAlignObj[indicateAlign] || indicateAlignObj.center} {indicateInjClass}"
	>
		<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
		{#each data as _, i}
			<div
				class="{indicateStyleOutFun(indicateStyle, currentIndicate === i, indicateColor, indicateActiveColor)} {indicateRadius &&
					'rounded-full'} transition-all"
				style="transition-duration: {duration}ms;"
			>
				{#if indicateStyle === 'longLine'}
					<div
						class="absolute h-1 transition-all {long ? 'ease-linear' : ''} {indicateRadius && 'rounded-full'} {long && currentIndicate === i
							? 'w-16'
							: 'w-1'} {indicateActiveColor === '' ? 'bg-primary dark:bg-dark' : indicateActiveColor}"
						style={longTransition
							? `transition-duration: ${currentIndicate === 0 && once ? interval * 1000 : interval * 1000 - duration}ms;`
							: `transition-duration:${duration}ms`}
					></div>
				{/if}
			</div>
		{/each}
	</div>
</div>



================================================
FILE: packages/stdf/src/lib/components/switch/Switch.svelte
================================================
<script lang="ts">
	import Loading from '../loading/Loading.svelte';
	import type { SwitchProps } from '../../types/index.js';

	let {
		active = false,
		radius = 'middle',
		inside = null,
		injClass = '',
		disabled = false,
		async = false,
		loading = {},
		trueChild,
		falseChild,
		onchange,
		onclick
	}: SwitchProps = $props();

	// 是否处于纵向拉长状态  is in the vertical elongation state
	let isLong = $state(false);
	const radiusObj = { none: 'rounded-none', middle: 'rounded-sm', full: 'rounded-full' };
	const setChangeFun = () => {
		if (!disabled) {
			if (!async) {
				active = !active;
				onchange?.(active);
			}
			onclick?.();
		}
	};
	$effect(() => {
		if (!disabled) {
			active = active;
			isLong = true;
			setTimeout(() => {
				isLong = false;
			}, 150);
		}
	});
</script>

<button
	onclick={setChangeFun}
	class="relative flex h-6 w-12 justify-around transition-all duration-500 active:opacity-80 {radiusObj[radius] || radiusObj.middle} {active
		? `bg-primary dark:bg-dark ${injClass}`
		: 'bg-black/10 dark:bg-white/20'} {disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'}"
>
	<div
		class="absolute top-0.5 h-5 w-5 bg-white text-center text-xs leading-5 text-black/80 transition-all duration-300 dark:bg-black dark:text-white/90 {radiusObj[
			radius
		] || radiusObj.middle}"
		style="left:{active ? '1.625rem' : '0.125rem'};transform:{isLong ? 'scaleX(1.3)' : 'scaleX(1)'}"
	>
		{#if inside === 'state'}
			<span class:hidden={!active}><div class="ml-2 mt-1 h-3 w-1 rounded-full bg-black/80 dark:bg-white/90"></div></span>
			<span class:hidden={active}><div class="ml-1 mt-1 h-3 w-3 rounded-full border-2 border-black/80 dark:border-white/90"></div></span>
		{:else if inside === 'loading'}
			<div class="m-0.5">
				<Loading width="full" height="full" {...loading} />
			</div>
		{:else if trueChild && falseChild}
			<span class={active ? '' : 'hidden'}>{@render trueChild?.()}</span>
			<span class={!active ? '' : 'hidden'}>{@render falseChild?.()}</span>
		{:else if Array.isArray(inside) && inside.length === 2}
			<span class={active ? '' : 'hidden'}>{inside[1]} </span>
			<span class={!active ? '' : 'hidden'}>{inside[0]} </span>
		{:else}{/if}
	</div>
</button>



================================================
FILE: packages/stdf/src/lib/components/tabBar/TabBar.svelte
================================================
<script lang="ts">
	import Icon from '../icon/Icon.svelte';
	import type { TabBarProps } from '../../types/index.js';

	let {
		labels = [],
		active = $bindable(0),
		line = false,
		lineW = 4,
		love = false,
		injClass = '',
		tabInjClass = '',
		activeTabInjClass = '',
		activeInjClass = '',
		onchange
	}: TabBarProps = $props();

	const clickFun = (i: number) => {
		active = i;
		onchange?.(active);
	};
	let tabW = $state(0);
	let activeW = $derived(tabW / labels.length / lineW);
	let activeLeft = $derived(active * (tabW / labels.length) + tabW / labels.length / 2 - activeW / 2);
</script>

<div bind:clientWidth={tabW} class="relative bg-white dark:bg-gray-800 {injClass}" style="padding-bottom: env(safe-area-inset-bottom);">
	{#if line}
		<div
			class="bg-primary dark:bg-dark absolute bottom-px mx-auto h-[2px] rounded-full transition-all {activeInjClass}"
			style="width: {lineW < 1 ? tabW / labels.length : activeW < 2 ? 2 : activeW}px;left: {lineW < 1
				? active * (tabW / labels.length)
				: activeLeft}px;"
		></div>
	{/if}
	<div class="flex justify-between">
		{#each labels as label, i}
			<button
				onclick={() => clickFun(i)}
				class="flex flex-1 flex-col items-center justify-center py-1 text-center active:opacity-80 {i === active
					? 'text-primary dark:text-dark'
					: 'text-black/80 dark:text-white/90'} {love ? 'text-lg' : 'text-sm'} {tabInjClass} {i === active && activeTabInjClass}"
			>
				{#if label.icon}
					<div class:py-2={!label.text}>
						<i class:hidden={i !== active}>
							<Icon
								{...label.icon}
								name={label.activeIcon ? label.activeIcon.name : label.icon.name}
								size={i === active
									? label.activeIcon?.size !== 'full' && label.activeIcon?.size
										? label.activeIcon.size * (love ? 1.2 : 1)
										: label.icon.size !== 'full' && label.icon.size
											? label.icon.size * (love ? 1.2 : 1)
											: undefined
									: label.icon.size !== 'full' && label.icon.size
										? label.icon.size * (love ? 1.2 : 1)
										: undefined}
								top={0}
							/>
						</i>
						<i class:hidden={i === active}>
							<Icon
								{...label.icon}
								name={label.icon.name}
								size={i === active
									? label.activeIcon?.size !== 'full' && label.activeIcon?.size
										? label.activeIcon.size * (love ? 1.2 : 1)
										: label.icon.size !== 'full' && label.icon.size
											? label.icon.size * (love ? 1.2 : 1)
											: undefined
									: label.icon.size !== 'full' && label.icon.size
										? label.icon.size * (love ? 1.2 : 1)
										: undefined}
								top={0}
							/>
						</i>
					</div>
				{/if}
				{#if label.text}
					<div class="{label.icon ? 'mt-[2px]' : 'py-1 text-lg'} {i === active && !label.icon ? ' font-bold' : ''}">
						{label.text}
					</div>
				{/if}
			</button>
		{/each}
	</div>
</div>



================================================
FILE: packages/stdf/src/lib/components/tabs/Tab.svelte
================================================
<script lang="ts">
	import Icon from '../icon/Icon.svelte';
	import type { TabProps } from '../../types/index.js';

	let {
		labels = [],
		active = $bindable(0),
		lineType = false,
		radius = 'sm',
		duration = 'base',
		layout = 'h',
		love = false,
		injClass = '',
		tabInjClass = '',
		activeTabInjClass = '',
		activeInjClass = '',
		mx = '2',
		overflow = false,
		showNum = 3,
		autoScroll = true,
		onclickTab
	}: TabProps = $props();

	const radiusObj = { none: 'rounded-none', sm: 'rounded-sm', xl: 'rounded-xl', full: 'rounded-full' };
	const durationObj = { fast: 'duration-150', base: 'duration-300', slow: 'duration-500', slower: 'duration-1000' };
	const mxClass = {
		'0': 'mx-0',
		'1': 'mx-1',
		'2': 'mx-2',
		'3': 'mx-3',
		'4': 'mx-4',
		'6': 'mx-6',
		'8': 'mx-8',
		'12': 'mx-12',
		'16': 'mx-16',
		'20': 'mx-20'
	};

	const clickTabFun = (i: number) => {
		active = i;
		onclickTab?.(i);
	};
	let tabW = $state(0);
	let tabH = $state(0);
	let activeW = $derived(layout === 'h' ? (tabW - 4) / labels.length : tabW - 4);
	let activeH = $derived(layout === 'h' ? tabH - 4 : (tabH - 4) / labels.length);
	let activeLeft = $derived(layout === 'h' ? 2 + active * ((tabW - 4) / labels.length) : 2);
	let activeTop = $derived(layout === 'h' ? (lineType ? tabH - 2 : 2) : 2 + active * ((tabH - 4) / labels.length));

	// 溢出模式下的变量
	// variables in overflow mode
	let ofTabW = $state(0);
	let ofTabH = $state(0);
	let itemW = $derived((ofTabW - 4) / (showNum + 0.5));
	let ofActiveW = $derived((ofTabW - 4) / (showNum + 0.5));
	let ofActiveH = $derived(ofTabH - 4);
	let ofActiveLeft = $derived(2 + active * ((ofTabW - 4) / (showNum + 0.5)));

	let ofDom = $state<HTMLDivElement | null>(null);
	let showIndexs = $state(new Array(showNum + 1).fill(0).map((item, index) => index));
	// 监听 active 变化，当 active 变化时，如果 active 不在可视区域内，则滚动 ofDom，使 active 显示在中间
	// listen to the change of active, when active changes, if active is not in the visible area, scroll ofDom to make active display in the middle
	$effect(() => {
		if (ofDom && active !== undefined && autoScroll) {
			// 如果 active >= showIndexs 的最后一个元素或 <= showIndexs 的第一个元素，则滚动 ofDom，滚动至 active*itemW
			// If active >= the last element of showIndexs or <= the first element of showIndexs, scroll ofDom to active*itemW
			if (active >= showIndexs[showIndexs.length - 1] || active <= showIndexs[0]) {
				ofDom.scrollLeft = (active - 1) * itemW;
				showIndexs = new Array(showNum + 1).fill(0).map((item, index) => index + active - 1);
			}
		}
	});
</script>

{#if overflow && layout === 'h'}
	<div
		bind:clientWidth={ofTabW}
		bind:clientHeight={ofTabH}
		bind:this={ofDom}
		class="{lineType ? '' : 'bg-black/5 dark:bg-white/10'} no-scrollbar relative overflow-auto scroll-smooth p-0.5 {radiusObj[radius] ||
			radiusObj.sm} {mxClass[mx] || mxClass['2']} {injClass}"
	>
		{#if lineType}
			<div class="absolute bottom-0 h-0.5 w-full bg-black/5 dark:bg-white/5" style="width: {itemW * labels.length}px"></div>
		{/if}
		<div
			class="{lineType ? '' : 'dark:shadow-xs shadow-sm dark:shadow-white/10'} absolute transition-all {durationObj[duration] ||
				durationObj.base} {radiusObj[radius] || radiusObj.sm} {lineType
				? 'bg-primary dark:bg-dark bottom-0'
				: 'bg-white dark:bg-gray-950'} {activeInjClass}"
			style="width: {ofActiveW}px;height: {lineType ? 2 : ofActiveH}px;left: {ofActiveLeft}px;"
		></div>
		<div class="relative flex whitespace-nowrap" style="width: {itemW * labels.length + 2}px;">
			{#each labels as label, i}
				<button
					class="flex shrink-0 justify-center overflow-hidden py-1 font-medium {love ? 'text-lg' : 'text-sm'} leading-6 {radiusObj[
						radius
					] || radiusObj.sm} {tabInjClass} {i === active ? activeTabInjClass : ''}"
					style="width: {itemW}px"
					onclick={() => clickTabFun(i)}
				>
					{#if label.icon}
						<div class="mr-0.5 {durationObj[duration] || durationObj.base}">
							<Icon {...label.icon} />
						</div>
					{/if}
					{#if label.text}
						<div class="transition-all {durationObj[duration] || durationObj.base}">{label.text}</div>
					{/if}
				</button>
			{/each}
		</div>
	</div>
{:else}
	<div
		bind:clientWidth={tabW}
		bind:clientHeight={tabH}
		class="{lineType && layout !== 'v' ? '' : 'bg-black/5 dark:bg-white/10'} relative p-0.5 {radiusObj[radius] || radiusObj.sm} {mxClass[
			mx
		] || mxClass['2']} {injClass}"
	>
		{#if lineType && layout !== 'v'}
			<div class="absolute bottom-0 h-0.5 w-full bg-black/5 dark:bg-white/5" style="width: {tabW - 4}px"></div>
		{/if}
		<div
			class="{lineType && layout !== 'v' ? '' : 'dark:shadow-xs shadow-sm dark:shadow-white/10'} absolute transition-all {durationObj[
				duration
			] || durationObj.base} {radiusObj[radius] || radiusObj.sm} {lineType && layout !== 'v'
				? 'bg-primary dark:bg-dark bottom-0'
				: 'bg-white dark:bg-gray-950'} {activeInjClass}"
			style="width: {activeW}px;height: {lineType && layout !== 'v' ? 2 : activeH}px;left: {activeLeft}px;top: {activeTop}px"
		></div>
		<div class="relative {layout === 'h' ? 'flex justify-between' : 'whitespace-nowrap px-4'}">
			{#each labels as label, i}
				<button
					class="flex flex-1 justify-center {layout === 'h' ? 'py-1' : 'py-2'} overflow-hidden font-medium {love
						? 'text-lg'
						: 'text-sm'} leading-6 {radiusObj[radius] || radiusObj.sm} {tabInjClass} {i === active ? activeTabInjClass : ''}"
					onclick={() => clickTabFun(i)}
				>
					{#if label.icon}
						<div class="mr-0.5 {durationObj[duration] || durationObj.base}">
							<Icon {...label.icon} />
						</div>
					{/if}
					{#if label.text}
						<div class="transition-all {durationObj[duration] || durationObj.base}">{label.text}</div>
					{/if}
				</button>
			{/each}
		</div>
	</div>
{/if}

<style>
	.no-scrollbar::-webkit-scrollbar {
		display: none;
	}
</style>



================================================
FILE: packages/stdf/src/lib/components/tabs/TabContent.svelte
================================================
<script lang="ts">
	import type { TabContentProps } from '../../types/index.js';

	let { show = true, children }: TabContentProps = $props();
</script>

<div class:hidden={!show} class="flex-1">
	{@render children?.()}
</div>



================================================
FILE: packages/stdf/src/lib/components/tabs/Tabs.svelte
================================================
<script lang="ts">
	import Tab from './Tab.svelte';
	import type { TabsProps } from '../../types/index.js';

	let { tab = {}, duration = 'base', position = 't', active = $bindable(0), transition = true, onchange, children }: TabsProps = $props();
	const clickTabFun = (a: number) => {
		active = a;
		onchange?.(a);
	};
	let width = $state(window.innerWidth);

	const durationObj = { fast: 'duration-150', base: 'duration-300', slow: 'duration-500', slower: 'duration-1000' };
</script>

{#if transition}
	{#if position === 't'}
		<Tab {active} {duration} {...tab} onclickTab={clickTabFun} />
		<div class="overflow-hidden" bind:clientWidth={width}>
			<div
				class="relative flex transition-all {durationObj[duration] || durationObj.base}"
				style="width: {(tab?.labels?.length ?? 0) * width}px;left: -{active * width}px"
			>
				{#if children}{@render children({ active })}{/if}
			</div>
		</div>
	{/if}
	{#if position === 'b'}
		<div class="overflow-hidden" bind:clientWidth={width}>
			<div
				class="relative flex transition-all {durationObj[duration] || durationObj.base}"
				style="width: {(tab?.labels?.length ?? 0) * width}px;left: -{active * width}px"
			>
				{#if children}{@render children({ active })}{/if}
			</div>
		</div>
		<Tab {active} {...tab} onclickTab={clickTabFun} />
	{/if}
	{#if position === 'l'}
		<div class="flex">
			<div>
				<Tab {active} {...tab} onclickTab={clickTabFun} layout="v" />
			</div>
			<div class="grow">
				{#if children}{@render children({ active })}{/if}
			</div>
		</div>
	{/if}
	{#if position === 'r'}
		<div class="flex">
			<div class="grow">
				{#if children}{@render children({ active })}{/if}
			</div>
			<div>
				<Tab {active} {...tab} onclickTab={clickTabFun} layout="v" />
			</div>
		</div>
	{/if}
{:else}
	{#if position === 't'}
		<Tab {active} {duration} {...tab} onclickTab={clickTabFun} />
		{#if children}{@render children({ active })}{/if}
	{/if}
	{#if position === 'b'}
		{#if children}{@render children({ active })}{/if}
		<Tab {active} {...tab} onclickTab={clickTabFun} />
	{/if}
	{#if position === 'l'}
		<div class="flex">
			<div>
				<Tab {active} {...tab} onclickTab={clickTabFun} layout="v" />
			</div>
			<div class="grow">
				{#if children}{@render children({ active })}{/if}
			</div>
		</div>
	{/if}
	{#if position === 'r'}
		<div class="flex">
			<div class="grow">
				{#if children}{@render children({ active })}{/if}
			</div>
			<div>
				<Tab {active} {...tab} onclickTab={clickTabFun} layout="v" />
			</div>
		</div>
	{/if}
{/if}



================================================
FILE: packages/stdf/src/lib/components/timePicker/TimePicker.svelte
================================================
<script lang="ts">
	import { getContext } from 'svelte';
	import Popup from '../popup/Popup.svelte';
	import ScrollRadio from '../scrollRadio/ScrollRadio.svelte';
	import { getDayNum } from '../utils/index.js';
	import { zh_CN, type LangProps } from '../../lang/index.js';
	import type { TimePickerProps, TimePickerObjProps } from '../../types/index.js';

	// 当前语言
	// current language
	const currentLang = (getContext('STDF_lang') || zh_CN) as LangProps;
	const timePickerLang: LangProps['timePicker'] = currentLang.timePicker;

	let {
		visible = $bindable(false),
		type = 'YYYYMMDDhhmmss',
		yearProps = {},
		monthProps = {},
		dayProps = {},
		hourProps = {},
		minuteProps = {},
		secondProps = {},
		initYear = '',
		initMonth = '',
		initDay = '',
		initHour = '',
		initMinute = '',
		initSecond = '',
		minuteStep = 1,
		secondStep = 1,
		yearRange = [],
		monthRange = [1, 12],
		hourRange = [0, 23],
		minuteRange = [0, 59],
		secondRange = [0, 59],
		showTips = true,
		cancelText = timePickerLang.defaultCancel,
		confirmText = timePickerLang.defaultConfirm,
		title = timePickerLang.defaultTitle,
		yearText = timePickerLang.defaultYear,
		monthText = timePickerLang.defaultMonth,
		dayText = timePickerLang.defaultDay,
		hourText = timePickerLang.defaultHour,
		minuteText = timePickerLang.defaultMinute,
		secondText = timePickerLang.defaultSecond,
		outFormat = '',
		popup = {},
		onclose,
		onconfirm,
		oncancel
	}: TimePickerProps = $props();

	// 获取当前时间，取出对应的年月日时分秒，转成字符，月、日、时、分、秒小于 10 的前面补 0
	// Get the current time, take out the corresponding year, month, day, hour, minute, and second, convert to a character, and add 0 to the front of month, day, hour, minute, and second less than 10
	const now = new Date();
	const currentYear = now.getFullYear().toString();
	const currentMonth = (now.getMonth() + 1 < 10 ? '0' + (now.getMonth() + 1) : now.getMonth() + 1).toString();
	const currentDay = (now.getDate() < 10 ? '0' + now.getDate() : now.getDate()).toString();
	const currentHour = (now.getHours() < 10 ? '0' + now.getHours() : now.getHours()).toString();
	const currentMinute = (now.getMinutes() < 10 ? '0' + now.getMinutes() : now.getMinutes()).toString();
	const currentSecond = (now.getSeconds() < 10 ? '0' + now.getSeconds() : now.getSeconds()).toString();

	// 总共可以传入 13 种 type，做一个映射，方便后面使用
	// A total of 13 types can be passed in, do a mapping, and it is convenient to use later
	const typeMap = {
		YYYY: 'YYYY',
		MM: 'MM',
		hh: 'hh',
		mm: 'mm',
		ss: 'ss',
		YYYYMM: 'YYYYMM',
		hhmm: 'hhmm',
		mmss: 'mmss',
		YYYYMMDD: 'YYYYMMDD',
		hhmmss: 'hhmmss',
		YYYYMMDDhh: 'YYYYMMDDhh',
		YYYYMMDDhhmm: 'YYYYMMDDhhmm',
		YYYYMMDDhhmmss: 'YYYYMMDDhhmmss'
	};

	// 定义 typeInner，对不在 typeMap 的 type 做一个过滤，不在 typeMap 的 type 设置为默认值 YMDhms
	// Define typeInner, filter out types that are not in typeMap, and set types that are not in typeMap to the default value YMDhms
	let typeInner = typeMap[type] || 'YYYYMMDDhhmmss';

	// 如果 yearRange 长度为2且后一项大于前一项，表示限定区间，否则取当前年的的前后 10 年
	// If the length of yearRange is 2 and the second item is greater than the first item, it means that the range is limited, otherwise the previous and next 10 years of the current year are taken
	let yearData = [];
	if (yearRange.length === 2 && yearRange[1] > yearRange[0]) {
		for (let i = yearRange[0]; i <= yearRange[1]; i++) {
			yearData.push({ label: i.toString() });
		}
	} else {
		for (let i = now.getFullYear() - 10; i <= now.getFullYear() + 10; i++) {
			yearData.push({ label: i.toString() });
		}
	}

	// 月份列数据，固定 12 个月，如果有限定区间
	// Month column data, fixed 12 months, if there is a limited range, it needs to be judged according to the year
	const baseMonthData: { label: string }[] = [];
	if (monthRange.length === 2 && monthRange[1] > monthRange[0] && monthRange[0] >= 1 && monthRange[1] <= 12) {
		for (let i = monthRange[0]; i <= monthRange[1]; i++) {
			baseMonthData.push({ label: (i < 10 ? '0' + i : i).toString() });
		}
	} else {
		for (let i = 1; i <= 12; i++) {
			baseMonthData.push({ label: (i < 10 ? '0' + i : i).toString() });
		}
	}

	// 小时列数据，根据限定小时区间计算
	// Hour column data, fixed 24 hours
	const baseHourData: { label: string }[] = [];
	if (hourRange.length === 2 && hourRange[1] > hourRange[0] && hourRange[0] >= 0 && hourRange[1] <= 23) {
		for (let i = hourRange[0]; i <= hourRange[1]; i++) {
			baseHourData.push({ label: (i < 10 ? '0' + i : i).toString() });
		}
	} else {
		for (let i = 0; i < 24; i++) {
			baseHourData.push({ label: (i < 10 ? '0' + i : i).toString() });
		}
	}

	// 分钟列数据，根据限定分钟区间计算
	// Minute column data, calculated according to the limited minute range
	const baseMinuteData: { label: string }[] = [];
	if (minuteRange.length === 2 && minuteRange[1] > minuteRange[0] && minuteRange[0] >= 0 && minuteRange[1] <= 59) {
		for (let i = minuteRange[0]; i <= minuteRange[1]; i += minuteStep) {
			baseMinuteData.push({ label: (i < 10 ? '0' + i : i).toString() });
		}
	} else {
		for (let i = 0; i < 60; i += minuteStep) {
			baseMinuteData.push({ label: (i < 10 ? '0' + i : i).toString() });
		}
	}

	// 秒列数据，根据限定秒区间计算
	// Second column data, calculated according to the limited second range
	const baseSecondData: { label: string }[] = [];
	if (secondRange.length === 2 && secondRange[1] > secondRange[0] && secondRange[0] >= 0 && secondRange[1] <= 59) {
		for (let i = secondRange[0]; i <= secondRange[1]; i += secondStep) {
			baseSecondData.push({ label: (i < 10 ? '0' + i : i).toString() });
		}
	} else {
		for (let i = 0; i < 60; i += secondStep) {
			baseSecondData.push({ label: (i < 10 ? '0' + i : i).toString() });
		}
	}

	// 找出 yearProps、monthProps、dayProps、hourProps、minuteProps、secondProps 中 showRow 的最大值
	// Find the maximum value of showRow in yearProps, monthProps, dayProps, hourProps, minuteProps, and secondProps
	const showRowsArr: number[] = [];
	showRowsArr.push(yearProps.showRow || 5);
	showRowsArr.push(monthProps.showRow || 5);
	showRowsArr.push(dayProps.showRow || 5);
	showRowsArr.push(hourProps.showRow || 5);
	showRowsArr.push(minuteProps.showRow || 5);
	showRowsArr.push(secondProps.showRow || 5);
	const maxShowRows = Math.max(...showRowsArr);

	// 天数列数据
	// Day column data
	let baseDayData = $state<{ label: string }[]>([]);

	// 根据当前年月初始一次天数列数据
	// Initialize the day column data according to the current year and month
	const tempDayData = [];
	for (let i = 1; i <= getDayNum(currentYear, currentMonth); i++) {
		tempDayData.push({ label: (i < 10 ? '0' + i : i).toString() });
	}
	baseDayData = tempDayData;

	// 初始时年份索引
	// Initial year index
	const initYearIndex =
		initYear === ''
			? yearData.findIndex((item) => item.label === currentYear)
			: yearData.findIndex((item) => item.label === initYear?.toString());

	// 初始时月份索引
	// Initial month index
	const initMonthIndex =
		initMonth === ''
			? baseMonthData.findIndex((item) => item.label === currentMonth)
			: baseMonthData.findIndex((item) => item.label === initMonth.toString());

	// 初始时天数索引
	// Initial day index
	let initDayIndex = $state(
		initDay === ''
			? tempDayData.findIndex((item) => item.label === currentDay)
			: tempDayData.findIndex((item) => item.label === initDay.toString())
	);

	// 初始时小时索引
	// Initial hour index
	const initHourIndex =
		initHour === ''
			? baseHourData.findIndex((item) => item.label === currentHour)
			: baseHourData.findIndex((item) => item.label === initHour.toString());

	// 初始时分钟索引
	// Initial minute index
	const initMinuteIndex =
		initMinute === ''
			? baseMinuteData.findIndex((item) => item.label === currentMinute)
			: baseMinuteData.findIndex((item) => item.label === initMinute.toString());

	// 初始时秒索引
	// Initial second index
	const initSecondIndex =
		initSecond === ''
			? baseSecondData.findIndex((item) => item.label === currentSecond)
			: baseSecondData.findIndex((item) => item.label === initSecond.toString());

	// 年月日时分秒初始索引
	// Year, month, day, hour, minute, second initial index
	let yearIndex = 0;
	let monthIndex = 0;
	let dayIndex = 0;
	let hourIndex = 0;
	let minuteIndex = 0;
	let secondIndex = 0;

	// 根据年份和月份获取对应的天数，更新 baseDayData
	// Get the number of days corresponding to the year and month according to the year and month, and update baseDayData
	const updateDayDataFunc = (dayNum: number) => {
		baseDayData = [];
		for (let i = 1; i <= dayNum; i++) {
			baseDayData.push({ label: (i < 10 ? '0' + i : i).toString() });
		}
	};

	// 初始一下生成天数数据
	// Generate day data initially
	updateDayDataFunc(getDayNum(yearData[yearIndex].label, baseMonthData[monthIndex].label));

	// 年数据滚动结束时的回调函数
	// Callback function when the year data scrolling ends
	const scrollEndYearFunc = (index: number, isTouch: boolean) => {
		yearIndex = index;
		// 如果月份是 2 月，需要重新计算天数
		// If the month is February, the number of days needs to be recalculated
		if (isTouch && baseMonthData[monthIndex].label === '02') {
			baseDayData = [];
			initDayIndex = 0;
			setTimeout(() => {
				updateDayDataFunc(getDayNum(yearData[yearIndex].label, baseMonthData[monthIndex].label));
			});
		}
	};

	// 月数据滚动结束时的回调函数
	// Callback function when the month data scrolling ends
	const scrollEndMonthFunc = (index: number, isTouch: boolean) => {
		monthIndex = index;
		// 根据年份和月份获取对应的天数
		// Get the number of days corresponding to the year and month according to the year and month
		if (isTouch) {
			baseDayData = [];
			initDayIndex = 0;
			setTimeout(() => {
				updateDayDataFunc(getDayNum(yearData[yearIndex].label, baseMonthData[monthIndex].label));
			});
		}
	};

	// 点击取消按钮的回调函数
	// Callback function when clicking the cancel button
	const clickCancelFunc = () => {
		visible = false;
		oncancel?.();
		onclose?.();
	};

	// 传入时间格式与时间对象，返回时间字符串
	// Pass in the time format and time object, return the time string
	const getTimeStr = (format: string, timeObj: TimePickerObjProps) => {
		const { YYYY, MM, DD, hh, mm, ss } = timeObj;
		const timeStr = format.replace('YYYY', YYYY).replace('MM', MM).replace('DD', DD).replace('hh', hh).replace('mm', mm).replace('ss', ss);
		return timeStr;
	};

	// 点击确定按钮的回调函数
	// Callback function when clicking the confirm button
	const clickConfirmFunc = () => {
		visible = false;
		onclose?.();
		const outData: TimePickerObjProps = { YYYY: '', MM: '', DD: '', hh: '', mm: '', ss: '' };
		if (typeInner.includes('YYYY')) {
			outData.YYYY = yearData[yearIndex].label;
		}
		if (typeInner.includes('MM')) {
			outData.MM = baseMonthData[monthIndex].label;
		}
		if (typeInner.includes('DD')) {
			outData.DD = baseDayData[dayIndex].label;
		}
		if (typeInner.includes('hh')) {
			outData.hh = baseHourData[hourIndex].label;
		}
		if (typeInner.includes('mm')) {
			outData.mm = baseMinuteData[minuteIndex].label;
		}
		if (typeInner.includes('ss')) {
			outData.ss = baseSecondData[secondIndex].label;
		}

		// 如果 outFormat 为空，则根据 type 格式
		// If outFormat is empty, format according to type
		if (outFormat === '') {
			// 预先根据 typeInner 生成一份 defaultOutFormat 字符，年月日之间用 - 连接，时分秒之间用 : 连接，年月日和时分秒之间用空格连接
			// Generate a copy of defaultOutFormat characters according to typeInner in advance, and connect the year, month and day with -, and connect the hour, minute and second with :, and connect the year, month, day and hour, minute and second with spaces
			let defaultOutFormat = typeInner
				.replace(/YYYY/g, 'YYYY-')
				.replace(/MM/g, 'MM-')
				.replace(/DD/g, 'DD ')
				.replace(/hh/g, 'hh:')
				.replace(/mm/g, 'mm:')
				.replace(/ss/g, 'ss');
			// 如果 defaultOutFormat 以 - 或 : 或空格 结尾，则去掉最后一个字符
			// If defaultOutFormat ends with - or : or space, remove the last character
			if (defaultOutFormat.endsWith('-') || defaultOutFormat.endsWith(':') || defaultOutFormat.endsWith(' ')) {
				defaultOutFormat = defaultOutFormat.slice(0, -1);
			}
			onconfirm?.(getTimeStr(defaultOutFormat, outData), outData);
		} else {
			// 将 outFormat 里面 YYYY MM DD hh mm ss 替换为对应的 outData 中的值
			// Replace YYYY MM DD hh mm ss in outFormat with the corresponding value in outData
			const outFormatInner = outFormat
				.replace(/YYYY/g, outData.YYYY)
				.replace(/MM/g, outData.MM)
				.replace(/DD/g, outData.DD)
				.replace(/hh/g, outData.hh)
				.replace(/mm/g, outData.mm)
				.replace(/ss/g, outData.ss);
			// 如果 outFormat 为空，则返回时间对象，否则返回时间字符串
			// If outFormat is empty, return the time object, otherwise return the time string
			onconfirm?.(getTimeStr(outFormatInner, outData), outData);
		}
	};
</script>

<Popup
	bind:visible
	size={0}
	maskClosable
	transitionDistance={(maxShowRows === 3 ? 64 : maxShowRows === 5 ? 48 : 32) * maxShowRows + 41 + (showTips ? 32 : 0)}
	{...popup}
>
	<div class="flex items-center justify-between border-b border-black/10 bg-white dark:border-white/20 dark:bg-black">
		<button class="h-10 cursor-pointer px-4 leading-10 text-black/60 dark:text-white/60" onclick={clickCancelFunc}>{cancelText}</button>
		<div>{title}</div>
		<button class="text-primary dark:text-dark h-10 cursor-pointer px-4 leading-10" onclick={clickConfirmFunc}>{confirmText}</button>
	</div>
	{#if showTips}
		<div
			class="flex h-8 items-center justify-around gap-1 bg-white text-center text-sm leading-8 text-black/60 dark:bg-black dark:text-white/60"
		>
			{#if typeInner.includes('Y')}
				<div class="px-2" style="flex:{yearProps.flex || '1'};text-align:{yearProps.align}">{yearText}</div>{/if}
			{#if typeInner.includes('M')}
				<div class="px-2" style="flex:{monthProps.flex || '1'};text-align:{monthProps.align}">{monthText}</div>{/if}
			{#if typeInner.includes('D')}
				<div class="px-2" style="flex:{dayProps.flex || '1'};text-align:{dayProps.align}">{dayText}</div>{/if}
			{#if typeInner.includes('h')}
				<div class="px-2" style="flex:{hourProps.flex || '1'};text-align:{hourProps.align}">{hourText}</div>{/if}
			{#if typeInner.includes('m')}
				<div class="px-2" style="flex:{minuteProps.flex || '1'};text-align:{minuteProps.align}">{minuteText}</div>{/if}
			{#if typeInner.includes('s')}
				<div class="px-2" style="flex:{secondProps.flex || '1'};text-align:{secondProps.align}">{secondText}</div>{/if}
		</div>
	{/if}
	<div class="flex items-center justify-around gap-1 bg-white dark:bg-black">
		{#if typeInner.includes('Y')}
			<div class="truncate" style="flex:{yearProps.flex || '1'}">
				<ScrollRadio data={yearData} initIndex={initYearIndex} autoScrollToLast={false} {...yearProps} onscrollEnd={scrollEndYearFunc} />
			</div>
		{/if}
		{#if typeInner.includes('M')}
			<div class="truncate" style="flex:{monthProps.flex || '1'}">
				<ScrollRadio data={baseMonthData} lastSelectedIndex={initMonthIndex} {...monthProps} onscrollEnd={scrollEndMonthFunc} />
			</div>
		{/if}
		{#if baseDayData.length > 0 && typeInner.includes('D')}
			<div class="truncate" style="flex:{dayProps.flex || '1'}">
				<ScrollRadio data={baseDayData} lastSelectedIndex={initDayIndex} {...dayProps} onscrollEnd={(index) => (dayIndex = index)} />
			</div>
		{/if}
		{#if typeInner.includes('h')}
			<div class="truncate" style="flex:{hourProps.flex || '1'}">
				<ScrollRadio data={baseHourData} lastSelectedIndex={initHourIndex} {...hourProps} onscrollEnd={(index) => (hourIndex = index)} />
			</div>
		{/if}
		{#if typeInner.includes('m')}
			<div class="truncate" style="flex:{minuteProps.flex || '1'}">
				<ScrollRadio
					data={baseMinuteData}
					lastSelectedIndex={initMinuteIndex}
					{...minuteProps}
					onscrollEnd={(index) => (minuteIndex = index)}
				/>
			</div>
		{/if}
		{#if typeInner.includes('s')}
			<div class="truncate" style="flex:{secondProps.flex || '1'}">
				<ScrollRadio
					data={baseSecondData}
					lastSelectedIndex={initSecondIndex}
					{...secondProps}
					onscrollEnd={(index) => (secondIndex = index)}
				/>
			</div>
		{/if}
	</div>
</Popup>



================================================
FILE: packages/stdf/src/lib/components/toast/Toast.svelte
================================================
<script lang="ts">
	import Loading from '../loading/Loading.svelte';
	import Icon from '../icon/Icon.svelte';
	import Mask from '../mask/Mask.svelte';
	import Transition from './Transition.svelte';
	import type { ToastProps } from '../../types/index.js';

	let {
		message = '',
		visible = $bindable(false),
		duration = 2000,
		position = 'center',
		py = '0',
		radius = 'sm',
		transitionType = 'scale',
		transitionParams = {},
		outDuration = 0,
		zIndex = 1000,
		type = null,
		mask = {},
		loading = {},
		icon = {},
		clickable = false,
		dynamicFixed = true,
		children,
		onclose
	}: ToastProps = $props();

	$effect(() => {
		if (visible) {
			if (duration === 0) {
				//不自动关闭  not auto close
			} else {
				setTimeout(() => {
					visible = false;
					onclose?.();
				}, duration);
			}
		}
	});

	const typeObj = { success: 'checkbox-circle', error: 'close-circle', warning: 'error-warning', info: 'information' };
	const positionClass = { center: ' justify-center', top: ' justify-start', bottom: ' justify-end' };
	const pyClass = { '0': ' py-0', '10': ' py-10', '20': ' py-20', '40': ' py-40', '60': ' py-60', '80': ' py-80' };
	const radiusClass = {
		sm: ' rounded-sm',
		full: ' rounded-full',
		none: ' rounded-none',
		xs: ' rounded-xs',
		md: ' rounded-md',
		lg: ' rounded-lg',
		xl: ' rounded-xl',
		'2xl': ' rounded-2xl'
	};
	const typeColor = { success: 'text-success', error: 'text-error', warning: 'text-warning', info: 'text-info' };

	//解决 Safari 和 Chrome 或其他浏览器滚动时工具栏隐藏与显示引发的窗口高度变化问题
	// First we get the viewport height and we multiple it by 1% to get a value for a vh unit
	// let vh = window.innerHeight * 0.01;
	// // Then we set the value in the --vh custom property to the root of the document
	// document.documentElement.style.setProperty('--vh', `${vh}px`);
	// // We listen to the resize event
	// window.addEventListener('resize', () => {
	//     // We execute the same script as before
	//     let vh = window.innerHeight * 0.01;
	//     document.documentElement.style.setProperty('--vh', `${vh}px`);
	// });

	let innerHeight = $state(0);
	$effect(() => {
		innerHeight = window.innerHeight;
	});
	if (dynamicFixed) {
		//解决 Safari 和 Chrome 或其他浏览器滚动时工具栏隐藏与显示引发的窗口高度变化问题
		// First we get the viewport height and we multiple it by 1% to get a value for a vh unit
		window.addEventListener('resize', () => {
			innerHeight = window.innerHeight;
		});
	}
</script>

{#if visible}
	<Mask {visible} {clickable} opacity="0" {outDuration} {...mask} />
{/if}
{#if visible}
	<div
		class="fixed inset-0 flex h-screen w-screen flex-col{positionClass[position] || positionClass['center']}{position === 'center'
			? ''
			: pyClass[py] || pyClass['20']} w-full h-full${clickable ? ' pointer-events-none' : ''}"
		style="z-index:{zIndex};height:{innerHeight}px;"
	>
		<Transition {visible} {transitionType} {transitionParams} {outDuration}>
			<div class="flex justify-center px-10">
				<div
					class="inline-block bg-black/90 text-center dark:bg-white/90 p-4{radiusClass[radius] ||
						radiusClass.sm} text-white dark:text-black"
				>
					{#if children}
						{@render children()}
					{:else}
						{#if type !== null}
							<div class="mb-2">
								{#if type === 'loading'}
									<Loading inverse {...loading} />
								{:else if type === 'icon'}
									<Icon size={30} {...icon} />
								{:else if type === 'success' || type === 'error' || type === 'warning' || type === 'info'}
									<Icon name={`ri-${typeObj[type]}-line`} injClass={typeColor[type]} size={30} {...icon} />
								{:else}{/if}
							</div>
						{/if}
						<div>
							{message}
						</div>
					{/if}
				</div>
			</div>
		</Transition>
	</div>
{/if}



================================================
FILE: packages/stdf/src/lib/components/toast/Transition.svelte
================================================
<script lang="ts">
	import type { Snippet } from 'svelte';
	import {
		fade,
		fly,
		blur,
		slide,
		scale,
		type ScaleParams,
		type FlyParams,
		type SlideParams,
		type BlurParams,
		type FadeParams
	} from 'svelte/transition';

	type Props = {
		visible: boolean;
		transitionType: 'scale' | 'fly' | 'slide' | 'blur' | 'fade' | null;
		transitionParams: ScaleParams | FlyParams | SlideParams | BlurParams | FadeParams;
		outDuration: number;
		children: Snippet;
	};
	let { visible = false, transitionType = 'scale', transitionParams = {}, outDuration = 0, children }: Props = $props();
</script>

{#if visible}
	{#if transitionType === 'scale'}
		<div in:scale|global={{ duration: 300, ...transitionParams }} out:scale|global={{ ...transitionParams, duration: outDuration }}>
			{@render children?.()}
		</div>
	{:else if transitionType === 'fly'}
		<div in:fly|global={{ duration: 300, ...transitionParams }} out:fly|global={{ ...transitionParams, duration: outDuration }}>
			{@render children?.()}
		</div>
	{:else if transitionType === 'fade'}
		<div in:fade|global={{ duration: 300, ...transitionParams }} out:fade|global={{ ...transitionParams, duration: outDuration }}>
			{@render children?.()}
		</div>
	{:else if transitionType === 'slide'}
		<div in:slide|global={{ duration: 300, ...transitionParams }} out:slide|global={{ ...transitionParams, duration: outDuration }}>
			{@render children?.()}
		</div>
	{:else if transitionType === 'blur'}
		<div in:blur|global={{ duration: 300, ...transitionParams }} out:blur|global={{ ...transitionParams, duration: outDuration }}>
			{@render children?.()}
		</div>
	{:else}
		{@render children?.()}
	{/if}
{/if}



================================================
FILE: packages/stdf/src/lib/components/utils/index.ts
================================================
/**
 * 防抖
 * debounce
 * @example
 * const fn = () => console.log('hello world');
 * const debounceFn = debounce(fn, 1000);
 */
export const debounce = <T extends (...args: unknown[]) => unknown>(fn: T, delay = 10): ((...args: Parameters<T>) => void) => {
	let timer: ReturnType<typeof setTimeout> | null = null;
	return function (this: ThisParameterType<T>, ...args: Parameters<T>) {
		if (timer) {
			clearTimeout(timer);
		}
		timer = setTimeout(() => {
			fn.apply(this, args);
			timer = null;
		}, delay);
	};
};

/**
 * 节流
 * throttle
 * @example
 * const fn = () => console.log('hello world');
 * const throttleFn = throttle(fn, 1000);
 */
export const throttle = <T extends (...args: unknown[]) => unknown>(fn: T, delay = 50): ((...args: Parameters<T>) => void) => {
	let timer: ReturnType<typeof setTimeout> | null = null;
	return function (this: ThisParameterType<T>, ...args: Parameters<T>) {
		if (timer) {
			return;
		}
		timer = setTimeout(() => {
			fn.apply(this, args);
			timer = null;
		}, delay);
	};
};

/**
 * 节流
 * throttle With requestAnimationFrame
 * @example
 * const fn = () => console.log('hello world');
 * const throttleWithRAFFn = throttleWithRAF(fn, 1000);
 */
export const throttleWithRAF = <T extends (e: PointerEvent) => void>(fn: T, delay = 16): ((...args: Parameters<T>) => void) => {
	let timeoutId: ReturnType<typeof setTimeout> | undefined = undefined;
	let rafId: number | undefined = undefined;
	let lastExec = 0;
	const throttledFn = function (this: unknown, ...args: Parameters<T>) {
		const now = performance.now();
		const remainingTime = delay - (now - lastExec);
		if (rafId === undefined && timeoutId === undefined) {
			// 如果没有 rafId 和 timeoutId，说明没有正在进行的动画帧或定时器
			// If there is no rafId and timeoutId, it means there is no animation frame or timer in progress.
			rafId = requestAnimationFrame(() => {
				// 在动画帧开始时执行函数
				// Executes a function at the beginning of an animation frame
				fn.apply(this, args);
				lastExec = performance.now();
				rafId = undefined;
			});
		} else if (remainingTime <= 0) {
			// 如果超过了延迟时间，取消当前的定时器，然后在下一个动画帧执行
			// If the delay time is exceeded, cancel the current timer and execute it in the next animation frame.
			clearTimeout(timeoutId);
			timeoutId = undefined;
			rafId = requestAnimationFrame(() => {
				fn.apply(this, args);
				lastExec = performance.now();
				rafId = undefined;
			});
		} else {
			// 如果还有剩余时间，设置定时器
			// If there is time left, set the timer
			clearTimeout(timeoutId);
			timeoutId = setTimeout(() => {
				rafId = requestAnimationFrame(() => {
					fn.apply(this, args);
					lastExec = performance.now();
					rafId = undefined;
				});
			}, remainingTime);
		}
	};
	throttledFn.clear = () => {
		if (timeoutId !== null) {
			clearTimeout(timeoutId);
			timeoutId = undefined;
		}
		if (rafId !== undefined) {
			cancelAnimationFrame(rafId);
			rafId = undefined;
		}
	};
	return throttledFn;
};

/**
 * 将数字按照步长进行四舍五入
 *  Round the number according to the step length
 * @example
 * stepNumberFun(18, 5) // 20
 */
export const stepNumberFun: (num: number, step?: number) => number = (num, step = 1) => {
	//将 step 乘 10，转换为整数，避免小数计算精度问题
	// Multiply step by 10, convert to integer, avoid decimal calculation precision problem
	const stepNum = step * 10;
	return (Math.round((num * 10) / stepNum) * stepNum) / 10;
};

/**
 * 传入 Dom 和一段字符串，返回占页面的宽度
 * Pass in Dom and a string, return the width occupied by the page
 * @example
 * getDomWidth(document.body, 'hello world') // 100
 */
export const getDomWidth: (dom: HTMLElement, str: string) => number = (dom, str) => {
	const span: HTMLSpanElement = document.createElement('span');
	span.innerHTML = str;
	span.style.visibility = 'hidden';
	dom.appendChild(span);
	const width = span.getBoundingClientRect().width;
	dom.removeChild(span);
	return width;
};

/**
 * 根据年份和月份获取对应的天数
 * Get the number of days corresponding to the year and month according to the year and month
 * @example
 * getDayNum('2020', '02') // 29
 */
export const getDayNum: (year: string, month: string) => number = (year, month) => {
	if (month === '02') {
		return isLeapYear(Number(year)) ? 29 : 28;
	} else if (month === '04' || month === '06' || month === '09' || month === '11') {
		return 30;
	} else {
		return 31;
	}
};

/**
 * 是否是闰年
 * Is it a leap year
 * @example
 * isLeapYear(2020) // true
 */
export const isLeapYear: (year: number) => boolean = (year) => {
	return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
};

/**
 * 返回当前日期所处周的开始与结束日期组成的数组，日期格式为 YYYYMMDD
 * return an array of start and end date of current week, date format is YYYYMMDD
 * @example
 * getWeekRange() // ['20200518', '20200524']
 */
export const getWeekRange: () => string[] = () => {
	const now = new Date();
	const year = now.getFullYear();
	const month = now.getMonth();
	const day = now.getDate();
	const week = now.getDay();
	const start = new Date(year, month, day - week + 1);
	const end = new Date(year, month, day + (7 - week));
	return [start, end].map((date) => {
		const year = date.getFullYear();
		const month = date.getMonth() + 1;
		const day = date.getDate();
		return `${year}${month < 10 ? `0${month}` : month}${day < 10 ? `0${day}` : day}`;
	});
};

/**
 * 返回当前日期所处月的开始与结束日期组成的数组，日期格式为 YYYYMMDD
 * return an array of start and end date of current month, date format is YYYYMMDD
 * @returns {Array}
 * @example
 * getMonthRange() // ['20200501', '20200531']
 */
export const getMonthRange: () => string[] = () => {
	const now = new Date();
	const year = now.getFullYear();
	const month = now.getMonth();
	const start = new Date(year, month, 1);
	const end = new Date(year, month + 1, 0);
	return [start, end].map((date) => {
		const year = date.getFullYear();
		const month = date.getMonth() + 1;
		const day = date.getDate();
		return `${year}${month < 10 ? `0${month}` : month}${day < 10 ? `0${day}` : day}`;
	});
};

/**
 * 传入年月数据 YYYYMM，返回开始日是周几
 * Pass in year and month data YYYYMM, return the start day of the week
 * @example
 * getStartDay('202005') // 6
 */
export const getStartDay: (yearMonth: string) => number = (yearMonth) => {
	const year = yearMonth.slice(0, 4);
	const month = yearMonth.slice(4);
	return new Date(`${year}-${month}-01`).getDay();
};

/**
 * 传入正数或者负数 n，返回当前月往前或者往后的 n 个月的年月数据，格式为 YYYYMM，不足两位的月份前面补 0
 * Pass in a positive or negative number n, return the year and month data of the current month forward or backward n months, the format is YYYYMM, and the month less than two digits is filled with 0
 * @example
 * getYearMonth(1) // '202006'
 */
export const getNowBeforeOrAfterMonth: (n: number) => string = (n) => {
	const now = new Date();
	const year = now.getFullYear();
	const month = now.getMonth() + 1;
	const newMonth = month + n;
	if (newMonth > 12) {
		return `${year + 1}${newMonth - 12 < 10 ? `0${newMonth - 12}` : newMonth - 12}`;
	} else if (newMonth < 1) {
		return `${year - 1}${newMonth + 12 < 10 ? `0${newMonth + 12}` : newMonth + 12}`;
	} else {
		return `${year}${newMonth < 10 ? `0${newMonth}` : newMonth}`;
	}
};

/**
 * 传入年月数据 YYYYMM，根据当月 1 日的周几，返回当月的日历数据数组。如果 startSunday 为 true 从周日开始，否则从周一开始，1 日之前的数据为空字符串，之后的数据为空字符串并去除
 * Pass in year and month data YYYYMM, return the calendar data array according to the week of the first day of the month. If startSunday is true, start from Sunday, otherwise start from Monday. The data before 1 day is an empty string, and the data after 1 day is an empty string and is removed
 * @example
 * getCalendarData('202005') // ['','','','','','','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','']
 */
export const getCalendarData: (yearMonth: string, startSunday?: boolean) => string[] = (yearMonth, startSunday) => {
	const year = yearMonth.slice(0, 4);
	const month = yearMonth.slice(4);
	const startDay = getStartDay(yearMonth);
	const dayNum = getDayNum(year, month);
	const data: { day: string; [key: string]: unknown }[] = [];
	for (let i = 0; i < (startDay > 0 ? startDay - (startSunday ? 0 : 1) : 7 - (startSunday ? 0 : 1)); i++) {
		data.push({ day: '' });
	}
	for (let i = 1; i <= dayNum; i++) {
		data.push({ day: i.toString().padStart(2, '0') });
	}
	for (let i = 0; i < 42 - startDay - (startSunday ? 0 : 1) - dayNum; i++) {
		data.push({ day: '' });
	}
	// 去除结尾的所有空字符
	// Remove all empty characters at the end
	while (data[data.length - 1].day === '') {
		data.pop();
	}
	// 如果 day 是 00 或 0 的替换为空字
	// If day is 00, replace it with an empty character
	data.forEach((item: { day: string; [key: string]: unknown }) => {
		if (item.day === '00' || item.day === '0') {
			item.day = '';
		}
	});
	// 循环 data，如果 day 不为 ''，则计算出 day 是周几，放在 week
	// Loop data, if day is not '', then calculate that day is what day of the week, put it in week
	data.forEach((item: { day: string; [key: string]: unknown }) => {
		if (item.day !== '') {
			item.week = new Date(`${year}-${month}-${item.day}`).getDay();
		}
	});
	// 循环 data，如果当天是月末，endDay 为 true，否则为 false
	// Loop data, if today is the end of the month, endDay is true, otherwise it is false
	data.forEach((item: { day: string; [key: string]: unknown }, index: number) => {
		if (item.day !== '') {
			item.endDay = index === data.length - 1;
			item.startDay = item.day === '01';
		}
	});
	// 根据从周一开始还是周末开始，循环 data，如果 day 不为 ''，判断每天是 周第一天 还是 周最后一天，分别放在 weekStartDay 和 weekEndDay
	// According to whether it starts from Monday or Sunday, loop data, if day is not '', judge whether each day is the first day of the week or the last day of the week, and put it in weekStartDay and weekEndDay respectively
	if (!startSunday) {
		data.forEach((item: { day: string; [key: string]: unknown }) => {
			if (item.day !== '') {
				item.weekStartDay = item.week === 1;
				item.weekEndDay = item.week === 0;
			}
		});
	} else {
		data.forEach((item: { day: string; [key: string]: unknown }) => {
			if (item.day !== '') {
				item.weekStartDay = item.week === 0;
				item.weekEndDay = item.week === 6;
			}
		});
	}
	// 根据每一天的 startDay 和 weekStartDay，endDay 和 weekEndDay，只要有一项是 true，就是月第一天或周第一天，放在 start 和 end 中
	// According to the startDay and weekStartDay of each day, endDay and weekEndDay, as long as one item is true, it is the first day of the month or the first day of the week, put it in start and end
	data.forEach((item: { day: string; [key: string]: unknown }) => {
		if (item.day !== '') {
			item.start = item.startDay || item.weekStartDay;
			item.end = item.endDay || item.weekEndDay;
		}
	});
	return data.map((item: { day: string; [key: string]: unknown }) => item.day);
};

/**
 * 传入格式为 YYYYMM 的开始与结束月份字符串，返回这两月份之间的所有月份数据数组，格式为 YYYYMM，不足两位的月份前面补 0
 * Pass in the start and end month strings in the format of YYYYMM, return the data array of all months between these two months, the format is YYYYMM, and the month less than two digits is filled with 0
 * @example
 * getMonthListRange('202005', '202007') // ['202005', '202006', '202007']
 */
export const getMonthListRange: (startMonthStr: string, endMonthStr: string) => string[] = (startMonthStr, endMonthStr) => {
	const startYear = startMonthStr.slice(0, 4);
	const startMonth = startMonthStr.slice(4);
	const endYear = endMonthStr.slice(0, 4);
	const endMonth = endMonthStr.slice(4);
	const data = [];
	if (startYear === endYear) {
		for (let i = Number(startMonth); i <= Number(endMonth); i++) {
			data.push(`${startYear}${i < 10 ? `0${i}` : i}`);
		}
	} else {
		for (let i = Number(startMonth); i <= 12; i++) {
			data.push(`${startYear}${i < 10 ? `0${i}` : i}`);
		}
		for (let i = 1; i <= Number(endMonth); i++) {
			data.push(`${endYear}${i < 10 ? `0${i}` : i}`);
		}
	}
	return data;
};

/**
 * 传入开始与结束日期 YYYYMMDD，需要剔除的日期组成的数组 disabledDates。返回中间的所有日期数组，包含开始与结束日期，月与日不足两位的前面补 0，格式为 YYYYMMDD
 * Pass in the start and end date YYYYMMDD, the array of disabled dates to be removed. Return the array of all dates in the middle, including the start and end dates, and the month and day less than two digits are filled with 0, in the format of YYYYMMDD
 * @example
 * getDateRange('20200501', '20200503') // ['20200501', '20200502', '20200503']
 */
export const getDateRange: (startDate: string, endDate: string, disabledDates: string[]) => string[] = (
	startDate,
	endDate,
	disabledDates
) => {
	// 将 startDate 与 endDate 转化为 YYYY-MM-DD 格式
	// Convert startDate and endDate to YYYY-MM-DD format
	const startYear = startDate.slice(0, 4);
	const startMonth = startDate.slice(4, 6);
	const startDay = startDate.slice(6);
	const endYear = endDate.slice(0, 4);
	const endMonth = endDate.slice(4, 6);
	const endDay = endDate.slice(6);
	const startTimeStr = new Date(`${startYear}-${startMonth}-${startDay}`).getTime();
	const endTimeStr = new Date(`${endYear}-${endMonth}-${endDay}`).getTime();
	const startTime = new Date(startTimeStr).getTime();
	const endTime = new Date(endTimeStr).getTime();
	const data: string[] = [];
	for (let i = startTime; i <= endTime; i += 24 * 60 * 60 * 1000) {
		const date = new Date(i);
		const year = date.getFullYear();
		const month = date.getMonth() + 1;
		const day = date.getDate();
		data.push(`${year}${month < 10 ? `0${month}` : month}${day < 10 ? `0${day}` : day}`);
	}
	// 剔除 disabledDates 中的日期
	// Remove dates in disabledDates
	if (disabledDates && disabledDates.length) {
		disabledDates.forEach((item) => {
			const index = data.indexOf(item);
			if (index > -1) {
				data.splice(index, 1);
			}
		});
	}

	return data;
};

/**
 * 传入 startSunday，返回当天所处周的所有日期数组，日期格式为 YYYYMMDD，月与日不足两位的前面补 0
 * Pass in startSunday, return the array of all dates in the week of the current day, the date format is YYYYMMDD, and the month and day less than two digits are filled with 0
 * @example
 * getWeekRange(true) // ['20200531', '20200601', '20200602', '20200603', '20200604', '20200605', '20200606']
 */
export const getCurrentWeek: (startSunday: boolean) => string[] = (startSunday) => {
	const now = new Date();
	const year = now.getFullYear();
	const month = now.getMonth() + 1;
	const date = now.getDate();
	const day = now.getDay();
	const weekDates: string[] = [];
	if (startSunday) {
		for (let i = 0; i < 7; i++) {
			const newDate = new Date(year, month - 1, date - day + i);
			const newYear = newDate.getFullYear();
			const newMonth = newDate.getMonth() + 1;
			const newDateNum = newDate.getDate();

			weekDates.push(`${newYear}${newMonth.toString().padStart(2, '0')}${newDateNum.toString().padStart(2, '0')}`);
		}
	} else {
		for (let i = 1; i < 8; i++) {
			const newDate = new Date(year, month - 1, date - day + i);
			const newYear = newDate.getFullYear();
			const newMonth = newDate.getMonth() + 1;
			const newDateNum = newDate.getDate();

			weekDates.push(`${newYear}${newMonth.toString().padStart(2, '0')}${newDateNum.toString().padStart(2, '0')}`);
		}
	}
	return weekDates;
};

/**
 * 返回当天所处月份的所有日期数组，日期格式为 YYYYMMDD，月与日不足两位的前面补 0
 * Return the array of all dates in the month of the current day, the date format is YYYYMMDD, and the month and day less than two digits are filled with 0
 * @example
 * getCurrentMonth() // ['20200501', '20200502', '20200503', ...]
 */
export const getCurrentMonth: () => string[] = () => {
	const now = new Date();
	const year = now.getFullYear();
	const month = now.getMonth() + 1;
	const days = new Date(year, month, 0).getDate();
	const dates: string[] = [];
	for (let i = 1; i <= days; i++) {
		dates.push(`${year}${month.toString().padStart(2, '0')}${i.toString().padStart(2, '0')}`);
	}
	return dates;
};

/**
 * 返回当天所处季度的所有日期数组，日期格式为 YYYYMMDD，月与日不足两位的前面补 0
 * Pass in the date, return the array of all dates in the quarter of the current day, the date format is YYYYMMDD, and the month and day less than two digits are filled with 0
 * @example
 * getCurrentQuarter() // ['20200401', '20200402', '20200403', ...]
 */
export const getCurrentQuarter: () => string[] = () => {
	const now = new Date();
	const year = now.getFullYear();
	const month = now.getMonth() + 1;
	const quarter = Math.floor((month - 1) / 3) + 1;
	const startMonth = (quarter - 1) * 3 + 1;
	const endMonth = quarter * 3;
	const days: string[] = [];
	for (let i = startMonth; i <= endMonth; i++) {
		const daysInMonth = new Date(year, i, 0).getDate();
		for (let j = 1; j <= daysInMonth; j++) {
			days.push(`${year}${i.toString().padStart(2, '0')}${j.toString().padStart(2, '0')}`);
		}
	}
	return days;
};

/**
 * 传入正数或负数天数 n 和是否从今天开始计算 today，返回对应的前后日期组成的数组，日期格式为 YYYYMMDD，月与日不足两位的前面补 0
 * Pass in a positive or negative number of days n, whether to include today hasToday, return the array of dates before and after the current day, the date format is YYYYMMDD, and the month and day less than two digits are filled with 0
 * @example
 * getDaysRangeWithToday(3) // ['20200501', '20200502', '20200503']
 */
export const getDaysRangeWithToday: (n: number, today: boolean) => string[] = (n = 0, today = true) => {
	const now = new Date();
	let fakeToday = now;
	if (today) {
		fakeToday = new Date(now.getFullYear(), now.getMonth(), now.getDate());
	} else {
		if (n < 0) {
			fakeToday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
		} else if (n > 0) {
			fakeToday = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);
		} else {
			fakeToday = now;
		}
	}
	const dates: string[] = [];
	for (let i = 0; i < Math.abs(n); i++) {
		const date = new Date(fakeToday.getTime() + (n > 0 ? i : -i) * 24 * 60 * 60 * 1000);
		dates.push(`${date.getFullYear()}${(date.getMonth() + 1).toString().padStart(2, '0')}${date.getDate().toString().padStart(2, '0')}`);
	}
	// 对日期排序
	// Sort dates
	dates.sort((a, b) => Number(a) - Number(b));
	return dates;
};



================================================
FILE: packages/stdf/src/lib/lang/ar_EG.ts
================================================
import type { LangProps } from './index.js';

const ar_EG: LangProps = {
	common: {
		slotEmpty: 'محتويات الفتحة فارغة!',
		loading: 'جار التحميل ...',
		noData: 'لا يوجد بيانات',
		noMoreData: 'لا توجد بيانات إضافية',
		done: 'تم'
	},
	actionSheet: {
		cancelText: 'إلغاء'
	},
	bottomSheet: {
		title: 'العنوان'
	},
	dialog: {
		title: 'تلميح',
		content: 'المحتوى',
		primaryText: 'تأكيد',
		secondaryText: 'إلغاء'
	},
	input: {
		pleaseInput: 'الرجاء إدخال'
	},
	modal: {
		title: 'العنوان',
		content: 'المحتوى',
		btnText: 'أراهن'
	},
	navBar: {
		title: 'العنوان'
	},
	pagination: {
		defaultOnlyOnePage: 'فقط صفحة واحدة'
	},
	picker: {
		defaultTitle: 'الرجاء الاختيار',
		defaultCancel: 'إلغاء',
		defaultConfirm: 'تأكيد'
	},
	asyncPicker: {
		defaultTitle: 'الرجاء الاختيار',
		defaultCancel: 'إلغاء',
		defaultConfirm: 'تأكيد',
		defaultNext: 'التالي',
		defaultPrev: 'السابق',
		defaultSelected: 'المختار'
	},
	rate: {
		error1: 'لا يمكن أن يكون القيمة أكبر من الإجمالي!',
		error2: 'يجب أن يتم إزالة الإجمالي بمقدار 1!',
		error3: 'يجب أن تكون القيمة أقل بمقدار 1 عندما لا تكون مختارة نصفياً!',
		error4: 'يجب أن يتم إزالة القيمة بمقدار 0.5 عند الاختيار بشكل نصفي!',
		error5: 'العرض أو الارتفاع أقل من 20، والذي يجعل النقر على التليفون المحمول صعبًا!'
	},
	timePicker: {
		defaultTitle: 'الرجاء الاختيار',
		defaultCancel: 'إلغاء',
		defaultConfirm: 'تأكيد',
		defaultYear: 'سنة',
		defaultMonth: 'شهر',
		defaultDay: 'يوم',
		defaultHour: 'ساعة',
		defaultMinute: 'دقيقة',
		defaultSecond: 'ثانية'
	},
	calendar: {
		weekTextList: ['الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت', 'الأحد'],
		weekSundayStartTextList: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
		monthTextList: ['يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو', 'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر'],
		confirmText: 'تأكيد',
		selectedText: 'المحددة',
		dayText: 'يوم',
		beforeText: 'الأخيرة',
		afterText: 'المستقبل',
		currentWeekText: 'هذا الأسبوع',
		currentMonthText: 'هذا الشهر',
		currentQuarterText: 'هذه الفصل'
	}
};

export default ar_EG;



================================================
FILE: packages/stdf/src/lib/lang/az_AZ.ts
================================================
import type { LangProps } from './index.js';

const az_AZ: LangProps = {
	common: {
		slotEmpty: 'Slotun məzmunu boşdur!',
		loading: 'Yüklənir...',
		noData: 'Məlumat yoxdur',
		noMoreData: 'Artıq məlumat yoxdur',
		done: 'Hazır'
	},
	actionSheet: {
		cancelText: 'Ləğv et'
	},
	bottomSheet: {
		title: 'Başlıq'
	},
	dialog: {
		title: 'Xəbərdarlıq',
		content: 'Məzmun',
		primaryText: 'Təsdiq',
		secondaryText: 'Ləğv et'
	},
	input: {
		pleaseInput: 'Daxil edin'
	},
	modal: {
		title: 'Başlıq',
		content: 'Məzmun',
		btnText: 'Gördüm'
	},
	navBar: {
		title: 'Başlıq'
	},
	pagination: {
		defaultOnlyOnePage: 'Yalnız bir səhifə'
	},
	picker: {
		defaultTitle: 'Seçin',
		defaultCancel: 'Ləğv et',
		defaultConfirm: 'Təsdiq et'
	},
	asyncPicker: {
		defaultTitle: 'Seçin',
		defaultCancel: 'Ləğv et',
		defaultConfirm: 'Təsdiq et',
		defaultNext: 'Növbəti',
		defaultPrev: 'Əvvəlki',
		defaultSelected: 'Seçildi'
	},
	rate: {
		error1: 'Dəyər Ümumi dəyərdən böyük ola bilməz!',
		error2: 'Ümumi 1 çıxılmalıdır!',
		error3: 'Yarım seçildiyi zaman dəyər 1 çıxılmalıdır!',
		error4: 'Yarım seçilmədiyində Dəyər 0.5 azalır !',
		error5: 'Genişlik və ya hündürlük 20 -dən kiçikdir, mobil terminalda klik etmək çətindir!'
	},
	timePicker: {
		defaultTitle: 'Seçin',
		defaultCancel: 'Ləğv et',
		defaultConfirm: 'Təsdiq et',
		defaultYear: 'İl',
		defaultMonth: 'Ay',
		defaultDay: 'Gün',
		defaultHour: 'Saat',
		defaultMinute: 'Dəqiqə',
		defaultSecond: 'Saniyə'
	},
	calendar: {
		weekTextList: ['B.', 'Ç.', 'Ç.a.', 'Ç.', 'C.', 'C.a.', 'Ş.'],
		weekSundayStartTextList: ['Ş.', 'B.', 'Ç.', 'Ç.a.', 'Ç.', 'C.', 'C.a.'],
		monthTextList: ['Yanvar', 'Fevral', 'Mart', 'Aprel', 'May', 'İyun', 'İyul', 'Avqust', 'Sentyabr', 'Oktyabr', 'Noyabr', 'Dekabr'],
		confirmText: 'Təsdiq et',
		selectedText: 'Seçilib',
		dayText: 'gün',
		beforeText: 'Son',
		afterText: 'Gələcək',
		currentWeekText: 'Bu həftə',
		currentMonthText: 'Bu ay',
		currentQuarterText: 'Bu rəbə'
	}
};

export default az_AZ;



================================================
FILE: packages/stdf/src/lib/lang/bg_BG.ts
================================================
import type { LangProps } from './index.js';

const bg_BG: LangProps = {
	common: {
		slotEmpty: 'Съдържанието на слота е празно!',
		loading: 'Зареждане...',
		noData: 'Няма данни',
		noMoreData: 'Няма повече данни',
		done: 'Готово'
	},
	actionSheet: {
		cancelText: 'Отказ'
	},
	bottomSheet: {
		title: 'Заглавие'
	},
	dialog: {
		title: 'Подсказка',
		content: 'Съдържание',
		primaryText: 'Потвърди',
		secondaryText: 'Откажи'
	},
	input: {
		pleaseInput: 'Моля, въведете'
	},
	modal: {
		title: 'Заглавие',
		content: 'Съдържание',
		btnText: 'Разбрах'
	},
	navBar: {
		title: 'Заглавие'
	},
	pagination: {
		defaultOnlyOnePage: 'Само една'
	},
	picker: {
		defaultTitle: 'Моля, изберете',
		defaultCancel: 'Отказ',
		defaultConfirm: 'Потвърди'
	},
	asyncPicker: {
		defaultTitle: 'Моля, изберете',
		defaultCancel: 'Отказ',
		defaultConfirm: 'Потвърди',
		defaultNext: 'Следващ',
		defaultPrev: 'Предишен',
		defaultSelected: 'Избрано'
	},
	rate: {
		error1: 'Стойността не може да бъде по-голяма от общата!',
		error2: 'Общата трябва да се раздели с 1!',
		error3: 'Стойността трябва да се раздели с 1, когато не е наполовина избрана!',
		error4: 'Стойността трябва да се раздели с 0,5, когато е наполовина избрана!',
		error5: 'Широчината или височината има стойност по-малка от 20, което прави щракването на мобилното устройство трудно!'
	},
	timePicker: {
		defaultTitle: 'Моля, изберете',
		defaultCancel: 'Отказ',
		defaultConfirm: 'Потвърди',
		defaultYear: 'Година',
		defaultMonth: 'Месец',
		defaultDay: 'Ден',
		defaultHour: 'Час',
		defaultMinute: 'Минута',
		defaultSecond: 'Секунда'
	},
	calendar: {
		weekTextList: ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Нд'],
		weekSundayStartTextList: ['Нд', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],
		monthTextList: ['Януари', 'Февруари', 'Март', 'Април', 'Май', 'Юни', 'Юли', 'Август', 'Септември', 'Октомври', 'Ноември', 'Декември'],
		confirmText: 'Потвърди',
		selectedText: 'Избрано',
		dayText: 'ден',
		beforeText: 'Последен',
		afterText: 'Следващ',
		currentWeekText: 'Тази седмица',
		currentMonthText: 'Този месец',
		currentQuarterText: 'Това тримесечие'
	}
};

export default bg_BG;



================================================
FILE: packages/stdf/src/lib/lang/bn_BD.ts
================================================
import type { LangProps } from './index.js';

const bn_BD: LangProps = {
	common: {
		slotEmpty: 'স্লটের উপাদান খালি!',
		loading: 'লোড হচ্ছে ...',
		noData: 'কোন তথ্য নেই',
		noMoreData: 'আর কোন তথ্য নেই',
		done: 'সম্পন্ন'
	},
	actionSheet: {
		cancelText: 'বাতিল'
	},
	bottomSheet: {
		title: 'শিরোনাম'
	},
	dialog: {
		title: 'উপদেশ',
		content: 'বিষয়বস্তু',
		primaryText: 'হ্যাঁ',
		secondaryText: 'না'
	},
	input: {
		pleaseInput: 'অনুগ্রহপূর্বক প্রবেশ করুন'
	},
	modal: {
		title: 'শিরোনাম',
		content: 'বিষয়বস্তু',
		btnText: 'ঠিক আছে'
	},
	navBar: {
		title: 'শিরোনাম'
	},
	pagination: {
		defaultOnlyOnePage: 'শুধুমাত্র একটি'
	},
	picker: {
		defaultTitle: 'অনুগ্রহ করে নির্বাচন করুন',
		defaultCancel: 'বাতিল',
		defaultConfirm: 'নিশ্চিত করুন'
	},
	asyncPicker: {
		defaultTitle: 'অনুগ্রহ করে নির্বাচন করুন',
		defaultCancel: 'বাতিল',
		defaultConfirm: 'নিশ্চিত করুন',
		defaultNext: 'পরবর্তী',
		defaultPrev: 'আগে',
		defaultSelected: 'নির্বাচিত'
	},
	rate: {
		error1: 'মানটি সম্পূর্ণ প্রতিবেদন থেকে বেশি হতে পারে না!',
		error2: 'সম্পূর্ণ প্রতিবেদনের সাথে গুণফল করতে হবে!',
		error3: 'মানটি বেশি নয়, তখন সাম্প্রতিক নয়!',
		error4: 'মানটি আধ হওয়া উচিত, তখন সে সাম্প্রতিক হিসাবে উন্নয়ন করা হবে!',
		error5: 'উচ্চতা বা প্রস্থ এমন মান যা মোবাইল ডিভাইসে ক্লিক করা অসহজ করে দেয়!'
	},
	timePicker: {
		defaultTitle: 'অনুগ্রহ করে নির্বাচন করুন',
		defaultCancel: 'বাতিল',
		defaultConfirm: 'নিশ্চিত করুন',
		defaultYear: 'বছর',
		defaultMonth: 'মাস',
		defaultDay: 'দিন',
		defaultHour: 'ঘন্টা',
		defaultMinute: 'মিনিট',
		defaultSecond: 'সেকেন্ড'
	},
	calendar: {
		weekTextList: ['সোম', 'মঙ্গল', 'বুধ', 'বৃহস্পতি', 'শুক্র', 'শনি', 'রবি'],
		weekSundayStartTextList: ['রবি', 'সোম', 'মঙ্গল', 'বুধ', 'বৃহস্পতি', 'শুক্র', 'শনি'],
		monthTextList: [
			'জানুয়ারী',
			'ফেব্রুয়ারী',
			'মার্চ',
			'এপ্রিল',
			'মে',
			'জুন',
			'জুলাই',
			'আগস্ট',
			'সেপ্টেম্বর',
			'অক্টোবর',
			'নভেম্বর',
			'ডিসেম্বর'
		],
		confirmText: 'নিশ্চিত করুন',
		selectedText: 'নির্বাচিত',
		dayText: 'দিন',
		beforeText: 'পূর্ববর্তী',
		afterText: 'পরবর্তী',
		currentWeekText: 'এই সপ্তাহে',
		currentMonthText: 'এই মাসে',
		currentQuarterText: 'এই ত্রৈমাসিকে'
	}
};

export default bn_BD;



================================================
FILE: packages/stdf/src/lib/lang/ca_ES.ts
================================================
import type { LangProps } from './index.js';

const ca_ES: LangProps = {
	common: {
		slotEmpty: 'La ranura està buida!',
		loading: "S'està carregant ...",
		noData: 'No hi ha dades disponibles',
		noMoreData: 'No hi ha més dades',
		done: 'Fet'
	},
	actionSheet: {
		cancelText: 'Cancel·lar'
	},
	bottomSheet: {
		title: 'Títol'
	},
	dialog: {
		title: 'Avís',
		content: 'Contingut',
		primaryText: "D'acord",
		secondaryText: 'Cancel·lar'
	},
	input: {
		pleaseInput: 'Si us plau, introdueixi'
	},
	modal: {
		title: 'Títol',
		content: 'Contingut',
		btnText: "D'acord"
	},
	navBar: {
		title: 'Títol'
	},
	pagination: {
		defaultOnlyOnePage: 'Només una pàgina'
	},
	picker: {
		defaultTitle: 'Si us plau, trieu',
		defaultCancel: 'Cancel·lar',
		defaultConfirm: 'Confirmar'
	},
	asyncPicker: {
		defaultTitle: 'Si us plau, trieu',
		defaultCancel: 'Cancel·lar',
		defaultConfirm: 'Confirmar',
		defaultNext: 'Següent',
		defaultPrev: 'Anterior',
		defaultSelected: 'Seleccionat'
	},
	rate: {
		error1: 'El valor no pot ser més gran que la seva informació de retroaliment completa!',
		error2: "El valor s'ha de puntuar amb la seva informació de retroaliment completa!",
		error3: 'El valor no és gran, llavors no és fresc!',
		error4: 'El valor ha de ser imparell, llavors es desenvolupa com a fresc!',
		error5: "L'alçada o l'amplada del valor és difícil de tocar al dispositiu mòbil!"
	},
	timePicker: {
		defaultTitle: 'Si us plau, trieu',
		defaultCancel: 'Cancel·lar',
		defaultConfirm: 'Confirmar',
		defaultYear: 'Any',
		defaultMonth: 'Mes',
		defaultDay: 'Dia',
		defaultHour: 'Hora',
		defaultMinute: 'Minut',
		defaultSecond: 'Segon'
	},
	calendar: {
		weekTextList: ['Dl', 'Dt', 'Dc', 'Dj', 'Dv', 'Ds', 'Dg'],
		weekSundayStartTextList: ['Dg', 'Dl', 'Dt', 'Dc', 'Dj', 'Dv', 'Ds'],
		monthTextList: ['Gener', 'Febrer', 'Març', 'Abril', 'Maig', 'Juny', 'Juliol', 'Agost', 'Setembre', 'Octubre', 'Novembre', 'Desembre'],
		confirmText: 'Confirmar',
		selectedText: 'Seleccionat',
		dayText: 'Dia',
		beforeText: 'Abans',
		afterText: 'Després',
		currentWeekText: 'Aquesta setmana',
		currentMonthText: 'Aquest mes',
		currentQuarterText: 'Aquest trimestre'
	}
};

export default ca_ES;



================================================
FILE: packages/stdf/src/lib/lang/cs_CZ.ts
================================================
import type { LangProps } from './index.js';

const cs_CZ: LangProps = {
	common: {
		slotEmpty: 'Slot je prázdný!',
		loading: 'Načítání...',
		noData: 'Žádná data',
		noMoreData: 'Žádná další data',
		done: 'Hotovo'
	},
	actionSheet: {
		cancelText: 'Zrušit'
	},
	bottomSheet: {
		title: 'Název'
	},
	dialog: {
		title: 'Upozornění',
		content: 'Obsah',
		primaryText: 'OK',
		secondaryText: 'Zrušit'
	},
	input: {
		pleaseInput: 'Prosím, zadejte'
	},
	modal: {
		title: 'Název',
		content: 'Obsah',
		btnText: 'OK'
	},
	navBar: {
		title: 'Název'
	},
	pagination: {
		defaultOnlyOnePage: 'Jen jedna stránka'
	},
	picker: {
		defaultTitle: 'Prosím vyberte',
		defaultCancel: 'Zrušit',
		defaultConfirm: 'Potvrdit'
	},
	asyncPicker: {
		defaultTitle: 'Prosím vyberte',
		defaultCancel: 'Zrušit',
		defaultConfirm: 'Potvrdit',
		defaultNext: 'Další',
		defaultPrev: 'Předchozí',
		defaultSelected: 'Vybráno'
	},
	rate: {
		error1: 'Hodnocení nemůže být větší než celková zpětná vazba!',
		error2: 'Hodnocení musí být vyplněno alespoň celou jednou!',
		error3: 'Hodnocení není velké, pak že ježek spí!',
		error4: 'Hodnocení musí být liché, pak se vyvíjí jako ježek!',
		error5: 'Výška nebo šířka hodnocení je na mobilním zařízení obtížně dotykatelná!'
	},
	timePicker: {
		defaultTitle: 'Prosím vyberte',
		defaultCancel: 'Zrušit',
		defaultConfirm: 'Potvrdit',
		defaultYear: 'Rok',
		defaultMonth: 'Měsíc',
		defaultDay: 'Den',
		defaultHour: 'Hodina',
		defaultMinute: 'Minuta',
		defaultSecond: 'Sekunda'
	},
	calendar: {
		weekTextList: ['Po', 'Út', 'St', 'Čt', 'Pá', 'So', 'Ne'],
		weekSundayStartTextList: ['Ne', 'Po', 'Út', 'St', 'Čt', 'Pá', 'So'],
		monthTextList: ['Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec', 'Srpen', 'Září', 'Říjen', 'Listopad', 'Prosinec'],
		confirmText: 'Potvrdit',
		selectedText: 'Vybraná',
		dayText: '. den',
		beforeText: 'Před',
		afterText: 'Po',
		currentWeekText: 'Tento týden',
		currentMonthText: 'Tento měsíc',
		currentQuarterText: 'Toto čtvrtletí'
	}
};

export default cs_CZ;



================================================
FILE: packages/stdf/src/lib/lang/da_DK.ts
================================================
import type { LangProps } from './index.js';

const da_DK: LangProps = {
	common: {
		slotEmpty: 'Slot er tom!',
		loading: 'Indlæser...',
		noData: 'Ingen data',
		noMoreData: 'Ingen flere data',
		done: 'Færdig'
	},
	actionSheet: {
		cancelText: 'Annuller'
	},
	bottomSheet: {
		title: 'Titel'
	},
	dialog: {
		title: 'Advarsel',
		content: 'Indhold',
		primaryText: 'OK',
		secondaryText: 'Annuller'
	},
	input: {
		pleaseInput: 'Indtast venligst'
	},
	modal: {
		title: 'Titel',
		content: 'Indhold',
		btnText: 'OK'
	},
	navBar: {
		title: 'Titel'
	},
	pagination: {
		defaultOnlyOnePage: 'Kun en side'
	},
	picker: {
		defaultTitle: 'Vælg venligst',
		defaultCancel: 'Annuller',
		defaultConfirm: 'Bekræft'
	},
	asyncPicker: {
		defaultTitle: 'Vælg venligst',
		defaultCancel: 'Annuller',
		defaultConfirm: 'Bekræft',
		defaultNext: 'Næste',
		defaultPrev: 'Tidligere',
		defaultSelected: 'Valgt'
	},
	rate: {
		error1: 'Bedømmelsen må ikke være større end din samlede feedback!',
		error2: 'Bedømmelse skal være udarbejdet mindst en hel!',
		error3: 'Bedømmelse er ikke stor, så pindsvinet sover!',
		error4: 'Bedømmelse skal være ulige, så udvikler sig som en pindsvin!',
		error5: 'Højden eller bredden af bedømmelsen er svær at røre mobil!'
	},
	timePicker: {
		defaultTitle: 'Vælg venligst',
		defaultCancel: 'Annuller',
		defaultConfirm: 'Bekræft',
		defaultYear: 'År',
		defaultMonth: 'Måned',
		defaultDay: 'Dag',
		defaultHour: 'Time',
		defaultMinute: 'Minut',
		defaultSecond: 'Anden'
	},
	calendar: {
		weekTextList: ['Ma', 'Ti', 'On', 'To', 'Fr', 'Lø', 'Sø'],
		weekSundayStartTextList: ['Sø', 'Ma', 'Ti', 'On', 'To', 'Fr', 'Lø'],
		monthTextList: ['Januar', 'Februar', 'Marts', 'April', 'Maj', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'December'],
		confirmText: 'Bekræft',
		selectedText: 'Valgt',
		dayText: '. dag',
		beforeText: 'Før',
		afterText: 'Efter',
		currentWeekText: 'Denne uge',
		currentMonthText: 'Denne måned',
		currentQuarterText: 'Dette kvartal'
	}
};

export default da_DK;



================================================
FILE: packages/stdf/src/lib/lang/de_DE.ts
================================================
import type { LangProps } from './index.js';

const de_DE: LangProps = {
	common: {
		slotEmpty: 'Slot ist leer!',
		loading: 'Laden...',
		noData: 'Keine Daten',
		noMoreData: 'Keine weiteren Daten',
		done: 'Fertig'
	},
	actionSheet: {
		cancelText: 'Abbrechen'
	},
	bottomSheet: {
		title: 'Titel'
	},
	dialog: {
		title: 'Warnung',
		content: 'Inhalt',
		primaryText: 'OK',
		secondaryText: 'Abbrechen'
	},
	input: {
		pleaseInput: 'Bitte geben Sie ein'
	},
	modal: {
		title: 'Titel',
		content: 'Inhalt',
		btnText: 'OK'
	},
	navBar: {
		title: 'Titel'
	},
	pagination: {
		defaultOnlyOnePage: 'Nur eine'
	},
	picker: {
		defaultTitle: 'Bitte wählen',
		defaultCancel: 'Abbrechen',
		defaultConfirm: 'Bestätigen'
	},
	asyncPicker: {
		defaultTitle: 'Bitte wählen',
		defaultCancel: 'Abbrechen',
		defaultConfirm: 'Bestätigen',
		defaultNext: 'Weiter',
		defaultPrev: 'Zurück',
		defaultSelected: 'Ausgewählt'
	},
	rate: {
		error1: 'Bewertung darf nicht größer als Ihr Gesamt-Feedback sein!',
		error2: 'Bewertung muss mindestens einmal vollständig ausgefüllt werden!',
		error3: 'Bewertung ist nicht groß, so schläft der Igel!',
		error4: 'Bewertung muss ungerade sein, damit sie sich wie ein Igel entwickelt!',
		error5: 'Die Höhe oder Breite der Bewertung ist auf dem Mobiltelefon schwer zu berühren!'
	},
	timePicker: {
		defaultTitle: 'Bitte wählen',
		defaultCancel: 'Abbrechen',
		defaultConfirm: 'Bestätigen',
		defaultYear: 'Jahr',
		defaultMonth: 'Monat',
		defaultDay: 'Tag',
		defaultHour: 'Stunde',
		defaultMinute: 'Minute',
		defaultSecond: 'Zweite'
	},
	calendar: {
		weekTextList: ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'],
		weekSundayStartTextList: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
		monthTextList: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
		confirmText: 'Bestätigen',
		selectedText: 'Ausgewählt',
		dayText: '. Tag',
		beforeText: 'Vor',
		afterText: 'Nach',
		currentWeekText: 'Diese Woche',
		currentMonthText: 'Dieser Monat',
		currentQuarterText: 'Dieses Quartal'
	}
};

export default de_DE;



================================================
FILE: packages/stdf/src/lib/lang/el_GR.ts
================================================
import type { LangProps } from './index.js';

const el_GR: LangProps = {
	common: {
		slotEmpty: 'Το slot είναι άδειο!',
		loading: 'Φόρτωση...',
		noData: 'Δεν υπάρχουν δεδομένα',
		noMoreData: 'Δεν υπάρχουν άλλα δεδομένα',
		done: 'Έγινε'
	},
	actionSheet: {
		cancelText: 'Ακύρωση'
	},
	bottomSheet: {
		title: 'Τίτλος'
	},
	dialog: {
		title: 'Προειδοποίηση',
		content: 'Περιεχόμενο',
		primaryText: 'ΟΚ',
		secondaryText: 'Ακύρωση'
	},
	input: {
		pleaseInput: 'Παρακαλώ εισάγετε'
	},
	modal: {
		title: 'Τίτλος',
		content: 'Περιεχόμενο',
		btnText: 'ΟΚ'
	},
	navBar: {
		title: 'Τίτλος'
	},
	pagination: {
		defaultOnlyOnePage: 'Μόνο μία'
	},
	picker: {
		defaultTitle: 'Παρακαλώ επιλέξτε',
		defaultCancel: 'Ακύρωση',
		defaultConfirm: 'Επιβεβαίωση'
	},
	asyncPicker: {
		defaultTitle: 'Παρακαλώ επιλέξτε',
		defaultCancel: 'Ακύρωση',
		defaultConfirm: 'Επιβεβαίωση',
		defaultNext: 'Επόμενο',
		defaultPrev: 'Προηγούμενο',
		defaultSelected: 'Επιλεγμένο'
	},
	rate: {
		error1: 'Η βαθμολογία δεν πρέπει να είναι μεγαλύτερη από τη συνολική ανατροφοδότησή σας!',
		error2: 'Η βαθμολογία πρέπει να συμπληρώνεται στο σύνολό της τουλάχιστον μία φορά!',
		error3: 'Η βαθμολογία δεν είναι μεγάλη, οπότε το σκαντζόχοιρο κοιμάται!',
		error4: 'Η βαθμολογία πρέπει να είναι μονός αριθμός, ώστε να αναπτύσσεται όπως ένα σκαντζόχοιρος!',
		error5: 'Το ύψος ή η πλάτος της βαθμολογίας είναι δύσκολο να αγγίξει στο κινητό!'
	},
	timePicker: {
		defaultTitle: 'Παρακαλώ επιλέξτε',
		defaultCancel: 'Ακύρωση',
		defaultConfirm: 'Επιβεβαίωση',
		defaultYear: 'Έτος',
		defaultMonth: 'Μήνας',
		defaultDay: 'Ημέρα',
		defaultHour: 'Ώρα',
		defaultMinute: 'Λεπτό',
		defaultSecond: 'Δευτερόλεπτο'
	},
	calendar: {
		weekTextList: ['Δε', 'Τρ', 'Τε', 'Πε', 'Πα', 'Σα', 'Κυ'],
		weekSundayStartTextList: ['Κυ', 'Δε', 'Τρ', 'Τε', 'Πε', 'Πα', 'Σα'],
		monthTextList: [
			'Ιανουάριος',
			'Φεβρουάριος',
			'Μάρτιος',
			'Απρίλιος',
			'Μάιος',
			'Ιούνιος',
			'Ιούλιος',
			'Αύγουστος',
			'Σεπτέμβριος',
			'Οκτώβριος',
			'Νοέμβριος',
			'Δεκέμβριος'
		],
		confirmText: 'Επιβεβαίωση',
		selectedText: 'Επιλεγμένο',
		dayText: 'η μέρα',
		beforeText: 'Πριν από',
		afterText: 'Μετά',
		currentWeekText: 'Αυτήν την εβδομάδα',
		currentMonthText: 'Αυτό το μήνα',
		currentQuarterText: 'Αυτό το τρίμηνο'
	}
};

export default el_GR;



================================================
FILE: packages/stdf/src/lib/lang/en_GB.ts
================================================
import type { LangProps } from './index.js';

const en_GB: LangProps = {
	common: {
		slotEmpty: 'Slot is empty!',
		loading: 'Loading...',
		noData: 'No data',
		noMoreData: 'No more data',
		done: 'Done'
	},
	actionSheet: {
		cancelText: 'Cancel'
	},
	bottomSheet: {
		title: 'Title'
	},
	dialog: {
		title: 'Warning',
		content: 'Content',
		primaryText: 'OK',
		secondaryText: 'Cancel'
	},
	input: {
		pleaseInput: 'Please input'
	},
	modal: {
		title: 'Title',
		content: 'Content',
		btnText: 'OK'
	},
	navBar: {
		title: 'Title'
	},
	pagination: {
		defaultOnlyOnePage: 'Only one'
	},
	picker: {
		defaultTitle: 'Please select',
		defaultCancel: 'Cancel',
		defaultConfirm: 'Confirm'
	},
	asyncPicker: {
		defaultTitle: 'Please select',
		defaultCancel: 'Cancel',
		defaultConfirm: 'Confirm',
		defaultNext: 'Next',
		defaultPrev: 'Prev',
		defaultSelected: 'Selected'
	},
	rate: {
		error1: 'Rating should not be greater than your overall feedback!',
		error2: 'Rating should be completed at least once as a whole!',
		error3: 'Rating is not high, so the hedgehog is sleeping!',
		error4: 'Rating should be an odd number, so that it can develop into a hedgehog!',
		error5: 'The height or width of the rating is difficult to touch on the mobile phone!'
	},
	timePicker: {
		defaultTitle: 'Please select',
		defaultCancel: 'Cancel',
		defaultConfirm: 'Confirm',
		defaultYear: 'Year',
		defaultMonth: 'Month',
		defaultDay: 'Day',
		defaultHour: 'Hour',
		defaultMinute: 'Minute',
		defaultSecond: 'Second'
	},
	calendar: {
		weekTextList: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
		weekSundayStartTextList: ['Sa', 'Su', 'Mo', 'Tu', 'We', 'Th', 'Fr'],
		monthTextList: [
			'January',
			'February',
			'March',
			'April',
			'May',
			'June',
			'July',
			'August',
			'September',
			'October',
			'November',
			'December'
		],
		confirmText: 'Confirm',
		selectedText: 'Selected',
		dayText: 'day',
		beforeText: 'Before',
		afterText: 'After',
		currentWeekText: 'This week',
		currentMonthText: 'This month',
		currentQuarterText: 'This quarter'
	}
};

export default en_GB;



================================================
FILE: packages/stdf/src/lib/lang/en_US.ts
================================================
import type { LangProps } from './index.js';

const en_US: LangProps = {
	common: {
		slotEmpty: 'The content of the slot is empty!',
		loading: 'Loading...',
		noData: 'No data',
		noMoreData: 'No more data',
		done: 'Done'
	},
	actionSheet: {
		cancelText: 'Cancel'
	},
	bottomSheet: {
		title: 'Title'
	},
	dialog: {
		title: 'Hint',
		content: 'Content',
		primaryText: 'Confirm',
		secondaryText: 'Cancel'
	},
	input: {
		pleaseInput: 'Please enter'
	},
	modal: {
		title: 'Title',
		content: 'Content',
		btnText: 'I see'
	},
	navBar: {
		title: 'Title'
	},
	pagination: {
		defaultOnlyOnePage: 'Only one page'
	},
	picker: {
		defaultTitle: 'Please choose',
		defaultCancel: 'Cancel',
		defaultConfirm: 'Confirm'
	},
	asyncPicker: {
		defaultTitle: 'Please choose',
		defaultCancel: 'Cancel',
		defaultConfirm: 'Confirm',
		defaultNext: 'Next',
		defaultPrev: 'Previous',
		defaultSelected: 'Selected'
	},
	rate: {
		error1: 'Value cannot be greater than Total!',
		error2: 'Total must be removed by 1!',
		error3: 'Value must be removed by 1 when non -semi -elected!',
		error4: 'Value must be removed by 0.5 when half elected!',
		error5: 'Width or height is less than 20, which makes the mobile terminal click difficult!'
	},
	timePicker: {
		defaultTitle: 'Please choose',
		defaultCancel: 'Cancel',
		defaultConfirm: 'Confirm',
		defaultYear: 'Year',
		defaultMonth: 'Month',
		defaultDay: 'Day',
		defaultHour: 'Hour',
		defaultMinute: 'Minute',
		defaultSecond: 'Second'
	},
	calendar: {
		weekTextList: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
		weekSundayStartTextList: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
		monthTextList: [
			'January',
			'February',
			'March',
			'April',
			'May',
			'June',
			'July',
			'August',
			'September',
			'October',
			'November',
			'December'
		],
		confirmText: 'Confirm',
		selectedText: 'Selected',
		dayText: 'day',
		beforeText: 'Recent',
		afterText: 'Future',
		currentWeekText: 'This week',
		currentMonthText: 'This month',
		currentQuarterText: 'This quarter'
	}
};

export default en_US;



================================================
FILE: packages/stdf/src/lib/lang/es_ES.ts
================================================
import type { LangProps } from './index.js';

const es_ES: LangProps = {
	common: {
		slotEmpty: '¡El slot está vacío!',
		loading: 'Cargando...',
		noData: 'Sin datos',
		noMoreData: 'No hay más datos',
		done: 'Hecho'
	},
	actionSheet: {
		cancelText: 'Cancelar'
	},
	bottomSheet: {
		title: 'Título'
	},
	dialog: {
		title: 'Advertencia',
		content: 'Contenido',
		primaryText: 'OK',
		secondaryText: 'Cancelar'
	},
	input: {
		pleaseInput: 'Por favor, introduzca'
	},
	modal: {
		title: 'Título',
		content: 'Contenido',
		btnText: 'OK'
	},
	navBar: {
		title: 'Título'
	},
	pagination: {
		defaultOnlyOnePage: 'Solo una página'
	},
	picker: {
		defaultTitle: 'Por favor seleccione',
		defaultCancel: 'Cancelar',
		defaultConfirm: 'Confirmar'
	},
	asyncPicker: {
		defaultTitle: 'Por favor seleccione',
		defaultCancel: 'Cancelar',
		defaultConfirm: 'Confirmar',
		defaultNext: 'Siguiente',
		defaultPrev: 'Anterior',
		defaultSelected: 'Seleccionado'
	},
	rate: {
		error1: '¡La calificación no debe ser mayor que su retroalimentación general!',
		error2: '¡Debe completar la calificación al menos una vez en su totalidad!',
		error3: '¡La calificación no es alta, por lo que el puercoespín está durmiendo!',
		error4: '¡La calificación debe ser un número impar, para que pueda convertirse en un puercoespín!',
		error5: '¡La altura o anchura de la calificación es difícil de tocar en el teléfono móvil!'
	},
	timePicker: {
		defaultTitle: 'Por favor seleccione',
		defaultCancel: 'Cancelar',
		defaultConfirm: 'Confirmar',
		defaultYear: 'Año',
		defaultMonth: 'Mes',
		defaultDay: 'Día',
		defaultHour: 'Hora',
		defaultMinute: 'Minuto',
		defaultSecond: 'Segundo'
	},
	calendar: {
		weekTextList: ['Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb'],
		weekSundayStartTextList: ['Sáb', 'Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie'],
		monthTextList: [
			'Enero',
			'Febrero',
			'Marzo',
			'Abril',
			'Mayo',
			'Junio',
			'Julio',
			'Agosto',
			'Septiembre',
			'Octubre',
			'Noviembre',
			'Diciembre'
		],
		confirmText: 'Confirmar',
		selectedText: 'Seleccionado',
		dayText: 'día',
		beforeText: 'Antes',
		afterText: 'Después',
		currentWeekText: 'Esta semana',
		currentMonthText: 'Este mes',
		currentQuarterText: 'Este trimestre'
	}
};

export default es_ES;



================================================
FILE: packages/stdf/src/lib/lang/et_EE.ts
================================================
import type { LangProps } from './index.js';

const et_EE: LangProps = {
	common: {
		slotEmpty: 'Pesa on tühi!',
		loading: 'Laadimine...',
		noData: 'Andmeid pole',
		noMoreData: 'Rohkem andmeid pole',
		done: 'Valmis'
	},
	actionSheet: {
		cancelText: 'Tühista'
	},
	bottomSheet: {
		title: 'Pealkiri'
	},
	dialog: {
		title: 'Hoiatus',
		content: 'Sisu',
		primaryText: 'OK',
		secondaryText: 'Tühista'
	},
	input: {
		pleaseInput: 'Palun sisesta'
	},
	modal: {
		title: 'Pealkiri',
		content: 'Sisu',
		btnText: 'OK'
	},
	navBar: {
		title: 'Pealkiri'
	},
	pagination: {
		defaultOnlyOnePage: 'Ainult üks leht'
	},
	picker: {
		defaultTitle: 'Palun valige',
		defaultCancel: 'Tühista',
		defaultConfirm: 'Kinnita'
	},
	asyncPicker: {
		defaultTitle: 'Palun valige',
		defaultCancel: 'Tühista',
		defaultConfirm: 'Kinnita',
		defaultNext: 'Järgmine',
		defaultPrev: 'Eelmine',
		defaultSelected: 'Valitud'
	},
	rate: {
		error1: 'Hinnang ei tohiks olla suurem kui kogu teie tagasiside!',
		error2: 'Hinnang tuleks täita vähemalt üks kord tervikuna!',
		error3: 'Hinnang pole kõrge, nii et siil magab!',
		error4: 'Hinnang peaks olema paaritu arv, et see võiks areneda siiliks!',
		error5: 'Hinnangu kõrgus või laius on mobiiltelefonil raskesti puudutatav!'
	},
	timePicker: {
		defaultTitle: 'Palun valige',
		defaultCancel: 'Tühista',
		defaultConfirm: 'Kinnita',
		defaultYear: 'Aasta',
		defaultMonth: 'Kuu',
		defaultDay: 'Päev',
		defaultHour: 'Tund',
		defaultMinute: 'Minut',
		defaultSecond: 'Sekund'
	},
	calendar: {
		weekTextList: ['P', 'E', 'T', 'K', 'N', 'R', 'L'],
		weekSundayStartTextList: ['L', 'P', 'E', 'T', 'K', 'N', 'R'],
		monthTextList: [
			'Jaanuar',
			'Veebruar',
			'Märts',
			'Aprill',
			'Mai',
			'Juuni',
			'Juuli',
			'August',
			'September',
			'Oktoober',
			'November',
			'Detsember'
		],
		confirmText: 'Kinnita',
		selectedText: 'Valitud',
		dayText: 'päev',
		beforeText: 'Enne',
		afterText: 'Pärast',
		currentWeekText: 'See nädal',
		currentMonthText: 'See kuu',
		currentQuarterText: 'See kvartal'
	}
};

export default et_EE;



================================================
FILE: packages/stdf/src/lib/lang/eu_ES.ts
================================================
import type { LangProps } from './index.js';

const eu_ES: LangProps = {
	common: {
		slotEmpty: 'Slot-a hutsik dago!',
		loading: 'Kargatzen...',
		noData: 'Datu gabe',
		noMoreData: 'Ez dago gehio datu',
		done: 'Eginda'
	},
	actionSheet: {
		cancelText: 'Utzi'
	},
	bottomSheet: {
		title: 'Izenburua'
	},
	dialog: {
		title: 'Kontuz!',
		content: 'Edukia',
		primaryText: 'Onartu',
		secondaryText: 'Utzi'
	},
	input: {
		pleaseInput: 'Mesedez sartu'
	},
	modal: {
		title: 'Izenburua',
		content: 'Edukia',
		btnText: 'Onartu'
	},
	navBar: {
		title: 'Izenburua'
	},
	pagination: {
		defaultOnlyOnePage: 'Orri bakarra'
	},
	picker: {
		defaultTitle: 'Aukeratu mesedez',
		defaultCancel: 'Utzi',
		defaultConfirm: 'Onartu'
	},
	asyncPicker: {
		defaultTitle: 'Aukeratu mesedez',
		defaultCancel: 'Utzi',
		defaultConfirm: 'Onartu',
		defaultNext: 'Hurrengoa',
		defaultPrev: 'Aurrekoa',
		defaultSelected: 'Aukeratuta'
	},
	rate: {
		error1: 'Kalifikazioa ezin da zure iruzkina orokorrean baino handiagoa izan!',
		error2: 'Kalifikazioa gutxienez osatu behar da oso bat aldiz!',
		error3: 'Kalifikazioa ez da handia, beraz oxela altxatuta dago!',
		error4: 'Kalifikazioa zenbaki bakoitzean asmatu behar da, sihinez armadillo bihurtzeko!',
		error5: 'Kalifikazioaren altuera edo zabalera txarto sakatzea da telefono mugikorrean!'
	},
	timePicker: {
		defaultTitle: 'Aukeratu mesedez',
		defaultCancel: 'Utzi',
		defaultConfirm: 'Onartu',
		defaultYear: 'Urtea',
		defaultMonth: 'Hilabetea',
		defaultDay: 'Eguna',
		defaultHour: 'Ordua',
		defaultMinute: 'Minutua',
		defaultSecond: 'Segundoa'
	},
	calendar: {
		weekTextList: ['Ig.', 'Al.', 'Ar.', 'Az.', 'Og.', 'Or.', 'La.'],
		weekSundayStartTextList: ['La.', 'Ig.', 'Al.', 'Ar.', 'Az.', 'Og.', 'Or.'],
		monthTextList: [
			'Urtarrila',
			'Otsaila',
			'Martxoa',
			'Apirila',
			'Maiatza',
			'Ekaina',
			'Uztaila',
			'Abuztua',
			'Iraila',
			'Urria',
			'Azaroa',
			'Abendua'
		],
		confirmText: 'Onartu',
		selectedText: 'Aukeratuta',
		dayText: 'eguna',
		beforeText: 'Aurretik',
		afterText: 'Ondoren',
		currentWeekText: 'Aste hau',
		currentMonthText: 'Hilabete hau',
		currentQuarterText: 'Gertaera hau'
	}
};

export default eu_ES;



================================================
FILE: packages/stdf/src/lib/lang/fa_IR.ts
================================================
import type { LangProps } from './index.js';

const fa_IR: LangProps = {
	common: {
		slotEmpty: 'اسلات خالی است!',
		loading: 'در حال بارگذاری...',
		noData: 'هیچ داده‌ای موجود نیست',
		noMoreData: 'دیگر داده‌ای موجود نیست',
		done: 'انجام شد'
	},
	actionSheet: {
		cancelText: 'لغو'
	},
	bottomSheet: {
		title: 'عنوان'
	},
	dialog: {
		title: 'هشدار',
		content: 'محتوا',
		primaryText: 'تایید',
		secondaryText: 'لغو'
	},
	input: {
		pleaseInput: 'لطفا وارد کنید'
	},
	modal: {
		title: 'عنوان',
		content: 'محتوا',
		btnText: 'تایید'
	},
	navBar: {
		title: 'عنوان'
	},
	pagination: {
		defaultOnlyOnePage: 'فقط یک صفحه وجود دارد'
	},
	picker: {
		defaultTitle: 'لطفا انتخاب کنید',
		defaultCancel: 'لغو',
		defaultConfirm: 'تایید'
	},
	asyncPicker: {
		defaultTitle: 'لطفا انتخاب کنید',
		defaultCancel: 'لغو',
		defaultConfirm: 'تایید',
		defaultNext: 'بعدی',
		defaultPrev: 'قبلی',
		defaultSelected: 'انتخاب شده'
	},
	rate: {
		error1: 'رتبه‌بندی نباید از کل بازخورد شما بیشتر باشد!',
		error2: 'رتبه‌بندی باید حداقل یکبار کامل شود!',
		error3: 'رتبه‌بندی بخش‌بخش است، بنابراین خزنده در حال خوابیدن است!',
		error4: 'رتبه‌بندی باید یک عدد فرد باشد تا بتواند به خزنده تبدیل شود!',
		error5: 'ارتفاع یا عرض ارزیابی بسیار سخت بر روی تلفن همراه است!'
	},
	timePicker: {
		defaultTitle: 'لطفا انتخاب کنید',
		defaultCancel: 'لغو',
		defaultConfirm: 'تایید',
		defaultYear: 'سال',
		defaultMonth: 'ماه',
		defaultDay: 'روز',
		defaultHour: 'ساعت',
		defaultMinute: 'دقیقه',
		defaultSecond: 'ثانیه'
	},
	calendar: {
		weekTextList: ['یک', 'دو', 'سه', 'چهار', 'پنج', 'جمعه', 'شنبه'],
		weekSundayStartTextList: ['ش', 'ی', 'د', 'س', 'چ', 'پ', 'ج'],
		monthTextList: ['ژانویه', 'فوریه', 'مارس', 'آوریل', 'می', 'ژوئن', 'جولای', 'آگوست', 'سپتامبر', 'اکتبر', 'نوامبر', 'دسامبر'],
		confirmText: 'تایید',
		selectedText: 'انتخاب شده',
		dayText: 'روز',
		beforeText: 'پیش',
		afterText: 'بعد',
		currentWeekText: 'هفته جاری',
		currentMonthText: 'ماه جاری',
		currentQuarterText: 'سه ماهه جاری'
	}
};

export default fa_IR;



================================================
FILE: packages/stdf/src/lib/lang/fi_FI.ts
================================================
import type { LangProps } from './index.js';

const fi_FI: LangProps = {
	common: {
		slotEmpty: 'Paikka on tyhjä!',
		loading: 'Ladataan...',
		noData: 'Ei dataa',
		noMoreData: 'Ei enempää tietoja',
		done: 'Valmis'
	},
	actionSheet: {
		cancelText: 'Peruuta'
	},
	bottomSheet: {
		title: 'Otsikko'
	},
	dialog: {
		title: 'Varoitus',
		content: 'Sisältö',
		primaryText: 'Vahvista',
		secondaryText: 'Peruuta'
	},
	input: {
		pleaseInput: 'Kirjoita tähän'
	},
	modal: {
		title: 'Otsikko',
		content: 'Sisältö',
		btnText: 'OK'
	},
	navBar: {
		title: 'Otsikko'
	},
	pagination: {
		defaultOnlyOnePage: 'Vain yksi sivu'
	},
	picker: {
		defaultTitle: 'Valitse',
		defaultCancel: 'Peruuta',
		defaultConfirm: 'OK'
	},
	asyncPicker: {
		defaultTitle: 'Valitse',
		defaultCancel: 'Peruuta',
		defaultConfirm: 'OK',
		defaultNext: 'Seuraava',
		defaultPrev: 'Edellinen',
		defaultSelected: 'Valittu'
	},
	rate: {
		error1: 'Arvostelun ei pitäisi olla suurempi kuin yhteenvetosi!',
		error2: 'Arvostelu on täytettävä vähintään kerran!',
		error3: 'Arvostelu on osioittain, joten pöllö nukkuu!',
		error4: 'Arvostelun on oltava yksi parittomista numeroista muuttaakseen sen kiharaksi!',
		error5: 'Arvostelun korkeus tai leveys on liian pieni puhelimessa!'
	},
	timePicker: {
		defaultTitle: 'Valitse',
		defaultCancel: 'Peruuta',
		defaultConfirm: 'OK',
		defaultYear: 'Vuosi',
		defaultMonth: 'Kuukausi',
		defaultDay: 'Päivä',
		defaultHour: 'Tunti',
		defaultMinute: 'Minuutti',
		defaultSecond: 'Sekunti'
	},
	calendar: {
		weekTextList: ['Su', 'Ma', 'Ti', 'Ke', 'To', 'Pe', 'La'],
		weekSundayStartTextList: ['Su', 'Ma', 'Ti', 'Ke', 'To', 'Pe', 'La'],
		monthTextList: [
			'Tammikuu',
			'Helmikuu',
			'Maaliskuu',
			'Huhtikuu',
			'Toukokuu',
			'Kesäkuu',
			'Heinäkuu',
			'Elokuu',
			'Syyskuu',
			'Lokakuu',
			'Marraskuu',
			'Joulukuu'
		],
		confirmText: 'OK',
		selectedText: 'Valittu',
		dayText: 'Päivä',
		beforeText: 'Ennen',
		afterText: 'Jälkeen',
		currentWeekText: 'Nykyinen viikko',
		currentMonthText: 'Nykyinen kuukausi',
		currentQuarterText: 'Nykyinen neljännesvuosi'
	}
};

export default fi_FI;



================================================
FILE: packages/stdf/src/lib/lang/fr_BE.ts
================================================
import type { LangProps } from './index.js';

const fr_BE: LangProps = {
	common: {
		slotEmpty: 'Emplacement libre!',
		loading: 'Chargement en cours...',
		noData: 'Aucune donnée',
		noMoreData: 'Plus de données',
		done: 'Terminé'
	},
	actionSheet: {
		cancelText: 'Annuler'
	},
	bottomSheet: {
		title: 'Titre'
	},
	dialog: {
		title: 'Avertissement',
		content: 'Contenu',
		primaryText: 'Confirmer',
		secondaryText: 'Annuler'
	},
	input: {
		pleaseInput: 'Veuillez renseigner'
	},
	modal: {
		title: 'Titre',
		content: 'Contenu',
		btnText: 'OK'
	},
	navBar: {
		title: 'Titre'
	},
	pagination: {
		defaultOnlyOnePage: 'Une seule page'
	},
	picker: {
		defaultTitle: 'Choisir',
		defaultCancel: 'Annuler',
		defaultConfirm: 'OK'
	},
	asyncPicker: {
		defaultTitle: 'Sélectionner',
		defaultCancel: 'Annuler',
		defaultConfirm: 'OK',
		defaultNext: 'Suivant',
		defaultPrev: 'Précédent',
		defaultSelected: 'Sélectionné'
	},
	rate: {
		error1: "L'évaluation ne doit pas être supérieure à votre résumé !",
		error2: "L'évaluation doit être remplie au moins une fois !",
		error3: "L'évaluation est en morceaux, alors la chouette est endormie !",
		error4: "L'évaluation doit être un nombre impair pour la rendre chouette!",
		error5: "La hauteur ou la largeur de l'évaluation est trop petite sur un téléphone !"
	},
	timePicker: {
		defaultTitle: 'Choisir',
		defaultCancel: 'Annuler',
		defaultConfirm: 'OK',
		defaultYear: 'Année',
		defaultMonth: 'Mois',
		defaultDay: 'Jour',
		defaultHour: 'Heure',
		defaultMinute: 'Minute',
		defaultSecond: 'Seconde'
	},
	calendar: {
		weekTextList: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],
		weekSundayStartTextList: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],
		monthTextList: [
			'Janvier',
			'Février',
			'Mars',
			'Avril',
			'Mai',
			'Juin',
			'Juillet',
			'Août',
			'Septembre',
			'Octobre',
			'Novembre',
			'Décembre'
		],
		confirmText: 'OK',
		selectedText: 'Sélectionné',
		dayText: 'Jour',
		beforeText: 'Avant',
		afterText: 'Après',
		currentWeekText: 'Semaine en cours',
		currentMonthText: 'Mois en cours',
		currentQuarterText: 'Trimestre en cours'
	}
};

export default fr_BE;



================================================
FILE: packages/stdf/src/lib/lang/fr_CA.ts
================================================
import type { LangProps } from './index.js';

const fr_CA: LangProps = {
	common: {
		slotEmpty: 'Emplacement libre!',
		loading: 'Chargement en cours...',
		noData: 'Aucune donnée',
		noMoreData: 'Plus de données',
		done: 'Terminé'
	},
	actionSheet: {
		cancelText: 'Annuler'
	},
	bottomSheet: {
		title: 'Titre'
	},
	dialog: {
		title: 'Avertissement',
		content: 'Contenu',
		primaryText: 'Confirmer',
		secondaryText: 'Annuler'
	},
	input: {
		pleaseInput: 'Veuillez renseigner'
	},
	modal: {
		title: 'Titre',
		content: 'Contenu',
		btnText: 'OK'
	},
	navBar: {
		title: 'Titre'
	},
	pagination: {
		defaultOnlyOnePage: 'Une seule page'
	},
	picker: {
		defaultTitle: 'Choisir',
		defaultCancel: 'Annuler',
		defaultConfirm: 'OK'
	},
	asyncPicker: {
		defaultTitle: 'Sélectionner',
		defaultCancel: 'Annuler',
		defaultConfirm: 'OK',
		defaultNext: 'Suivant',
		defaultPrev: 'Précédent',
		defaultSelected: 'Sélectionné'
	},
	rate: {
		error1: "L'évaluation ne doit pas être supérieure à votre résumé !",
		error2: "L'évaluation doit être remplie au moins une fois !",
		error3: "L'évaluation est en morceaux, alors la chouette est endormie !",
		error4: "L'évaluation doit être un nombre impair pour la rendre chouette!",
		error5: "La hauteur ou la largeur de l'évaluation est trop petite sur un téléphone !"
	},
	timePicker: {
		defaultTitle: 'Choisir',
		defaultCancel: 'Annuler',
		defaultConfirm: 'OK',
		defaultYear: 'Année',
		defaultMonth: 'Mois',
		defaultDay: 'Jour',
		defaultHour: 'Heure',
		defaultMinute: 'Minute',
		defaultSecond: 'Seconde'
	},
	calendar: {
		weekTextList: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],
		weekSundayStartTextList: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],
		monthTextList: [
			'Janvier',
			'Février',
			'Mars',
			'Avril',
			'Mai',
			'Juin',
			'Juillet',
			'Août',
			'Septembre',
			'Octobre',
			'Novembre',
			'Décembre'
		],
		confirmText: 'OK',
		selectedText: 'Sélectionné',
		dayText: 'Jour',
		beforeText: 'Avant',
		afterText: 'Après',
		currentWeekText: 'Semaine en cours',
		currentMonthText: 'Mois en cours',
		currentQuarterText: 'Trimestre en cours'
	}
};

export default fr_CA;



================================================
FILE: packages/stdf/src/lib/lang/fr_FR.ts
================================================
import type { LangProps } from './index.js';

const fr_FR: LangProps = {
	common: {
		slotEmpty: 'Emplacement libre!',
		loading: 'Chargement en cours...',
		noData: 'Aucune donnée',
		noMoreData: 'Plus de données',
		done: 'Terminé'
	},
	actionSheet: {
		cancelText: 'Annuler'
	},
	bottomSheet: {
		title: 'Titre'
	},
	dialog: {
		title: 'Avertissement',
		content: 'Contenu',
		primaryText: 'Confirmer',
		secondaryText: 'Annuler'
	},
	input: {
		pleaseInput: 'Veuillez renseigner'
	},
	modal: {
		title: 'Titre',
		content: 'Contenu',
		btnText: 'OK'
	},
	navBar: {
		title: 'Titre'
	},
	pagination: {
		defaultOnlyOnePage: 'Une seule page'
	},
	picker: {
		defaultTitle: 'Choisir',
		defaultCancel: 'Annuler',
		defaultConfirm: 'OK'
	},
	asyncPicker: {
		defaultTitle: 'Sélectionner',
		defaultCancel: 'Annuler',
		defaultConfirm: 'OK',
		defaultNext: 'Suivant',
		defaultPrev: 'Précédent',
		defaultSelected: 'Sélectionné'
	},
	rate: {
		error1: "L'évaluation ne doit pas être supérieure à votre résumé !",
		error2: "L'évaluation doit être remplie au moins une fois !",
		error3: "L'évaluation est en morceaux, alors la chouette est endormie !",
		error4: "L'évaluation doit être un nombre impair pour la rendre chouette!",
		error5: "La hauteur ou la largeur de l'évaluation est trop petite sur un téléphone !"
	},
	timePicker: {
		defaultTitle: 'Choisir',
		defaultCancel: 'Annuler',
		defaultConfirm: 'OK',
		defaultYear: 'Année',
		defaultMonth: 'Mois',
		defaultDay: 'Jour',
		defaultHour: 'Heure',
		defaultMinute: 'Minute',
		defaultSecond: 'Seconde'
	},
	calendar: {
		weekTextList: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],
		weekSundayStartTextList: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],
		monthTextList: [
			'Janvier',
			'Février',
			'Mars',
			'Avril',
			'Mai',
			'Juin',
			'Juillet',
			'Août',
			'Septembre',
			'Octobre',
			'Novembre',
			'Décembre'
		],
		confirmText: 'OK',
		selectedText: 'Sélectionné',
		dayText: 'Jour',
		beforeText: 'Avant',
		afterText: 'Après',
		currentWeekText: 'Semaine en cours',
		currentMonthText: 'Mois en cours',
		currentQuarterText: 'Trimestre en cours'
	}
};

export default fr_FR;



================================================
FILE: packages/stdf/src/lib/lang/ga_IE.ts
================================================
import type { LangProps } from './index.js';

const ga_IE: LangProps = {
	common: {
		slotEmpty: 'Sábháil oscailte!',
		loading: 'Lodáil i gceist...',
		noData: 'Níl aon sonraí ann',
		noMoreData: 'Níl tuilleadh sonraí',
		done: 'Déanta'
	},
	actionSheet: {
		cancelText: 'Cealaigh'
	},
	bottomSheet: {
		title: 'Teideal'
	},
	dialog: {
		title: 'Rabhadh',
		content: 'Ábhar',
		primaryText: 'Deimhnigh',
		secondaryText: 'Cealaigh'
	},
	input: {
		pleaseInput: 'Cuir isteach le do thoil'
	},
	modal: {
		title: 'Teideal',
		content: 'Ábhar',
		btnText: 'Ceart go leor'
	},
	navBar: {
		title: 'Teideal'
	},
	pagination: {
		defaultOnlyOnePage: 'Níl ach leathanach amháin ann'
	},
	picker: {
		defaultTitle: 'Roghnaigh',
		defaultCancel: 'Cealaigh',
		defaultConfirm: 'Ceart go leor'
	},
	asyncPicker: {
		defaultTitle: 'Roghnaigh',
		defaultCancel: 'Cealaigh',
		defaultConfirm: 'Ceart go leor',
		defaultNext: 'Ar aghaidh',
		defaultPrev: 'Anois siar',
		defaultSelected: 'Roghnaithe'
	},
	rate: {
		error1: 'Ní féidir an luacháil a bheith níos mó ná do chuid tuairimí!',
		error2: 'Caithfidh an luacháil a líonadh ar a laghad amháin!',
		error3: 'Tá an luacháil briste, is ea, taitníonn an t-úll dom!',
		error4: 'Ní mór don luacháil a bheith uimhriúil leis an t-úll a dhéanamh astu!',
		error5: 'Tá an méid nó an leithead an luachála ró-ghairid ar fón póca!'
	},
	timePicker: {
		defaultTitle: 'Roghnaigh',
		defaultCancel: 'Cealaigh',
		defaultConfirm: 'Ceart go leor',
		defaultYear: 'Bliain',
		defaultMonth: 'Mí',
		defaultDay: 'Lá',
		defaultHour: 'Uair',
		defaultMinute: 'Nóiméad',
		defaultSecond: 'Soicind'
	},
	calendar: {
		weekTextList: ['Domh', 'Luan', 'Mái', 'Céa', 'Déa', 'Aoi', 'Sat'],
		weekSundayStartTextList: ['Déa', 'Luan', 'Mái', 'Céa', 'Déa', 'Aoi', 'Sat'],
		monthTextList: [
			'Eanáir',
			'Feabhra',
			'Márta',
			'Aibreán',
			'Bealtaine',
			'Meitheamh',
			'Iúil',
			'Lúnasa',
			'Meán Fómhair',
			'Deireadh Fomhair',
			'Samhain',
			'Nollaig'
		],
		confirmText: 'Ceart go leor',
		selectedText: 'Roghnaithe',
		dayText: 'Lá',
		beforeText: 'Roimh',
		afterText: 'Tar éis',
		currentWeekText: 'Seachtain reatha',
		currentMonthText: 'Mí reatha',
		currentQuarterText: 'Ráithe reatha'
	}
};

export default ga_IE;



================================================
FILE: packages/stdf/src/lib/lang/gl_ES.ts
================================================
import type { LangProps } from './index.js';

const gl_ES: LangProps = {
	common: {
		slotEmpty: 'ranura vacía!',
		loading: 'Cargando...',
		noData: 'Ningún dato',
		noMoreData: 'No hay más datos',
		done: 'Hecho'
	},
	actionSheet: {
		cancelText: 'Cancelar'
	},
	bottomSheet: {
		title: 'Título'
	},
	dialog: {
		title: 'Aviso',
		content: 'Contenido',
		primaryText: 'Confirmar',
		secondaryText: 'Cancelar'
	},
	input: {
		pleaseInput: 'Por favor introduzca'
	},
	modal: {
		title: 'Título',
		content: 'Contenido',
		btnText: 'De acuerdo'
	},
	navBar: {
		title: 'Título'
	},
	pagination: {
		defaultOnlyOnePage: 'Solo hay una página'
	},
	picker: {
		defaultTitle: 'Elixir',
		defaultCancel: 'Cancelar',
		defaultConfirm: 'De acuerdo'
	},
	asyncPicker: {
		defaultTitle: 'Seleccionar',
		defaultCancel: 'Cancelar',
		defaultConfirm: 'De acuerdo',
		defaultNext: 'Próximo',
		defaultPrev: 'Anterior',
		defaultSelected: 'Seleccionados'
	},
	rate: {
		error1: '¡La valoración no puede ser mayor que el resumen!',
		error2: '¡La valoración debe ser completada al menos una vez!',
		error3: 'La valoración está rota, ¡así que la lechuza está durmiendo!',
		error4: '¡La valoración debe ser un número impar para hacerla genial!',
		error5: '¡La altura o ancho de la valoración es demasiado pequeña en un teléfono!'
	},
	timePicker: {
		defaultTitle: 'Elixir',
		defaultCancel: 'Cancelar',
		defaultConfirm: 'De acuerdo',
		defaultYear: 'Año',
		defaultMonth: 'Mes',
		defaultDay: 'Día',
		defaultHour: 'Hora',
		defaultMinute: 'Minuto',
		defaultSecond: 'Segundo'
	},
	calendar: {
		weekTextList: ['Dom', 'Lun', 'Mar', 'Mér', 'Xov', 'Ven', 'Sáb'],
		weekSundayStartTextList: ['Dom', 'Lun', 'Mar', 'Mér', 'Xob', 'Ven', 'Sáb'],
		monthTextList: ['Xan', 'Feb', 'Maz', 'Abr', 'Mai', 'Xun', 'Xul', 'Ago', 'Set', 'Out', 'Nov', 'Dec'],
		confirmText: 'De acuerdo',
		selectedText: 'Seleccionados',
		dayText: 'Día',
		beforeText: 'Antes',
		afterText: 'Despois',
		currentWeekText: 'Semana actual',
		currentMonthText: 'Este mes',
		currentQuarterText: 'Este cuarto'
	}
};

export default gl_ES;



================================================
FILE: packages/stdf/src/lib/lang/he_IL.ts
================================================
import type { LangProps } from './index.js';

const he_IL: LangProps = {
	common: {
		slotEmpty: 'ריק!',
		loading: 'טוען...',
		noData: 'אין נתונים',
		noMoreData: 'אין יותר נתונים',
		done: 'סיום'
	},
	actionSheet: {
		cancelText: 'בטל'
	},
	bottomSheet: {
		title: 'כותרת'
	},
	dialog: {
		title: 'הודעה',
		content: 'תוכן',
		primaryText: 'אישור',
		secondaryText: 'בטל'
	},
	input: {
		pleaseInput: 'אנא הזן'
	},
	modal: {
		title: 'כותרת',
		content: 'תוכן',
		btnText: 'אישור'
	},
	navBar: {
		title: 'כותרת'
	},
	pagination: {
		defaultOnlyOnePage: 'רק דף אחד'
	},
	picker: {
		defaultTitle: 'בחר',
		defaultCancel: 'בטל',
		defaultConfirm: 'אישור'
	},
	asyncPicker: {
		defaultTitle: 'בחר',
		defaultCancel: 'בטל',
		defaultConfirm: 'אישור',
		defaultNext: 'הבא',
		defaultPrev: 'הקודם',
		defaultSelected: 'נבחרים'
	},
	rate: {
		error1: 'הדירוג לא יכול להיות גבוה יותר מהסיכומים!',
		error2: 'נדרש להשלים את הדירוג לפחות פעם אחת!',
		error3: 'הדירוג שבור, לכן אני אוהב את התפוח שלי לישון!',
		error4: 'הדירוג חייב להיות מספר אי-זוגי כדי להיות מגניב!',
		error5: 'הגובה או הרוחב של הדירוג קטן מדי בטלפון!'
	},
	timePicker: {
		defaultTitle: 'בחר',
		defaultCancel: 'בטל',
		defaultConfirm: 'אישור',
		defaultYear: 'שנה',
		defaultMonth: 'חודש',
		defaultDay: 'יום',
		defaultHour: 'שעה',
		defaultMinute: 'דקה',
		defaultSecond: 'שניה'
	},
	calendar: {
		weekTextList: ['א', 'ב', 'ג', 'ד', 'ה', 'ו', 'ש'],
		weekSundayStartTextList: ['א', 'ב', 'ג', 'ד', 'ה', 'ו', 'ש'],
		monthTextList: ['ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'],
		confirmText: 'אישור',
		selectedText: 'נבחרים',
		dayText: 'יום',
		beforeText: 'לפני',
		afterText: 'אחרי',
		currentWeekText: 'שבוע נוכחי',
		currentMonthText: 'חודש נוכחי',
		currentQuarterText: 'רבעון נוכחי'
	}
};

export default he_IL;



================================================
FILE: packages/stdf/src/lib/lang/hi_IN.ts
================================================
import type { LangProps } from './index.js';

const hi_IN: LangProps = {
	common: {
		slotEmpty: 'खाली!',
		loading: 'लोड हो रहा है...',
		noData: 'कोई डेटा नहीं',
		noMoreData: 'और डेटा नहीं',
		done: 'पूरा कर लिया'
	},
	actionSheet: {
		cancelText: 'रद्द करें'
	},
	bottomSheet: {
		title: 'शीर्षक'
	},
	dialog: {
		title: 'सूचना',
		content: 'सामग्री',
		primaryText: 'अभिप्राय दर्ज करें',
		secondaryText: 'रद्द करें'
	},
	input: {
		pleaseInput: 'कृपया इनपुट करें'
	},
	modal: {
		title: 'शीर्षक',
		content: 'सामग्री',
		btnText: 'ठीक है'
	},
	navBar: {
		title: 'शीर्षक'
	},
	pagination: {
		defaultOnlyOnePage: 'केवल एक पृष्ठ'
	},
	picker: {
		defaultTitle: 'चयन करें',
		defaultCancel: 'रद्द करें',
		defaultConfirm: 'ठीक है'
	},
	asyncPicker: {
		defaultTitle: 'चयन करें',
		defaultCancel: 'रद्द करें',
		defaultConfirm: 'ठीक है',
		defaultNext: 'अगला',
		defaultPrev: 'पिछला',
		defaultSelected: 'चयनित'
	},
	rate: {
		error1: 'रेटिंग जमा आंकड़े से अधिक नहीं हो सकती!',
		error2: 'कम से कम एक बार रेटिंग पूर्ण करनी चाहिए!',
		error3: 'रेटिंग टूटी हुई है, इसलिए मैं अपनी गुलाब की नींद को पसंद करता हूँ!',
		error4: 'रेटिंग केवल विषम संख्या होनी चाहिए ताकि यह ग्रेट हो सके!',
		error5: 'फोन पर रेटिंग का ऊंचाई या चौड़ाई बहुत कम है!'
	},
	timePicker: {
		defaultTitle: 'चयन करें',
		defaultCancel: 'रद्द करें',
		defaultConfirm: 'ठीक है',
		defaultYear: 'वर्ष',
		defaultMonth: 'महीना',
		defaultDay: 'दिन',
		defaultHour: 'घंटा',
		defaultMinute: 'मिनट',
		defaultSecond: 'सेकंड'
	},
	calendar: {
		weekTextList: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'],
		weekSundayStartTextList: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'],
		monthTextList: ['जनवरी', 'फरवरी', 'मार्च', 'अप्रैल', 'मई', 'जून', 'जुलाई', 'अगस्त', 'सितंबर', 'अक्टूबर', 'नवंबर', 'दिसंबर'],
		confirmText: 'ठीक है',
		selectedText: 'चयनित',
		dayText: 'दिन',
		beforeText: 'पूर्व',
		afterText: 'बाद',
		currentWeekText: 'वर्तमान सप्ताह',
		currentMonthText: 'वर्तमान महीना',
		currentQuarterText: 'वर्तमान तिमाही'
	}
};

export default hi_IN;



================================================
FILE: packages/stdf/src/lib/lang/hr_HR.ts
================================================
import type { LangProps } from './index.js';

const hr_HR: LangProps = {
	common: {
		slotEmpty: 'Sadržaj ulaza je prazan!',
		loading: 'Učitavanje...',
		noData: 'Nema dostupnih podataka',
		noMoreData: 'Nema više podataka',
		done: 'Gotovo'
	},
	actionSheet: {
		cancelText: 'Otkaži'
	},
	bottomSheet: {
		title: 'Naslov'
	},
	dialog: {
		title: 'Savjet',
		content: 'Sadržaj',
		primaryText: 'Potvrdi',
		secondaryText: 'Otkaži'
	},
	input: {
		pleaseInput: 'Molimo unesite'
	},
	modal: {
		title: 'Naslov',
		content: 'Sadržaj',
		btnText: 'Razumijem'
	},
	navBar: {
		title: 'Naslov'
	},
	pagination: {
		defaultOnlyOnePage: 'Samo jedna stranica'
	},
	picker: {
		defaultTitle: 'Odaberite',
		defaultCancel: 'Otkaži',
		defaultConfirm: 'Potvrdi'
	},
	asyncPicker: {
		defaultTitle: 'Odaberite',
		defaultCancel: 'Otkaži',
		defaultConfirm: 'Potvrdi',
		defaultNext: 'Sljedeći',
		defaultPrev: 'Prethodni',
		defaultSelected: 'Odabran'
	},
	rate: {
		error1: 'Vrijednost ne smije biti veća od Ukupno!',
		error2: 'Ukupno se mora smanjiti za 1!',
		error3: 'Vrijednost se mora smanjiti za 1 ako nije pola odabrana!',
		error4: 'Vrijednost se mora smanjiti za 0,5 ako je pola odabrana!',
		error5: 'Širina ili visina manja je od 20, što otežava klikanje u mobilnom uređaju!'
	},
	timePicker: {
		defaultTitle: 'Odaberite',
		defaultCancel: 'Otkaži',
		defaultConfirm: 'Potvrdi',
		defaultYear: 'Godina',
		defaultMonth: 'Mjesec',
		defaultDay: 'Dan',
		defaultHour: 'Sat',
		defaultMinute: 'Minute',
		defaultSecond: 'Sekunde'
	},
	calendar: {
		weekTextList: ['Pon', 'Uto', 'Sri', 'Čet', 'Pet', 'Sub', 'Ned'],
		weekSundayStartTextList: ['Ned', 'Pon', 'Uto', 'Sri', 'Čet', 'Pet', 'Sub'],
		monthTextList: [
			'Siječanj',
			'Veljača',
			'Ožujak',
			'Travanj',
			'Svibanj',
			'Lipanj',
			'Srpanj',
			'Kolovoz',
			'Rujan',
			'Listopad',
			'Studeni',
			'Prosinac'
		],
		confirmText: 'Potvrdi',
		selectedText: 'Odabrano',
		dayText: 'Dan',
		beforeText: 'Nedavno',
		afterText: 'Budućnost',
		currentWeekText: 'Ovaj tjedan',
		currentMonthText: 'Ovaj mjesec',
		currentQuarterText: 'Ovo tromjesečje'
	}
};

export default hr_HR;



================================================
FILE: packages/stdf/src/lib/lang/hu_HU.ts
================================================
import type { LangProps } from './index.js';

const hu_HU: LangProps = {
	common: {
		slotEmpty: 'A bemenet tartalma üres!',
		loading: 'Betöltés...',
		noData: 'Nincsenek adatok',
		noMoreData: 'Nincs több adat',
		done: 'Kész'
	},
	actionSheet: {
		cancelText: 'Mégsem'
	},
	bottomSheet: {
		title: 'Cím'
	},
	dialog: {
		title: 'Tipp',
		content: 'Tartalom',
		primaryText: 'Megerősít',
		secondaryText: 'Mégsem'
	},
	input: {
		pleaseInput: 'Kérem írja be'
	},
	modal: {
		title: 'Cím',
		content: 'Tartalom',
		btnText: 'Értettem'
	},
	navBar: {
		title: 'Cím'
	},
	pagination: {
		defaultOnlyOnePage: 'Csak egy oldal'
	},
	picker: {
		defaultTitle: 'Kérem válasszon',
		defaultCancel: 'Mégsem',
		defaultConfirm: 'Megerősít'
	},
	asyncPicker: {
		defaultTitle: 'Kérem válasszon',
		defaultCancel: 'Mégsem',
		defaultConfirm: 'Megerősít',
		defaultNext: 'Következő',
		defaultPrev: 'Előző',
		defaultSelected: 'Kiválasztott'
	},
	rate: {
		error1: 'Az érték nem lehet nagyobb, mint az Összeg!',
		error2: 'Az Összeget 1-gyel csökkenteni kell!',
		error3: 'Az értéket 1-gyel csökkenteni kell, ha nem félkiválasztva!',
		error4: 'Az értéknek 0,5-tel kell csökkennie, ha félkiválasztva!',
		error5: 'A szélesség vagy a magasság 20-nál kisebb, ami nehezíti a mobil eszközön történő kattintást!'
	},
	timePicker: {
		defaultTitle: 'Kérem válasszon',
		defaultCancel: 'Mégsem',
		defaultConfirm: 'Megerősít',
		defaultYear: 'Év',
		defaultMonth: 'Hónap',
		defaultDay: 'Nap',
		defaultHour: 'Óra',
		defaultMinute: 'Perc',
		defaultSecond: 'Másodperc'
	},
	calendar: {
		weekTextList: ['Hét', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat', 'Vasárnap'],
		weekSundayStartTextList: ['Vas', 'Hét', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat'],
		monthTextList: [
			'Január',
			'Február',
			'Március',
			'Április',
			'Május',
			'Június',
			'Július',
			'Augusztus',
			'Szeptember',
			'Október',
			'November',
			'December'
		],
		confirmText: 'Megerősít',
		selectedText: 'Kiválasztva',
		dayText: 'Nap',
		beforeText: 'Friss',
		afterText: 'Jövő',
		currentWeekText: 'Ezen a héten',
		currentMonthText: 'Ebben a hónapban',
		currentQuarterText: 'Ebben a negyedévben'
	}
};

export default hu_HU;



================================================
FILE: packages/stdf/src/lib/lang/hy_AM.ts
================================================
import type { LangProps } from './index.js';

const hy_AM: LangProps = {
	common: {
		slotEmpty: 'Մուտքագրման բույլերի պարամետրերը դատարկ են!',
		loading: 'Բեռնում...',
		noData: 'Ոչ մի տվյալ',
		noMoreData: 'Տվյալները ավելի չկան',
		done: 'Ավարտված'
	},
	actionSheet: {
		cancelText: 'Չեղարկել'
	},
	bottomSheet: {
		title: 'Գլխավորություն'
	},
	dialog: {
		title: 'Հիշողություն',
		content: 'Բոլոր բանալիներ՝',
		primaryText: 'Կատարել',
		secondaryText: 'Չեղարկել'
	},
	input: {
		pleaseInput: 'Խնդրում եմ մուտքագրել'
	},
	modal: {
		title: 'Վերնագիր',
		content: 'Բոլոր բանալիներ՝',
		btnText: 'Ես հասկացավի՞ք'
	},
	navBar: {
		title: 'Վերնագիր'
	},
	pagination: {
		defaultOnlyOnePage: 'Միայն մեկ էջ'
	},
	picker: {
		defaultTitle: 'Ընտրեք',
		defaultCancel: 'Չեղարկել',
		defaultConfirm: 'Կատարել'
	},
	asyncPicker: {
		defaultTitle: 'Ընտրեք',
		defaultCancel: 'Չեղարկել',
		defaultConfirm: 'Կատարել',
		defaultNext: 'Հաջորդը',
		defaultPrev: 'Նախորդը',
		defaultSelected: 'Ընտրված'
	},
	rate: {
		error1: 'Արժեքը չի կարող լինել Ընդհանուրից մեծանալուց!',
		error2: 'Պետք է Հետևանքը մեկով նվազել!',
		error3: 'Արժեքը պետք է մեկով նվազել, եթե կետը դեռևս ընտրված չէ!',
		error4: 'Արժեքը պետք է նվազել 0,5-ով, եթե կետը ընտրված է!',
		error5: 'Շարադաշտը կամ բույլերի բարձրությունը փոքր է 20-ից, որը դանդաղելի է շարադաշտերում!'
	},
	timePicker: {
		defaultTitle: 'Ընտրեք',
		defaultCancel: 'Չեղարկել',
		defaultConfirm: 'Կատարել',
		defaultYear: 'Տարի',
		defaultMonth: 'Ամիս',
		defaultDay: 'Օր',
		defaultHour: 'Ժամ',
		defaultMinute: 'Րոպե',
		defaultSecond: 'Վայրկյան'
	},
	calendar: {
		weekTextList: ['Հինգշաբթի', 'երկուշաբթի', 'երեքշաբթի', 'չորեքշաբթի', 'հինգշաբթի', 'ուրբաթ', 'շաբաթ'],
		weekSundayStartTextList: ['Կիր', 'Երկ', 'Երք', 'Չոր', 'Հնգ', 'Ուրբ', 'Շբթ'],
		monthTextList: [
			'Հունվար',
			'Փետրվար',
			'Մարտ',
			'Ապրիլ',
			'Մայիս',
			'Հունիս',
			'Հուլիս',
			'Օգոստոս',
			'Սեպտեմբեր',
			'Հոկտեմբեր',
			'Նոյեմբեր',
			'Դեկտեմբեր'
		],
		confirmText: 'Կատարել',
		selectedText: 'Ընտրված',
		dayText: 'Օր',
		beforeText: 'Անձնական',
		afterText: 'Առաջացած',
		currentWeekText: 'Այս շաբաթ',
		currentMonthText: 'Այս ամսվա մեջ',
		currentQuarterText: 'Այս եռամսյա մեջ'
	}
};

export default hy_AM;



================================================
FILE: packages/stdf/src/lib/lang/id_ID.ts
================================================
import type { LangProps } from './index.js';

const id_ID: LangProps = {
	common: {
		slotEmpty: 'Isi slot kosong!',
		loading: 'Sedang memuat...',
		noData: 'Tidak ada data',
		noMoreData: 'Tidak ada lagi data',
		done: 'Selesai'
	},
	actionSheet: {
		cancelText: 'Batal'
	},
	bottomSheet: {
		title: 'Judul'
	},
	dialog: {
		title: 'Petunjuk',
		content: 'Konten',
		primaryText: 'Konfirmasi',
		secondaryText: 'Batal'
	},
	input: {
		pleaseInput: 'Silakan masukkan'
	},
	modal: {
		title: 'Judul',
		content: 'Konten',
		btnText: 'Saya mengerti'
	},
	navBar: {
		title: 'Judul'
	},
	pagination: {
		defaultOnlyOnePage: 'Hanya satu halaman'
	},
	picker: {
		defaultTitle: 'Silakan pilih',
		defaultCancel: 'Batal',
		defaultConfirm: 'Konfirmasi'
	},
	asyncPicker: {
		defaultTitle: 'Silakan pilih',
		defaultCancel: 'Batal',
		defaultConfirm: 'Konfirmasi',
		defaultNext: 'Berikutnya',
		defaultPrev: 'Sebelumnya',
		defaultSelected: 'Terpilih'
	},
	rate: {
		error1: 'Nilai tidak boleh lebih besar dari Total!',
		error2: 'Total harus dikurangi 1!',
		error3: 'Nilai harus dikurangi 1 ketika tidak terpilih!',
		error4: 'Nilai harus dikurangi 0,5 ketika terpilih setengah!',
		error5: 'Lebar atau tinggi kurang dari 20, yang membuat klik pada terminal seluler sulit!'
	},
	timePicker: {
		defaultTitle: 'Silakan pilih',
		defaultCancel: 'Batal',
		defaultConfirm: 'Konfirmasi',
		defaultYear: 'Tahun',
		defaultMonth: 'Bulan',
		defaultDay: 'Hari',
		defaultHour: 'Jam',
		defaultMinute: 'Menit',
		defaultSecond: 'Kedua'
	},
	calendar: {
		weekTextList: ['Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab', 'Ming'],
		weekSundayStartTextList: ['Ming', 'Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab'],
		monthTextList: [
			'Januari',
			'Februari',
			'Maret',
			'April',
			'Mei',
			'Juni',
			'Juli',
			'Agustus',
			'September',
			'Oktober',
			'November',
			'Desember'
		],
		confirmText: 'Konfirmasi',
		selectedText: 'Terpilih',
		dayText: 'hari',
		beforeText: 'Terakhir',
		afterText: 'Masa depan',
		currentWeekText: 'Minggu Ini',
		currentMonthText: 'Bulan Ini',
		currentQuarterText: 'Kuartal Ini'
	}
};

export default id_ID;



================================================
FILE: packages/stdf/src/lib/lang/index.ts
================================================
export { default as ar_EG } from './ar_EG.js';
export { default as az_AZ } from './az_AZ.js';
export { default as bg_BG } from './bg_BG.js';
export { default as bn_BD } from './bn_BD.js';
export { default as ca_ES } from './ca_ES.js';
export { default as cs_CZ } from './cs_CZ.js';
export { default as da_DK } from './da_DK.js';
export { default as de_DE } from './de_DE.js';
export { default as el_GR } from './el_GR.js';
export { default as en_GB } from './en_GB.js';
export { default as en_US } from './en_US.js';
export { default as es_ES } from './es_ES.js';
export { default as et_EE } from './et_EE.js';
export { default as eu_ES } from './eu_ES.js';
export { default as fa_IR } from './fa_IR.js';
export { default as fi_FI } from './fi_FI.js';
export { default as fr_BE } from './fr_BE.js';
export { default as fr_CA } from './fr_CA.js';
export { default as fr_FR } from './fr_FR.js';
export { default as ga_IE } from './ga_IE.js';
export { default as gl_ES } from './gl_ES.js';
export { default as he_IL } from './he_IL.js';
export { default as hi_IN } from './hi_IN.js';
export { default as hr_HR } from './hr_HR.js';
export { default as hu_HU } from './hu_HU.js';
export { default as hy_AM } from './hy_AM.js';
export { default as id_ID } from './id_ID.js';
export { default as is_IS } from './is_IS.js';
export { default as it_IT } from './it_IT.js';
export { default as ja_JP } from './ja_JP.js';
export { default as ka_GE } from './ka_GE.js';
export { default as kk_KZ } from './kk_KZ.js';
export { default as km_KH } from './km_KH.js';
export { default as kmr_IQ } from './kmr_IQ.js';
export { default as kn_IN } from './kn_IN.js';
export { default as ko_KR } from './ko_KR.js';
export { default as lt_LT } from './lt_LT.js';
export { default as lv_LV } from './lv_LV.js';
export { default as mk_MK } from './mk_MK.js';
export { default as ml_IN } from './ml_IN.js';
export { default as mn_MN } from './mn_MN.js';
export { default as ms_MY } from './ms_MY.js';
export { default as nb_NO } from './nb_NO.js';
export { default as ne_NP } from './ne_NP.js';
export { default as nl_BE } from './nl_BE.js';
export { default as nl_NL } from './nl_NL.js';
export { default as pl_PL } from './pl_PL.js';
export { default as pt_BR } from './pt_BR.js';
export { default as pt_PT } from './pt_PT.js';
export { default as ro_RO } from './ro_RO.js';
export { default as ru_RU } from './ru_RU.js';
export { default as si_LK } from './si_LK.js';
export { default as sk_SK } from './sk_SK.js';
export { default as sl_SI } from './sl_SI.js';
export { default as sr_RS } from './sr_RS.js';
export { default as sv_SE } from './sv_SE.js';
export { default as ta_IN } from './ta_IN.js';
export { default as th_TH } from './th_TH.js';
export { default as tk_TK } from './tk_TK.js';
export { default as tr_TR } from './tr_TR.js';
export { default as uk_UA } from './uk_UA.js';
export { default as ur_PK } from './ur_PK.js';
export { default as vi_VN } from './vi_VN.js';
export { default as zh_CN } from './zh_CN.js';
export { default as zh_HK } from './zh_HK.js';
export { default as zh_TW } from './zh_TW.js';

export type LangProps = {
	common: {
		slotEmpty: string;
		loading: string;
		noData: string;
		noMoreData: string;
		done: string;
	};
	actionSheet: {
		cancelText: string;
	};
	bottomSheet: {
		title: string;
	};
	dialog: {
		title: string;
		content: string;
		primaryText: string;
		secondaryText: string;
	};
	input: {
		pleaseInput: string;
	};
	modal: {
		title: string;
		content: string;
		btnText: string;
	};
	navBar: {
		title: string;
	};
	pagination: {
		defaultOnlyOnePage: string;
	};
	picker: {
		defaultTitle: string;
		defaultCancel: string;
		defaultConfirm: string;
	};
	asyncPicker: {
		defaultTitle: string;
		defaultCancel: string;
		defaultConfirm: string;
		defaultNext: string;
		defaultPrev: string;
		defaultSelected: string;
	};
	rate: {
		error1: string;
		error2: string;
		error3: string;
		error4: string;
		error5: string;
	};
	timePicker: {
		defaultTitle: string;
		defaultCancel: string;
		defaultConfirm: string;
		defaultYear: string;
		defaultMonth: string;
		defaultDay: string;
		defaultHour: string;
		defaultMinute: string;
		defaultSecond: string;
	};
	calendar: {
		weekTextList: string[];
		weekSundayStartTextList: string[];
		monthTextList: string[];
		confirmText: string;
		selectedText: string;
		dayText: string;
		beforeText: string;
		afterText: string;
		currentWeekText: string;
		currentMonthText: string;
		currentQuarterText: string;
	};
};



================================================
FILE: packages/stdf/src/lib/lang/is_IS.ts
================================================
import type { LangProps } from './index.js';

const is_IS: LangProps = {
	common: {
		slotEmpty: 'Hlaða tómi!',
		loading: 'Hleður...',
		noData: 'Engin gögn',
		noMoreData: 'Engin fleiri gögn',
		done: 'Lokið'
	},
	actionSheet: {
		cancelText: 'Hætta við'
	},
	bottomSheet: {
		title: 'Titill'
	},
	dialog: {
		title: 'Ábending',
		content: 'Efni',
		primaryText: 'Staðfesta',
		secondaryText: 'Hætta við'
	},
	input: {
		pleaseInput: 'Vinsamlegast sláðu inn'
	},
	modal: {
		title: 'Titill',
		content: 'Efni',
		btnText: 'Ég skil'
	},
	navBar: {
		title: 'Titill'
	},
	pagination: {
		defaultOnlyOnePage: 'Aðeins ein síða'
	},
	picker: {
		defaultTitle: 'Veldu vinsamlegast',
		defaultCancel: 'Hætta við',
		defaultConfirm: 'Staðfesta'
	},
	asyncPicker: {
		defaultTitle: 'Veldu vinsamlegast',
		defaultCancel: 'Hætta við',
		defaultConfirm: 'Staðfesta',
		defaultNext: 'Næsta',
		defaultPrev: 'Fyrra',
		defaultSelected: 'Valinn'
	},
	rate: {
		error1: 'Gildið má ekki vera stærri en Heild!',
		error2: 'Heild verður þá breytt ef gildi sleppt er!',
		error3: 'Gildi verður breytt þegar það er ekki valið!',
		error4: 'Gildi verður breytt þegar það er valið að hálft!',
		error5: 'Breidd eða hæð minni en 20, sem gerir smella á fararmiða erfið á símanum!'
	},
	timePicker: {
		defaultTitle: 'Veldu vinsamlegast',
		defaultCancel: 'Hætta við',
		defaultConfirm: 'Staðfesta',
		defaultYear: 'Ár',
		defaultMonth: 'Mánuður',
		defaultDay: 'Dagur',
		defaultHour: 'Klst.',
		defaultMinute: 'Mín.',
		defaultSecond: 'Sek.'
	},
	calendar: {
		weekTextList: ['Mán', 'Þri', 'Mið', 'Fim', 'Fös', 'Lau', 'Sun'],
		weekSundayStartTextList: ['Sun', 'Mán', 'Þri', 'Mið', 'Fim', 'Fös', 'Lau'],
		monthTextList: ['Janúar', 'Febrúar', 'Mars', 'Apríl', 'Maí', 'Júní', 'Júlí', 'Ágúst', 'September', 'Október', 'Nóvember', 'Desember'],
		confirmText: 'Staðfesta',
		selectedText: 'Valinn',
		dayText: 'dagur',
		beforeText: 'Fyrir',
		afterText: 'Eftir',
		currentWeekText: 'Þessi vika',
		currentMonthText: 'Þessi mánuður',
		currentQuarterText: 'Þessi fjórðungur'
	}
};

export default is_IS;



================================================
FILE: packages/stdf/src/lib/lang/it_IT.ts
================================================
import type { LangProps } from './index.js';

const it_IT: LangProps = {
	common: {
		slotEmpty: 'Il contenuto dello slot è vuoto!',
		loading: 'Caricamento...',
		noData: 'Nessun dato',
		noMoreData: 'Non ci sono più dati',
		done: 'Fatto'
	},
	actionSheet: {
		cancelText: 'Annulla'
	},
	bottomSheet: {
		title: 'Titolo'
	},
	dialog: {
		title: 'Suggerimento',
		content: 'Contenuto',
		primaryText: 'Conferma',
		secondaryText: 'Annulla'
	},
	input: {
		pleaseInput: 'Si prega di inserire'
	},
	modal: {
		title: 'Titolo',
		content: 'Contenuto',
		btnText: 'Ho capito'
	},
	navBar: {
		title: 'Titolo'
	},
	pagination: {
		defaultOnlyOnePage: 'Solo una pagina'
	},
	picker: {
		defaultTitle: 'Si prega di scegliere',
		defaultCancel: 'Annulla',
		defaultConfirm: 'Conferma'
	},
	asyncPicker: {
		defaultTitle: 'Si prega di scegliere',
		defaultCancel: 'Annulla',
		defaultConfirm: 'Conferma',
		defaultNext: 'Successivo',
		defaultPrev: 'Precedente',
		defaultSelected: 'Selezionato'
	},
	rate: {
		error1: 'Il valore non può essere maggiore di Totale!',
		error2: 'Il Totale deve essere sottratto di 1!',
		error3: 'Il valore deve essere sottratto di 1 quando non selezionato!',
		error4: 'Il valore deve essere sottratto di 0,5 quando selezionato a metà!',
		error5: 'Larghezza o altezza inferiore a 20, rende difficoltoso il clic sul terminale mobile!'
	},
	timePicker: {
		defaultTitle: 'Si prega di scegliere',
		defaultCancel: 'Annulla',
		defaultConfirm: 'Conferma',
		defaultYear: 'Anno',
		defaultMonth: 'Mese',
		defaultDay: 'Giorno',
		defaultHour: 'Ora',
		defaultMinute: 'Minuto',
		defaultSecond: 'Secondo'
	},
	calendar: {
		weekTextList: ['Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab', 'Dom'],
		weekSundayStartTextList: ['Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab'],
		monthTextList: [
			'Gennaio',
			'Febbraio',
			'Marzo',
			'Aprile',
			'Maggio',
			'Giugno',
			'Luglio',
			'Agosto',
			'Settembre',
			'Ottobre',
			'Novembre',
			'Dicembre'
		],
		confirmText: 'Conferma',
		selectedText: 'Selezionato',
		dayText: 'giorno',
		beforeText: 'Recente',
		afterText: 'Futuro',
		currentWeekText: 'Questa settimana',
		currentMonthText: 'Questo mese',
		currentQuarterText: 'Questo trimestre'
	}
};

export default it_IT;



================================================
FILE: packages/stdf/src/lib/lang/ja_JP.ts
================================================
import type { LangProps } from './index.js';

const ja_JP: LangProps = {
	common: {
		slotEmpty: 'スロットの内容が空です！',
		loading: '読み込み中...',
		noData: 'データがありません',
		noMoreData: 'これ以上のデータはありません',
		done: '完了'
	},
	actionSheet: {
		cancelText: 'キャンセル'
	},
	bottomSheet: {
		title: 'タイトル'
	},
	dialog: {
		title: '注意',
		content: '内容',
		primaryText: '確認する',
		secondaryText: 'キャンセル'
	},
	input: {
		pleaseInput: '入力してください'
	},
	modal: {
		title: 'タイトル',
		content: '内容',
		btnText: '了解'
	},
	navBar: {
		title: 'タイトル'
	},
	pagination: {
		defaultOnlyOnePage: '1 ページのみ'
	},
	picker: {
		defaultTitle: '選んでください',
		defaultCancel: 'キャンセル',
		defaultConfirm: '確認'
	},
	asyncPicker: {
		defaultTitle: '選んでください',
		defaultCancel: 'キャンセル',
		defaultConfirm: '確認',
		defaultNext: '次へ',
		defaultPrev: '前へ',
		defaultSelected: '選択済み'
	},
	rate: {
		error1: 'value は total を上回ることはできません！',
		error2: 'total は 1 で割り切れる必要があります！',
		error3: '半選択時、value は 1 で割り切れる必要があります！',
		error4: '半選択時、value は 0.5 で割り切れる必要があります！',
		error5: 'width または height が 20 未満の場合、モバイル端末でのクリックが困難になる可能性があります！'
	},
	timePicker: {
		defaultTitle: '選んでください',
		defaultCancel: 'キャンセル',
		defaultConfirm: '確認',
		defaultYear: '年',
		defaultMonth: '月',
		defaultDay: '日',
		defaultHour: '時',
		defaultMinute: '分',
		defaultSecond: '秒'
	},
	calendar: {
		weekTextList: ['月', '火', '水', '木', '金', '土', '日'],
		weekSundayStartTextList: ['日', '月', '火', '水', '木', '金', '土'],
		monthTextList: ['1 月', '2 月', '3 月', '4 月', '5 月', '6 月', '7 月', '8 月', '9 月', '10 月', '11 月', '12 月'],
		confirmText: '確認',
		selectedText: '選択済み',
		dayText: '日',
		beforeText: '最近',
		afterText: '未来',
		currentWeekText: '今週',
		currentMonthText: '今月',
		currentQuarterText: '今四半期'
	}
};

export default ja_JP;



================================================
FILE: packages/stdf/src/lib/lang/ka_GE.ts
================================================
import type { LangProps } from './index.js';

const ka_GE: LangProps = {
	common: {
		slotEmpty: 'შიდა ლექში არის ცარიელი!',
		loading: 'იტვირთება...',
		noData: 'მონაცემები არ არის',
		noMoreData: 'არ არის უფრო მეტი მონაცემი',
		done: 'დასრულებულია'
	},
	actionSheet: {
		cancelText: 'გაუქმება'
	},
	bottomSheet: {
		title: 'სათაური'
	},
	dialog: {
		title: 'შეტყობინება',
		content: 'შინაარსი',
		primaryText: 'დადასტურება',
		secondaryText: 'გაუქმება'
	},
	input: {
		pleaseInput: 'შეიყვანეთ'
	},
	modal: {
		title: 'სათაური',
		content: 'შინაარსი',
		btnText: 'გაგეცემა'
	},
	navBar: {
		title: 'სათაური'
	},
	pagination: {
		defaultOnlyOnePage: 'მხოლოდ 1 გვერდი'
	},
	picker: {
		defaultTitle: 'აირჩიეთ',
		defaultCancel: 'გაუქმება',
		defaultConfirm: 'დადასტურება'
	},
	asyncPicker: {
		defaultTitle: 'აირჩიეთ',
		defaultCancel: 'გაუქმება',
		defaultConfirm: 'დადასტურება',
		defaultNext: 'შემდეგი',
		defaultPrev: 'წინა',
		defaultSelected: 'არჩეულია'
	},
	rate: {
		error1: 'value არ შეიძლება დაემატოს total-ზე!',
		error2: 'total-ის მნიშვნელობა უნდა 1-ით გაყოფილი იყოს!',
		error3: 'ნახეთ error2-ი!',
		error4: 'ნახეთ error2-ი!',
		error5:
			'სიგრძის ან სიმაღლის მნიშვნელობა 20-ზე ნაკლები შეიძლება ნაკლები ვიქნებოდეს, რაც მობილურ მოწყობილობებში ბადალაში დაკლიკების შესაძლებლობას უზრუნველყოფს!'
	},
	timePicker: {
		defaultTitle: 'აირჩიეთ',
		defaultCancel: 'გაუქმება',
		defaultConfirm: 'დადასტურება',
		defaultYear: 'წელი',
		defaultMonth: 'თვე',
		defaultDay: 'დღე',
		defaultHour: 'საათი',
		defaultMinute: 'წუთი',
		defaultSecond: 'წამი'
	},
	calendar: {
		weekTextList: ['ორ', 'სამ', 'ოთხ', 'ხუთ', 'პარ', 'შაბ', 'კვ'],
		weekSundayStartTextList: ['კვ', 'ორ', 'სამ', 'ოთხ', 'ხუთ', 'პარ', 'შაბ'],
		monthTextList: [
			'იანვარი',
			'თებერვალი',
			'მარტი',
			'აპრილი',
			'მაისი',
			'ივნისი',
			'ივლისი',
			'აგვისტო',
			'სექტემბერი',
			'ოქტომბერი',
			'ნოემბერი',
			'დეკემბერი'
		],
		confirmText: 'დადასტურება',
		selectedText: 'არჩეულია',
		dayText: 'დღე',
		beforeText: 'უახლესი',
		afterText: 'მომდევნო',
		currentWeekText: 'ამ კვირაში',
		currentMonthText: 'ამ თვეში',
		currentQuarterText: 'ამ კვარტალში'
	}
};

export default ka_GE;



================================================
FILE: packages/stdf/src/lib/lang/kk_KZ.ts
================================================
import type { LangProps } from './index.js';

const kk_KZ: LangProps = {
	common: {
		slotEmpty: 'Слот әдісі бос!',
		loading: 'Жүктеу...',
		noData: 'Деректер жоқ',
		noMoreData: 'Көбірек деректер жоқ',
		done: 'Аяқталды'
	},
	actionSheet: {
		cancelText: 'Болдырмау'
	},
	bottomSheet: {
		title: 'Тақырып'
	},
	dialog: {
		title: 'Ескерту',
		content: 'Мазмұн',
		primaryText: 'Растау',
		secondaryText: 'Болдырмау'
	},
	input: {
		pleaseInput: 'Құпия сөзді енгізіңіз'
	},
	modal: {
		title: 'Тақырып',
		content: 'Мазмұн',
		btnText: 'Көрдім'
	},
	navBar: {
		title: 'Тақырып'
	},
	pagination: {
		defaultOnlyOnePage: 'Тек 1 бет'
	},
	picker: {
		defaultTitle: 'Таңдаңыз',
		defaultCancel: 'Болдырмау',
		defaultConfirm: 'Растау'
	},
	asyncPicker: {
		defaultTitle: 'Таңдаңыз',
		defaultCancel: 'Болдырмау',
		defaultConfirm: 'Растау',
		defaultNext: 'Келесі',
		defaultPrev: 'Алдыңғы',
		defaultSelected: 'Таңдалған'
	},
	rate: {
		error1: 'Құны жиынтықтан үлкен болмауы тиіс!',
		error2: 'Құны жиынтықты 1-ге бөлу керек!',
		error3: 'Немесе-таңдалмаған жағдайында құны 1-ге бөлу керек!',
		error4: 'Немесе-бір орындамаған жағдайында құны 0,5 дейін бөлу керек!',
		error5: 'Ені-биіктігі 20-тен аз, мобильді терминалда түртіну және басу көзін арттыру мүмкіндігін қамтіды!'
	},
	timePicker: {
		defaultTitle: 'Таңдаңыз',
		defaultCancel: 'Болдырмау',
		defaultConfirm: 'Растау',
		defaultYear: 'Жыл',
		defaultMonth: 'Ай',
		defaultDay: 'Күн',
		defaultHour: 'Сағат',
		defaultMinute: 'Минут',
		defaultSecond: 'Секунд'
	},
	calendar: {
		weekTextList: ['Дс', 'Сс', 'Ср', 'Бс', 'Бс', 'Жм', 'Жк'],
		weekSundayStartTextList: ['Жк', 'Дс', 'Сс', 'Ср', 'Бс', 'Бс', 'Жм'],
		monthTextList: ['Қаңтар', 'Ақпан', 'Наурыз', 'Сәуір', 'Мамыр', 'Маусым', 'Шілде', 'Тамыз', 'Қыркүйек', 'Қазан', 'Қараша', 'Желтоқсан'],
		confirmText: 'Растау',
		selectedText: 'Таңдалды',
		dayText: 'күн',
		beforeText: 'соңғы',
		afterText: 'келесі',
		currentWeekText: 'Бұл апта',
		currentMonthText: 'Бұл ай',
		currentQuarterText: 'Бұл тоқсаны'
	}
};

export default kk_KZ;



================================================
FILE: packages/stdf/src/lib/lang/km_KH.ts
================================================
import type { LangProps } from './index.js';

const km_KH: LangProps = {
	common: {
		slotEmpty: 'គ្មានទិន្នន័យទេ។',
		loading: 'កំពុងផ្ទុកទិន្នន័យ ...',
		noData: 'គ្មានទិន្នន័យទេ',
		noMoreData: 'គ្មានទិន្នន័យផ្សេងទៀតទេ',
		done: 'ធ្វើរួចរាល់'
	},
	actionSheet: {
		cancelText: 'បោះបង់'
	},
	bottomSheet: {
		title: 'ចំណងជើង'
	},
	dialog: {
		title: 'សារ',
		content: 'មាតិកាពីរប់ពីវាលបរិបទ។',
		primaryText: 'យល់ព្រម',
		secondaryText: 'បោះបង់'
	},
	input: {
		pleaseInput: 'សូមបំពេញ'
	},
	modal: {
		title: 'ចំណងជើង',
		content: 'មាតិកាពីរប់ពីវាលបរិបទ',
		btnText: 'ផ្ដល់'
	},
	navBar: {
		title: 'ចំណងជើង'
	},
	pagination: {
		defaultOnlyOnePage: 'មានតែទំព័រមួយទំព័រប៉ុណ្ណោះ'
	},
	picker: {
		defaultTitle: 'ជ្រើសរើស',
		defaultCancel: 'បោះបង់',
		defaultConfirm: 'យល់ព្រម'
	},
	asyncPicker: {
		defaultTitle: 'ជ្រើសរើស',
		defaultCancel: 'បោះបង់',
		defaultConfirm: 'យល់ព្រម',
		defaultNext: 'បន្ទាប់',
		defaultPrev: 'មុន',
		defaultSelected: 'បានជ្រើសរើស'
	},
	rate: {
		error1: 'មិនអាចបន្ថែមតម្លៃទៅលើសរុបបានទេ!',
		error2: 'តម្លៃលើសសរុបគឺត្រូវតែស្មើនឹង ១',
		error3: 'មើល Error2!',
		error4: 'មើល Error2!',
		error5: 'ប្រវែងឬកម្រិតអតិបរិមាណ 20 ឬទាប់គ្នា អាចត្រូវបានខូចខាត ។ មាននៅក្នុងទូរស័ព្ទទំនេរ យ៉ាងតិចការស្វែងរកវាបានបញ្ចូល!'
	},
	timePicker: {
		defaultTitle: 'ជ្រើសរើស',
		defaultCancel: 'បោះបង់',
		defaultConfirm: 'យល់ព្រម',
		defaultYear: 'ឆ្នាំ',
		defaultMonth: 'ខែ',
		defaultDay: 'ថ្ងៃ',
		defaultHour: 'ម៉ោង',
		defaultMinute: 'នាទី',
		defaultSecond: 'វិនាទីទីមួយ'
	},
	calendar: {
		weekTextList: ['ចន្ទ', 'អង្គារ', 'ពុធ', 'ព្រហស្បតិ៖', 'សុក្រ', 'សៅរ៏', 'អាទិត្យ'],
		weekSundayStartTextList: ['អាទិត្យ', 'ចន្ទ', 'អង្គារ', 'ពុធ', 'ព្រហស្បតិ៖', 'សុក្រ', 'សៅរ៏'],
		monthTextList: ['មករា', 'កុម្ភៈ', 'មិនា', 'មេសា', 'ឧសភា', 'មិថុនា', 'កក្កដា', 'សីហាកុអ្វីស្រា', 'កញ្ញា', 'តុលា', 'វិច្ឆិកា', 'ធ្នូ'],
		confirmText: 'យល់ព្រម',
		selectedText: 'បានជ្រើសរើស',
		dayText: 'ថ្ងៃ',
		beforeText: 'មុន',
		afterText: 'បន្ទាប់',
		currentWeekText: 'សប្តាហ៍នេះ',
		currentMonthText: 'ខែនេះ',
		currentQuarterText: 'ត្រីមាសនេះ'
	}
};

export default km_KH;



================================================
FILE: packages/stdf/src/lib/lang/kmr_IQ.ts
================================================
import type { LangProps } from './index.js';

const kmr_IQ: LangProps = {
	common: {
		slotEmpty: 'Agahî tune',
		loading: 'Daxistin...',
		noData: 'Agahî tune',
		noMoreData: 'Agahî din tune',
		done: 'Têkildar'
	},
	actionSheet: {
		cancelText: 'Betalke'
	},
	bottomSheet: {
		title: 'Navnîş'
	},
	dialog: {
		title: 'Birêvebirin',
		content: 'Gotar ji her cihê.',
		primaryText: 'Bighîje',
		secondaryText: 'Betalke'
	},
	input: {
		pleaseInput: 'Ji kerema xwe bixwîne'
	},
	modal: {
		title: 'Nav',
		content: 'Gotar ji her cihê.',
		btnText: 'Bighîje'
	},
	navBar: {
		title: 'Nav'
	},
	pagination: {
		defaultOnlyOnePage: 'Tenê yek rûpel'
	},
	picker: {
		defaultTitle: 'Hilbijêre',
		defaultCancel: 'Betalke',
		defaultConfirm: 'Bighîje'
	},
	asyncPicker: {
		defaultTitle: 'Hilbijêre',
		defaultCancel: 'Betalke',
		defaultConfirm: 'Bighîje',
		defaultNext: 'Paşve',
		defaultPrev: 'Pêşve',
		defaultSelected: 'Hilbijandin'
	},
	rate: {
		error1: 'Em nikarin hîn bêtir star bidin!',
		error2: 'Starên ji xwe re dbê ne wek yek tê hesibandin!',
		error3: 'Di error2 de bifikirin!',
		error4: 'Di error2 de bifikirin!',
		error5: 'Di telefonê we de dê klavyeya we jorîn û nîqaşan jî bi rê ve bibe!'
	},
	timePicker: {
		defaultTitle: 'Hilbijêre',
		defaultCancel: 'Betalke',
		defaultConfirm: 'Bighîje',
		defaultYear: 'Sal',
		defaultMonth: 'Meh',
		defaultDay: 'Roj',
		defaultHour: 'Seet',
		defaultMinute: 'Daqîqey',
		defaultSecond: 'Second'
	},
	calendar: {
		weekTextList: ['Yekşem', 'Duşem', 'Sêşem', 'Çarşem', 'Pêncşem', 'În', 'Şemî'],
		weekSundayStartTextList: ['Şemî', 'Yekşem', 'Duşem', 'Sêşem', 'Çarşem', 'Pêncşem', 'În'],
		monthTextList: [
			'Rêbendan',
			'Gulan',
			'Hezîran',
			'Tîrmeh',
			'Tebax',
			'Tîrmeh',
			'Tebax',
			'Rezber',
			'Kewçêr',
			'Serewend',
			'Mijdar',
			'Kanûn'
		],
		confirmText: 'Bighîje',
		selectedText: 'Hilbijandin',
		dayText: 'Roj',
		beforeText: 'Pêve',
		afterText: 'Pêş',
		currentWeekText: 'Ji bo herî dawî ji bo asta',
		currentMonthText: 'Ji bo herî dawî ji bo asta',
		currentQuarterText: 'Ji bo herî dawî ji bo asta'
	}
};

export default kmr_IQ;



================================================
FILE: packages/stdf/src/lib/lang/kn_IN.ts
================================================
import type { LangProps } from './index.js';

const kn_IN: LangProps = {
	common: {
		slotEmpty: 'ಸ್ಲಾಟ್ ಖಾಲಿಯಾಗಿದೆ!',
		loading: 'ಲೋಡ್ ಆಗುತ್ತಿದೆ...',
		noData: 'ಡೇಟಾ ಇಲ್ಲ',
		noMoreData: 'ಹೆಚ್ಚು ಡೇಟಾ ಇಲ್ಲ',
		done: 'ಮುಗಿದಿದೆ'
	},
	actionSheet: {
		cancelText: 'ರದ್ದುಮಾಡಿ'
	},
	bottomSheet: {
		title: 'ಶೀರ್ಷಿಕೆ'
	},
	dialog: {
		title: 'ಎಚ್ಚರಿಕೆ',
		content: 'ವಿಷಯ',
		primaryText: 'ಪ್ರಾಥಮಿಕ',
		secondaryText: 'ರದ್ದುಪಡಿಸಿ'
	},
	input: {
		pleaseInput: 'ದಯವಿಟ್ಟು ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ನಮೂದಿಸಿ'
	},
	modal: {
		title: 'ಶೀರ್ಷಿಕೆ',
		content: 'ವಿಷಯ',
		btnText: 'ಗ್ರಹಿಸಿ'
	},
	navBar: {
		title: 'ಶೀರ್ಷಿಕೆ'
	},
	pagination: {
		defaultOnlyOnePage: 'ಒಂದು ಪುಟ ಮಾತ್ರ'
	},
	picker: {
		defaultTitle: 'ಆಯ್ಕೆ ಮಾಡಿ',
		defaultCancel: 'ರದ್ದುಮಾಡಿ',
		defaultConfirm: 'ದೃಢೀಕರಿಸು'
	},
	asyncPicker: {
		defaultTitle: 'ಆಯ್ಕೆ ಮಾಡಿ',
		defaultCancel: 'ರದ್ದುಮಾಡಿ',
		defaultConfirm: 'ದೃಢೀಕರಿಸು',
		defaultNext: 'ಮುಂದಿನ',
		defaultPrev: 'ಹಿಂದಿನ',
		defaultSelected: 'ಆಯ್ಕೆಯಾಗಿದೆ'
	},
	rate: {
		error1: 'ಮೊತ್ತವನ್ನು ಕಡಿಮೆಗೊಳಿಸಿ!',
		error2: 'ಮೊತ್ತವನ್ನು 1 ನಿಂದ ವಿಭಜಿಸಬೇಕು!',
		error3: 'ಅಥವಾ ಅನುಸ್ತಾಪಿಸಲಾಗದ ಸಂದರ್ಭದಲ್ಲಿ, ಮೊತ್ತವನ್ನು 1 ನಿಂದ ವಿಭಜಿಸಬೇಕು!',
		error4: 'ಅಥವಾ ಒಂದು ಸ್ಥಾನವನ್ನು ನೀಡಬೇಕಾದ ಸಂದರ್ಭದಲ್ಲಿ, ಮೊತ್ತವನ್ನು 0.5 ರವರೆಗೆ ವಿಭಜಿಸಬೇಕು!',
		error5: 'ಗಾತ್ರದ ಅಳತೆ 20 ಕ್ಕಿಂತ ಕಡಿಮೆಯಿರಬೇಕು, ಮೊಬೈಲ್ ಟೆರ್ಮಿನಲ್‌ನಲ್ಲಿ ಗುರುತಿಸುವುದು ಮತ್ತು ನೀರ್ಗಲ್ಲಿನ ಮೂಲಕ ಬೇಯಿಸುವುದು ಸಾಧ್ಯವಿಲ್ಲ!'
	},
	timePicker: {
		defaultTitle: 'ಆಯ್ದಿಸಿ',
		defaultCancel: 'ರದ್ದುಮಾಡಿ',
		defaultConfirm: 'ದೃಢೀಕರಿಸು',
		defaultYear: 'ವರ್ಷ',
		defaultMonth: 'ತಿಂಗಳು',
		defaultDay: 'ದಿನ',
		defaultHour: 'ಘಂಟೆ',
		defaultMinute: 'ನಿಮಿಷ',
		defaultSecond: 'ಸೆಕೆಂಡ್'
	},
	calendar: {
		weekTextList: ['ಭಾನು', 'ಸೋಮ', 'ಮಂಗಳ', 'ಬುಧ', 'ಗುರು', 'ಶುಕ್ರ', 'ಶನಿ'],
		weekSundayStartTextList: ['ಶನಿ', 'ಭಾನು', 'ಸೋಮ', 'ಮಂಗಳ', 'ಬುಧ', 'ಗುರು', 'ಶುಕ್ರ'],
		monthTextList: [
			'ಜನವರಿ',
			'ಫೆಬ್ರವರಿ',
			'ಮಾರ್ಚ್',
			'ಏಪ್ರಿಲ್',
			'ಮೇ',
			'ಜೂನ್',
			'ಜುಲೈ',
			'ಆಗಸ್ಟ್',
			'ಸೆಪ್ಟೆಂಬರ್',
			'ಅಕ್ಟೋಬರ್',
			'ನವೆಂಬರ್',
			'ಡಿಸೆಂಬರ್'
		],
		confirmText: 'ದೃಢೀಕರಿಸು',
		selectedText: 'ಆಯ್ದಲ್ಲಿದೆ',
		dayText: 'ದಿನ',
		beforeText: 'ಕೊನೆಯದೊಂದು',
		afterText: 'ಮುಂದೆ',
		currentWeekText: 'ಈ ವಾರ',
		currentMonthText: 'ಈ ತಿಂಗಳು',
		currentQuarterText: 'ಈ ತ್ರೈಮಾಸಿಕ'
	}
};

export default kn_IN;



================================================
FILE: packages/stdf/src/lib/lang/ko_KR.ts
================================================
import type { LangProps } from './index.js';

const ko_KR: LangProps = {
	common: {
		slotEmpty: '슬롯이 비어 있습니다!',
		loading: '로딩 중...',
		noData: '데이터가 없습니다',
		noMoreData: '데이터가 더 이상 없습니다',
		done: '완료'
	},
	actionSheet: {
		cancelText: '취소'
	},
	bottomSheet: {
		title: '제목'
	},
	dialog: {
		title: '경고',
		content: '내용',
		primaryText: '확인',
		secondaryText: '취소'
	},
	input: {
		pleaseInput: '비밀번호를 입력해주세요'
	},
	modal: {
		title: '제목',
		content: '내용',
		btnText: '확인'
	},
	navBar: {
		title: '제목'
	},
	pagination: {
		defaultOnlyOnePage: '한 페이지만 있습니다'
	},
	picker: {
		defaultTitle: '선택해주세요',
		defaultCancel: '취소',
		defaultConfirm: '확인'
	},
	asyncPicker: {
		defaultTitle: '선택해주세요',
		defaultCancel: '취소',
		defaultConfirm: '확인',
		defaultNext: '다음',
		defaultPrev: '이전',
		defaultSelected: '선택됨'
	},
	rate: {
		error1: '합계를 감소시키십시오!',
		error2: '합계를 1 로 나누십시오!',
		error3: '또는 합계를 1 로 나눌 수 없는 경우',
		error4: '또는 값이 0.5 미만인 경우!',
		error5: '측정 값은 20 보다 작아야합니다. 모바일 단말기에서 식별하거나 물을 통해 측정할 수 없습니다!'
	},
	timePicker: {
		defaultTitle: '선택해주세요',
		defaultCancel: '취소',
		defaultConfirm: '확인',
		defaultYear: '년',
		defaultMonth: '월',
		defaultDay: '일',
		defaultHour: '시간',
		defaultMinute: '분',
		defaultSecond: '초'
	},
	calendar: {
		weekTextList: ['일', '월', '화', '수', '목', '금', '토'],
		weekSundayStartTextList: ['토', '일', '월', '화', '수', '목', '금'],
		monthTextList: ['1 월', '2 월', '3 월', '4 월', '5 월', '6 월', '7 월', '8 월', '9 월', '10 월', '11 월', '12 월'],
		confirmText: '확인',
		selectedText: '선택됨',
		dayText: '일',
		beforeText: '이전',
		afterText: '이후',
		currentWeekText: '이번 주',
		currentMonthText: '이번 달',
		currentQuarterText: '이번 분기'
	}
};

export default ko_KR;



================================================
FILE: packages/stdf/src/lib/lang/lt_LT.ts
================================================
import type { LangProps } from './index.js';

const lt_LT: LangProps = {
	common: {
		slotEmpty: 'Slotas tuščias!',
		loading: 'Įkeliama...',
		noData: 'Nėra duomenų',
		noMoreData: 'Daugiau duomenų nėra',
		done: 'Atlikta'
	},
	actionSheet: {
		cancelText: 'Atšaukti'
	},
	bottomSheet: {
		title: 'Pavadinimas'
	},
	dialog: {
		title: 'Įspėjimas',
		content: 'Turinys',
		primaryText: 'Patvirtinti',
		secondaryText: 'Atšaukti'
	},
	input: {
		pleaseInput: 'Įveskite slaptažodį'
	},
	modal: {
		title: 'Pavadinimas',
		content: 'Turinys',
		btnText: 'Patvirtinti'
	},
	navBar: {
		title: 'Pavadinimas'
	},
	pagination: {
		defaultOnlyOnePage: 'Tik vienas puslapis'
	},
	picker: {
		defaultTitle: 'Pasirinkite',
		defaultCancel: 'Atšaukti',
		defaultConfirm: 'Patvirtinti'
	},
	asyncPicker: {
		defaultTitle: 'Pasirinkite',
		defaultCancel: 'Atšaukti',
		defaultConfirm: 'Patvirtinti',
		defaultNext: 'Kitas',
		defaultPrev: 'Ankstesnis',
		defaultSelected: 'Pasirinkta'
	},
	rate: {
		error1: 'Suma mažesnė už sumą!',
		error2: 'Suma negali būti padalyta iš 1!',
		error3: 'Arba suma negali būti padalyta iš 1',
		error4: 'Arba vertė yra mažesnė nei 0,5!',
		error5: 'Matavimo vertė turi būti mažesnė nei 20. Ją sunku nustatyti naudojant mobilųjį įrenginį arba per vandenį!'
	},
	timePicker: {
		defaultTitle: 'Pasirinkite',
		defaultCancel: 'Atšaukti',
		defaultConfirm: 'Patvirtinti',
		defaultYear: 'Metai',
		defaultMonth: 'Mėnesis',
		defaultDay: 'Diena',
		defaultHour: 'Valanda',
		defaultMinute: 'Minutė',
		defaultSecond: 'Sekundė'
	},
	calendar: {
		weekTextList: ['Se', 'Pr', 'An', 'Tr', 'Ke', 'Pe', 'Še'],
		weekSundayStartTextList: ['Še', 'Pr', 'An', 'Tr', 'Ke', 'Pe', 'Se'],
		monthTextList: [
			'Sausio',
			'Vasario',
			'Kovo',
			'Balandžio',
			'Gegužės',
			'Birželio',
			'Liepos',
			'Rugpjūčio',
			'Rugsėjo',
			'Spalio',
			'Lapkričio',
			'Gruodžio'
		],
		confirmText: 'Patvirtinti',
		selectedText: 'Pasirinkta',
		dayText: 'Di',
		beforeText: 'Ankstesnė',
		afterText: 'Sekanti',
		currentWeekText: 'Ši savaitė',
		currentMonthText: 'Šis mėnuo',
		currentQuarterText: 'Šis ketvirtis'
	}
};

export default lt_LT;



================================================
FILE: packages/stdf/src/lib/lang/lv_LV.ts
================================================
import type { LangProps } from './index.js';

const lv_LV: LangProps = {
	common: {
		slotEmpty: 'Slots ir tukšs!',
		loading: 'Ielādē...',
		noData: 'Nav datu',
		noMoreData: 'Nav vairāk datu',
		done: 'Pabeigts'
	},
	actionSheet: {
		cancelText: 'Atcelt'
	},
	bottomSheet: {
		title: 'Nosaukums'
	},
	dialog: {
		title: 'Brīdinājums',
		content: 'Saturs',
		primaryText: 'Apstiprināt',
		secondaryText: 'Atcelt'
	},
	input: {
		pleaseInput: 'Lūdzu, ievadiet paroli'
	},
	modal: {
		title: 'Nosaukums',
		content: 'Saturs',
		btnText: 'Apstiprināt'
	},
	navBar: {
		title: 'Nosaukums'
	},
	pagination: {
		defaultOnlyOnePage: 'Tikai viena lapa'
	},
	picker: {
		defaultTitle: 'Izvēlieties',
		defaultCancel: 'Atcelt',
		defaultConfirm: 'Apstiprināt'
	},
	asyncPicker: {
		defaultTitle: 'Izvēlieties',
		defaultCancel: 'Atcelt',
		defaultConfirm: 'Apstiprināt',
		defaultNext: 'Nākamais',
		defaultPrev: 'Iepriekšējais',
		defaultSelected: 'Izvēlēts'
	},
	rate: {
		error1: 'Summa ir mazāka par summu!',
		error2: 'Summu nevar dalīt ar 1!',
		error3: 'Vai arī summu nevar dalīt ar 1',
		error4: 'Vai vertība ir mazāka par 0,5!',
		error5: 'Mērījuma vērtībai jābūt mazākai par 20. To ir grūti noteikt, izmantojot mobilos ierīces vai caur ūdeni!'
	},
	timePicker: {
		defaultTitle: 'Izvēlieties',
		defaultCancel: 'Atcelt',
		defaultConfirm: 'Apstiprināt',
		defaultYear: 'Gads',
		defaultMonth: 'Mēnesis',
		defaultDay: 'Diena',
		defaultHour: 'Stunda',
		defaultMinute: 'Minūte',
		defaultSecond: 'Sekunde'
	},
	calendar: {
		weekTextList: ['Sv', 'Pr', 'Ot', 'Tr', 'Ce', 'Pk', 'Se'],
		weekSundayStartTextList: ['Se', 'Pr', 'Ot', 'Tr', 'Ce', 'Pk', 'Sv'],
		monthTextList: [
			'Janvāris',
			'Februāris',
			'Marts',
			'Aprīlis',
			'Maijs',
			'Jūnijs',
			'Jūlijs',
			'Augusts',
			'Septembris',
			'Oktobris',
			'Novembris',
			'Decembris'
		],
		confirmText: 'Apstiprināt',
		selectedText: 'Izvēlētais',
		dayText: 'Di',
		beforeText: 'Iepriekšējais',
		afterText: 'Nākamais',
		currentWeekText: 'Šonedēļ',
		currentMonthText: 'Šomēnes',
		currentQuarterText: 'Šajā ceturksnī'
	}
};

export default lv_LV;



================================================
FILE: packages/stdf/src/lib/lang/mk_MK.ts
================================================
import type { LangProps } from './index.js';

const mk_MK: LangProps = {
	common: {
		slotEmpty: 'Слотот е празен!',
		loading: 'Вчитување...',
		noData: 'Нема податоци',
		noMoreData: 'Нема повеќе податоци',
		done: 'Завршено'
	},
	actionSheet: {
		cancelText: 'Откажи'
	},
	bottomSheet: {
		title: 'Наслов'
	},
	dialog: {
		title: 'Предупредување',
		content: 'Содржина',
		primaryText: 'Потврди',
		secondaryText: 'Откажи'
	},
	input: {
		pleaseInput: 'Внесете лозинка'
	},
	modal: {
		title: 'Наслов',
		content: 'Содржина',
		btnText: 'Потврди'
	},
	navBar: {
		title: 'Наслов'
	},
	pagination: {
		defaultOnlyOnePage: 'Само една страница'
	},
	picker: {
		defaultTitle: 'Избери',
		defaultCancel: 'Откажи',
		defaultConfirm: 'Потврди'
	},
	asyncPicker: {
		defaultTitle: 'Избери',
		defaultCancel: 'Откажи',
		defaultConfirm: 'Потврди',
		defaultNext: 'Следно',
		defaultPrev: 'Претходно',
		defaultSelected: 'Избрано'
	},
	rate: {
		error1: 'Сумата е помала од дозволената предност!',
		error2: 'Сумата не може да биде делива со 1!',
		error3: 'Во спротивно, сумата не може да биде делива со 1',
		error4: 'Или вредноста е помала од 0,5!',
		error5: 'Мерната вредност мора да биде помала од 20. Тоа е тешко да се одреди со мобилен уред или преку вода!'
	},
	timePicker: {
		defaultTitle: 'Избери',
		defaultCancel: 'Откажи',
		defaultConfirm: 'Потврди',
		defaultYear: 'Година',
		defaultMonth: 'Месец',
		defaultDay: 'Ден',
		defaultHour: 'Час',
		defaultMinute: 'Минута',
		defaultSecond: 'Секунда'
	},
	calendar: {
		weekTextList: ['Не', 'По', 'Вт', 'Ср', 'Че', 'Пе', 'Сабота'],
		weekSundayStartTextList: ['Сабота', 'Не', 'По', 'Вт', 'Ср', 'Че', 'Пе'],
		monthTextList: [
			'Јануари',
			'Февруари',
			'Март',
			'Април',
			'Мај',
			'Јуни',
			'Јули',
			'Август',
			'Септември',
			'Октомври',
			'Ноември',
			'Декември'
		],
		confirmText: 'Потврди',
		selectedText: 'Избрано',
		dayText: 'Ден',
		beforeText: 'Претходно',
		afterText: 'Следно',
		currentWeekText: 'Оваа недела',
		currentMonthText: 'Овој месец',
		currentQuarterText: 'Оваа тромесечје'
	}
};

export default mk_MK;



================================================
FILE: packages/stdf/src/lib/lang/ml_IN.ts
================================================
import type { LangProps } from './index.js';

const ml_IN: LangProps = {
	common: {
		slotEmpty: 'സ്ലോട്ട് ശൂന്യമാണ്!',
		loading: 'ലോഡുചെയ്യുന്നു...',
		noData: 'ഡാറ്റായില്ല',
		noMoreData: 'കൂടുതൽ ഡാറ്റാ ഇല്ല',
		done: 'ചെയ്തു'
	},
	actionSheet: {
		cancelText: 'റദ്ദാക്കുക'
	},
	bottomSheet: {
		title: 'ശീർഷകം'
	},
	dialog: {
		title: 'മുന്നറിയിപ്പ്',
		content: 'ഉള്ളടക്കം',
		primaryText: 'സ്ഥിരീകരിക്കുക',
		secondaryText: 'റദ്ദാക്കുക'
	},
	input: {
		pleaseInput: 'പാസ്സ്വേഡ് നൽകുക'
	},
	modal: {
		title: 'ശീർഷകം',
		content: 'ഉള്ളടക്കം',
		btnText: 'സ്ഥിരീകരിക്കുക'
	},
	navBar: {
		title: 'ശീർഷകം'
	},
	pagination: {
		defaultOnlyOnePage: 'ഒരു പേജ് മാത്രം'
	},
	picker: {
		defaultTitle: 'തിരഞ്ഞെടുക്കുക',
		defaultCancel: 'റദ്ദാക്കുക',
		defaultConfirm: 'സ്ഥിരീകരിക്കുക'
	},
	asyncPicker: {
		defaultTitle: 'തിരഞ്ഞെടുക്കുക',
		defaultCancel: 'റദ്ദാക്കുക',
		defaultConfirm: 'സ്ഥിരീകരിക്കുക',
		defaultNext: 'അടുത്തത്',
		defaultPrev: 'മുന്നത്തെ',
		defaultSelected: 'തിരഞ്ഞെടുത്തു'
	},
	rate: {
		error1: 'മൊത്തം പ്രധാനതയും കുറഞ്ഞ പ്രധാനതയിൽ കൂടാതെ ആണ്!',
		error2: 'മൂല്യം 1 നോക്കിയാൽ പൂർണ്ണമായി നിർണ്ണയിക്കാം എന്നില്ല!',
		error3: 'പൂർണ്ണമായോ അല്ലാതെ മൂല്യം 1 നോക്കുക എന്നില്ല',
		error4: 'അല്പം കൂടാതെ മൂല്യം 0.5 നോക്കുക!',
		error5:
			'കമ്പെർസർ ഇടയ്ക്കാൾ വിളിക്കുന്ന മൊത്തം 20 കൂടുതലാണ്. മൊബൈൽ ഉപകരണങ്ങളോടും ഉൾനാടൻ ഉപകരണങ്ങളോടും അതു പുലർത്തിയിട്ടുള്ളതായിരിക്കും!'
	},
	timePicker: {
		defaultTitle: 'തിരഞ്ഞെടുക്കുക',
		defaultCancel: 'റദ്ദാക്കുക',
		defaultConfirm: 'സ്ഥിരീകരിക്കുക',
		defaultYear: 'വർഷം',
		defaultMonth: 'മാസം',
		defaultDay: 'ദിവസം',
		defaultHour: 'മണിക്കൂർ',
		defaultMinute: 'മിനിറ്റ്',
		defaultSecond: 'സെക്കൻഡ്'
	},
	calendar: {
		weekTextList: ['ഞായർ', 'തിങ്കൾ', 'ചൊവ്വ', 'ബുധൻ', 'വ്യാഴം', 'വെള്ളി', 'ശനി'],
		weekSundayStartTextList: ['ശനി', 'ഞായർ', 'തിങ്കൾ', 'ചൊവ്വ', 'ബുധൻ', 'വ്യാഴം', 'വെള്ളി'],
		monthTextList: [
			'ജനുവരി',
			'ഫെബ്രുവരി',
			'മാർച്ച്',
			'ഏപ്രിൽ',
			'മേയ്',
			'ജൂൺ',
			'ജൂലൈ',
			'ഓഗസ്റ്റ്',
			'സെപ്റ്റംബർ',
			'ഒക്ടോബർ',
			'നവംബർ',
			'ഡിസംബർ'
		],
		confirmText: 'സ്ഥിരീകരിക്കുക',
		selectedText: 'തിരഞ്ഞെടുത്തത്',
		dayText: 'ദിവസം',
		beforeText: 'മുമ്പത്തെ',
		afterText: 'പിന്നിടുന്നു',
		currentWeekText: 'ഈ ആഴ്ച',
		currentMonthText: 'ഈ മാസം',
		currentQuarterText: 'ഈ ക്വാർട്ടർ'
	}
};

export default ml_IN;



================================================
FILE: packages/stdf/src/lib/lang/mn_MN.ts
================================================
import type { LangProps } from './index.js';

const mn_MN: LangProps = {
	common: {
		slotEmpty: 'Слот хоосон байна!',
		loading: 'Уншиж байна ...',
		noData: 'Өгөгдөл байхгүй байна',
		noMoreData: 'Дараагийн өгөгдөл байхгүй байна',
		done: 'Дууссан'
	},
	actionSheet: {
		cancelText: 'Цуцлах'
	},
	bottomSheet: {
		title: 'Гарчиг'
	},
	dialog: {
		title: 'Санал хүсэлт',
		content: 'Агуулга',
		primaryText: 'Захиалах',
		secondaryText: 'Цуцлах'
	},
	input: {
		pleaseInput: 'Нууц үгээ оруулна уу'
	},
	modal: {
		title: 'Гарчиг',
		content: 'Агуулга',
		btnText: 'Батлах'
	},
	navBar: {
		title: 'Гарчиг'
	},
	pagination: {
		defaultOnlyOnePage: 'Зөвхөн 1-р хуудас'
	},
	picker: {
		defaultTitle: 'Сонгох',
		defaultCancel: 'Цуцлах',
		defaultConfirm: 'Батлах'
	},
	asyncPicker: {
		defaultTitle: 'Сонгох',
		defaultCancel: 'Цуцлах',
		defaultConfirm: 'Батлах',
		defaultNext: 'Дараагийн',
		defaultPrev: 'Өмнөх',
		defaultSelected: 'Сонгосон'
	},
	rate: {
		error1: 'Нийт түрээсийн тооны улмаас бага байх боломжгүй!',
		error2: 'Үнэлгээ 1-ээс их аль болохгүй!',
		error3: '1-ын үнэлгээр хангах эсвэл үнэлэхийн тулд үнэлгээгүй байх ёстой',
		error4: 'Удаан тохиолдолд 0.5-с ихгүй үнэлгээтэй байх ёстой!',
		error5:
			'Компьютер ашиглахад үр дүнг 20-с ихгүй гаргаж болохгүй. Мобайл эсвэл тухайн оронд ашиглах үйлчилгээний үзүүлэлтүүд дээрээ багтын сайн сайхныг анхаарна уу!'
	},
	timePicker: {
		defaultTitle: 'Сонгох',
		defaultCancel: 'Цуцлах',
		defaultConfirm: 'Батлах',
		defaultYear: 'Жил',
		defaultMonth: 'Сар',
		defaultDay: 'Өдөр',
		defaultHour: 'Цаг',
		defaultMinute: 'Минут',
		defaultSecond: 'Секунд'
	},
	calendar: {
		weekTextList: ['Даваа', 'Мягмар', 'Лхагва', 'Пүрэв', 'Баасан', 'Бямба', 'Ням'],
		weekSundayStartTextList: ['Ням', 'Даваа', 'Мягмар', 'Лхагва', 'Пүрэв', 'Баасан', 'Бямба'],
		monthTextList: ['Хулгана', 'Үхэр', 'Бар', 'Туулай', 'Луу', 'Могой', 'Морь', 'Найман', 'Ес', 'Арваннэгүүд', 'Арванхоёр', 'Арвангахай'],
		confirmText: 'Батлах',
		selectedText: 'Сонгосон',
		dayText: 'Өдөр',
		beforeText: 'Өмнөх',
		afterText: 'Дараах',
		currentWeekText: 'Энэ долоо хоног',
		currentMonthText: 'Энэ сар',
		currentQuarterText: 'Энэ улирал'
	}
};

export default mn_MN;



================================================
FILE: packages/stdf/src/lib/lang/ms_MY.ts
================================================
import type { LangProps } from './index.js';

const ms_MY: LangProps = {
	common: {
		slotEmpty: 'Ruang kosong!',
		loading: 'Membaca ...',
		noData: 'Tiada data',
		noMoreData: 'Tiada lagi data',
		done: 'Selesai'
	},
	actionSheet: {
		cancelText: 'Batal'
	},
	bottomSheet: {
		title: 'Tajuk'
	},
	dialog: {
		title: 'Permintaan',
		content: 'Kandungan',
		primaryText: 'Tempah',
		secondaryText: 'Batal'
	},
	input: {
		pleaseInput: 'Sila masukkan kata laluan'
	},
	modal: {
		title: 'Tajuk',
		content: 'Kandungan',
		btnText: 'Tetapkan'
	},
	navBar: {
		title: 'Tajuk'
	},
	pagination: {
		defaultOnlyOnePage: 'Hanya satu halaman'
	},
	picker: {
		defaultTitle: 'Pilih',
		defaultCancel: 'Batal',
		defaultConfirm: 'Sahkan'
	},
	asyncPicker: {
		defaultTitle: 'Pilih',
		defaultCancel: 'Batal',
		defaultConfirm: 'Sahkan',
		defaultNext: 'Seterusnya',
		defaultPrev: 'Sebelumnya',
		defaultSelected: 'Dipilih'
	},
	rate: {
		error1: 'Nilai Rating tidak boleh lebih rendah daripada jumlah kelajuan!',
		error2: 'Komen tidak boleh diikat kepada satu bintang!',
		error3: 'Komen atau rating perlu diisi',
		error4: 'Rating perlu diberikan setidaknya setengah bintang!',
		error5:
			'Komputer tidak dapat melaksanakan rating noreview yang lebih besar dari 20, gunakan aplikasi pembantu pada telefon bimbit atau periksa kembali perkhidmatan yang anda gunakan!'
	},
	timePicker: {
		defaultTitle: 'Pilih',
		defaultCancel: 'Batal',
		defaultConfirm: 'Sahkan',
		defaultYear: 'Tahun',
		defaultMonth: 'Bulan',
		defaultDay: 'Hari',
		defaultHour: 'Jam',
		defaultMinute: 'Minit',
		defaultSecond: 'Saat'
	},
	calendar: {
		weekTextList: ['Isnin', 'Selasa', 'Rabu', 'Khamis', 'Jumaat', 'Sabtu', 'Ahad'],
		weekSundayStartTextList: ['Ahad', 'Isnin', 'Selasa', 'Rabu', 'Khamis', 'Jumaat', 'Sabtu'],
		monthTextList: ['Januari', 'Februari', 'Mac', 'April', 'Mei', 'Jun', 'Julai', 'Ogos', 'September', 'Oktober', 'November', 'Disember'],
		confirmText: 'Sahkan',
		selectedText: 'Dipilih',
		dayText: 'Hari',
		beforeText: 'Sebelum',
		afterText: 'Selepas',
		currentWeekText: 'Minggu ini',
		currentMonthText: 'Bulan ini',
		currentQuarterText: 'Suku Tahun Ini'
	}
};

export default ms_MY;



================================================
FILE: packages/stdf/src/lib/lang/nb_NO.ts
================================================
import type { LangProps } from './index.js';

const nb_NO: LangProps = {
	common: {
		slotEmpty: 'Innholdet i sporet er tomt!',
		loading: 'Laster...',
		noData: 'Ingen data',
		noMoreData: 'Ingen flere data',
		done: 'Ferdig'
	},
	actionSheet: {
		cancelText: 'Avbryt'
	},
	bottomSheet: {
		title: 'Tittel'
	},
	dialog: {
		title: 'Hint',
		content: 'Innhold',
		primaryText: 'Bekreft',
		secondaryText: 'Avbryt'
	},
	input: {
		pleaseInput: 'Vennligst skriv inn'
	},
	modal: {
		title: 'Tittel',
		content: 'Innhold',
		btnText: 'Jeg forstår'
	},
	navBar: {
		title: 'Tittel'
	},
	pagination: {
		defaultOnlyOnePage: 'Bare en side'
	},
	picker: {
		defaultTitle: 'Vennligst velg',
		defaultCancel: 'Avbryt',
		defaultConfirm: 'Bekreft'
	},
	asyncPicker: {
		defaultTitle: 'Vennligst velg',
		defaultCancel: 'Avbryt',
		defaultConfirm: 'Bekreft',
		defaultNext: 'Neste',
		defaultPrev: 'Forrige',
		defaultSelected: 'Valgt'
	},
	rate: {
		error1: 'Verdien kan ikke være større enn totalen!',
		error2: 'Totalen må være redusert med 1!',
		error3: 'Verdien må reduseres med 1 når ikke-halvselektiv!',
		error4: 'Verdien må reduseres med 0,5 når halvselektiv!',
		error5: 'Bredde eller høyde er mindre enn 20, noe som gjør mobilterminalen vanskelig å klikke!'
	},
	timePicker: {
		defaultTitle: 'Vennligst velg',
		defaultCancel: 'Avbryt',
		defaultConfirm: 'Bekreft',
		defaultYear: 'År',
		defaultMonth: 'Måned',
		defaultDay: 'Dag',
		defaultHour: 'Time',
		defaultMinute: 'Minutt',
		defaultSecond: 'Sekund'
	},
	calendar: {
		weekTextList: ['Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør', 'Søn'],
		weekSundayStartTextList: ['Søn', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør'],
		monthTextList: ['januar', 'februar', 'mars', 'april', 'mai', 'juni', 'juli', 'august', 'september', 'oktober', 'november', 'desember'],
		confirmText: 'Bekreft',
		selectedText: 'Valgt',
		dayText: 'dag',
		beforeText: 'Siste',
		afterText: 'Fremtidig',
		currentWeekText: 'Denne uken',
		currentMonthText: 'Denne måneden',
		currentQuarterText: 'Dette kvartalet'
	}
};

export default nb_NO;



================================================
FILE: packages/stdf/src/lib/lang/ne_NP.ts
================================================
import type { LangProps } from './index.js';

const ne_NP: LangProps = {
	common: {
		slotEmpty: 'स्लटको सामग्री खाली छ!',
		loading: 'लोड हुदैछ...',
		noData: 'कुनै डाटा छैन',
		noMoreData: 'अझै डेटा छैन',
		done: 'गरियो'
	},
	actionSheet: {
		cancelText: 'रद्द गर्नुहोस्'
	},
	bottomSheet: {
		title: 'शीर्षक'
	},
	dialog: {
		title: 'संकेत',
		content: 'सामग्री',
		primaryText: 'पुष्टि गर्नुहोस्',
		secondaryText: 'रद्द गर्नुहोस्'
	},
	input: {
		pleaseInput: 'कृपया टाइप गर्नुहोस्'
	},
	modal: {
		title: 'शीर्षक',
		content: 'सामग्री',
		btnText: 'मैं समझता हूँ'
	},
	navBar: {
		title: 'शीर्षक'
	},
	pagination: {
		defaultOnlyOnePage: 'केवल एक पृष्ठ'
	},
	picker: {
		defaultTitle: 'कृपया छान्नुहोस्',
		defaultCancel: 'रद्द गर्नुहोस्',
		defaultConfirm: 'पुष्टि गर्नुहोस्'
	},
	asyncPicker: {
		defaultTitle: 'कृपया छान्नुहोस्',
		defaultCancel: 'रद्द गर्नुहोस्',
		defaultConfirm: 'पुष्टि गर्नुहोस्',
		defaultNext: 'त्यसपछि',
		defaultPrev: 'पहिलो',
		defaultSelected: 'Selected'
	},
	rate: {
		error1: 'मात्रा पूर्णबाट ठुलो हुँदैन!',
		error2: 'संपूर्ण एकबट कम हुनुपर्छ!',
		error3: 'गैर-अर्ध चयन गरिएकोमा मान एकबाट कम हुनुपर्छ!',
		error4: 'अर्ध चयन गरिएकोमा मान अर्धबाट कम हुनुपर्छ!',
		error5: 'चौड़ाई वा उचाई 20 भन्दा कम छ जस्ले मोबाइल टर्मिनलमा क्लिक गर्न दुखद।'
	},
	timePicker: {
		defaultTitle: 'कृपया छान्नुहोस्',
		defaultCancel: 'रद्द गर्नुहोस्',
		defaultConfirm: 'पुष्टि गर्नुहोस्',
		defaultYear: 'वर्ष',
		defaultMonth: 'महिना',
		defaultDay: 'दिन',
		defaultHour: 'घण्टा',
		defaultMinute: 'मिनेट',
		defaultSecond: 'सेकेन्ड'
	},
	calendar: {
		weekTextList: ['सोम', 'मंगल', 'बुध', 'बिही', 'शुक्र', 'शनि', 'आइत'],
		weekSundayStartTextList: ['आइत', 'सोम', 'मंगल', 'बुध', 'बिही', 'शुक्र', 'शनि'],
		monthTextList: ['जनवरी', 'फरवरी', 'मार्च', 'अप्रिल', 'मे', 'जून', 'जुलाई', 'अगस्त', 'सेप्टेम्बर', 'अक्टोबर', 'नोभेम्बर', 'डिसेम्बर'],
		confirmText: 'पुष्टि गर्नुहोस्',
		selectedText: 'चयन गरिएको',
		dayText: 'दिन',
		beforeText: 'हालको',
		afterText: 'भविष्य',
		currentWeekText: 'यो हप्ता',
		currentMonthText: 'यो महिना',
		currentQuarterText: 'यो तिमीहरूको तिमी'
	}
};

export default ne_NP;



================================================
FILE: packages/stdf/src/lib/lang/nl_BE.ts
================================================
import type { LangProps } from './index.js';

const nl_BE: LangProps = {
	common: {
		slotEmpty: 'Deze sleuf is leeg!',
		loading: 'Bezig met laden...',
		noData: 'Geen gegevens',
		noMoreData: 'Geen extra gegevens',
		done: 'Gedaan'
	},
	actionSheet: {
		cancelText: 'Annuleren'
	},
	bottomSheet: {
		title: 'Titel'
	},
	dialog: {
		title: 'Titel',
		content: 'Inhoud',
		primaryText: 'Bevestigen',
		secondaryText: 'Annuleren'
	},
	input: {
		pleaseInput: 'Voer in'
	},
	modal: {
		title: 'Titel',
		content: 'Inhoud',
		btnText: 'Begrepen'
	},
	navBar: {
		title: 'Titel'
	},
	pagination: {
		defaultOnlyOnePage: 'Slechts één pagina'
	},
	picker: {
		defaultTitle: 'Selecteer alstublieft',
		defaultCancel: 'Annuleren',
		defaultConfirm: 'Bevestigen'
	},
	asyncPicker: {
		defaultTitle: 'Selecteer alstublieft',
		defaultCancel: 'Annuleren',
		defaultConfirm: 'Bevestigen',
		defaultNext: 'Volgende',
		defaultPrev: 'Vorige',
		defaultSelected: 'Geselecteerd'
	},
	rate: {
		error1: 'Waardering moet minimaal compleet zijn!',
		error2: 'Waardering mag niet minder dan één zijn!',
		error3: 'Een gedeeltelijke selectie moet meer dan 1 waarde hebben!',
		error4: 'Een gedeeltelijke selectie moet minder dan 1 waarde hebben!',
		error5: 'Breedte of hoogte kleiner dan 20, niet toegestaan om op mobiel te klikken.'
	},
	timePicker: {
		defaultTitle: 'Selecteer alstublieft',
		defaultCancel: 'Annuleren',
		defaultConfirm: 'Bevestigen',
		defaultYear: 'Jaar',
		defaultMonth: 'Maand',
		defaultDay: 'Dag',
		defaultHour: 'Uur',
		defaultMinute: 'Minuut',
		defaultSecond: 'Seconde'
	},
	calendar: {
		weekTextList: ['Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za', 'Zo'],
		weekSundayStartTextList: ['Zo', 'Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za'],
		monthTextList: [
			'Januari',
			'Februari',
			'Maart',
			'April',
			'Mei',
			'Juni',
			'Juli',
			'Augustus',
			'September',
			'Oktober',
			'November',
			'December'
		],
		confirmText: 'Bevestigen',
		selectedText: 'Geselecteerd',
		dayText: 'Dag',
		beforeText: 'Vóór',
		afterText: 'Na',
		currentWeekText: 'Deze week',
		currentMonthText: 'Deze maand',
		currentQuarterText: 'Dit kwartaal'
	}
};

export default nl_BE;



================================================
FILE: packages/stdf/src/lib/lang/nl_NL.ts
================================================
import type { LangProps } from './index.js';

const nl_NL: LangProps = {
	common: {
		slotEmpty: 'Deze slot is leeg!',
		loading: 'Laden...',
		noData: 'Geen data',
		noMoreData: 'Geen extra data',
		done: 'Gedaan'
	},
	actionSheet: {
		cancelText: 'Annuleren'
	},
	bottomSheet: {
		title: 'Titel'
	},
	dialog: {
		title: 'Titel',
		content: 'Inhoud',
		primaryText: 'Bevestigen',
		secondaryText: 'Annuleren'
	},
	input: {
		pleaseInput: 'Voer in'
	},
	modal: {
		title: 'Titel',
		content: 'Inhoud',
		btnText: 'Oké'
	},
	navBar: {
		title: 'Titel'
	},
	pagination: {
		defaultOnlyOnePage: 'Slechts één pagina'
	},
	picker: {
		defaultTitle: 'Selecteer alstublieft',
		defaultCancel: 'Annuleren',
		defaultConfirm: 'Bevestigen'
	},
	asyncPicker: {
		defaultTitle: 'Selecteer alstublieft',
		defaultCancel: 'Annuleren',
		defaultConfirm: 'Bevestigen',
		defaultNext: 'Volgende',
		defaultPrev: 'Vorige',
		defaultSelected: 'Geselecteerd'
	},
	rate: {
		error1: 'Waardering mag niet leeg zijn!',
		error2: 'Waardering moet meer dan 1 zijn!',
		error3: 'Een gedeeltelijke selectie moet meer dan 1 waarde hebben!',
		error4: 'Een gedeeltelijke selectie moet minder dan 1 waarde hebben!',
		error5: 'Breedte of hoogte kleiner dan 20, niet toegestaan om op mobiel te klikken.'
	},
	timePicker: {
		defaultTitle: 'Selecteer alstublieft',
		defaultCancel: 'Annuleren',
		defaultConfirm: 'Bevestigen',
		defaultYear: 'Jaar',
		defaultMonth: 'Maand',
		defaultDay: 'Dag',
		defaultHour: 'Uur',
		defaultMinute: 'Minuut',
		defaultSecond: 'Seconde'
	},
	calendar: {
		weekTextList: ['Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za', 'Zo'],
		weekSundayStartTextList: ['Zo', 'Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za'],
		monthTextList: [
			'Januari',
			'Februari',
			'Maart',
			'April',
			'Mei',
			'Juni',
			'Juli',
			'Augustus',
			'September',
			'Oktober',
			'November',
			'December'
		],
		confirmText: 'Bevestigen',
		selectedText: 'Geselecteerd',
		dayText: 'Dag',
		beforeText: 'Vóór',
		afterText: 'Na',
		currentWeekText: 'Deze week',
		currentMonthText: 'Deze maand',
		currentQuarterText: 'Dit kwartaal'
	}
};

export default nl_NL;



================================================
FILE: packages/stdf/src/lib/lang/pl_PL.ts
================================================
import type { LangProps } from './index.js';

const pl_PL: LangProps = {
	common: {
		slotEmpty: 'To miejsce jest puste!',
		loading: 'Wczytywanie...',
		noData: 'Brak danych',
		noMoreData: 'Brak dalszych danych',
		done: 'Gotowe'
	},
	actionSheet: {
		cancelText: 'Anuluj'
	},
	bottomSheet: {
		title: 'Tytuł'
	},
	dialog: {
		title: 'Tytuł',
		content: 'Treść',
		primaryText: 'Potwierdź',
		secondaryText: 'Anuluj'
	},
	input: {
		pleaseInput: 'Wprowadź'
	},
	modal: {
		title: 'Tytuł',
		content: 'Treść',
		btnText: 'OK'
	},
	navBar: {
		title: 'Tytuł'
	},
	pagination: {
		defaultOnlyOnePage: 'Tylko jedna strona'
	},
	picker: {
		defaultTitle: 'Proszę wybrać',
		defaultCancel: 'Anuluj',
		defaultConfirm: 'OK'
	},
	asyncPicker: {
		defaultTitle: 'Proszę wybrać',
		defaultCancel: 'Anuluj',
		defaultConfirm: 'OK',
		defaultNext: 'Następny',
		defaultPrev: 'Poprzedni',
		defaultSelected: 'Wybrano'
	},
	rate: {
		error1: 'Ocena nie może być pusta!',
		error2: 'Ocena musi być większa niż 1!',
		error3: 'Częściowa ocena musi zawierać co najmniej 1 wartość!',
		error4: 'Częściowa ocena nie może zawierać więcej niż 1 wartość!',
		error5: 'Szerokość lub wysokość mniejsza niż 20, nie można kliknąć na urządzeniach mobilnych.'
	},
	timePicker: {
		defaultTitle: 'Proszę wybrać',
		defaultCancel: 'Anuluj',
		defaultConfirm: 'OK',
		defaultYear: 'Rok',
		defaultMonth: 'Miesiąc',
		defaultDay: 'Dzień',
		defaultHour: 'Godzina',
		defaultMinute: 'Minuta',
		defaultSecond: 'Sekunda'
	},
	calendar: {
		weekTextList: ['Pn', 'Wt', 'Śr', 'Czw', 'Pt', 'Sob', 'Niedz'],
		weekSundayStartTextList: ['Niedz', 'Pn', 'Wt', 'Śr', 'Czw', 'Pt', 'Sob'],
		monthTextList: [
			'Styczeń',
			'Luty',
			'Marzec',
			'Kwiecień',
			'Maj',
			'Czerwiec',
			'Lipiec',
			'Sierpień',
			'Wrzesień',
			'Październik',
			'Listopad',
			'Grudzień'
		],
		confirmText: 'OK',
		selectedText: 'Wybrano',
		dayText: 'Dzień',
		beforeText: 'Przed',
		afterText: 'Po',
		currentWeekText: 'Bieżący tydzień',
		currentMonthText: 'Bieżący miesiąc',
		currentQuarterText: 'Bieżący kwartał'
	}
};

export default pl_PL;



================================================
FILE: packages/stdf/src/lib/lang/pt_BR.ts
================================================
import type { LangProps } from './index.js';

const pt_BR: LangProps = {
	common: {
		slotEmpty: 'Este espaço está vazio!',
		loading: 'Carregando...',
		noData: 'Sem dados',
		noMoreData: 'Não há mais dados',
		done: 'Feito'
	},
	actionSheet: {
		cancelText: 'Cancelar'
	},
	bottomSheet: {
		title: 'Título'
	},
	dialog: {
		title: 'Título',
		content: 'Conteúdo',
		primaryText: 'Confirmar',
		secondaryText: 'Cancelar'
	},
	input: {
		pleaseInput: 'Por favor, insira'
	},
	modal: {
		title: 'Título',
		content: 'Conteúdo',
		btnText: 'OK'
	},
	navBar: {
		title: 'Título'
	},
	pagination: {
		defaultOnlyOnePage: 'Apenas uma página'
	},
	picker: {
		defaultTitle: 'Por favor selecione',
		defaultCancel: 'Cancelar',
		defaultConfirm: 'Confirmar'
	},
	asyncPicker: {
		defaultTitle: 'Por favor selecione',
		defaultCancel: 'Cancelar',
		defaultConfirm: 'Confirmar',
		defaultNext: 'Próximo',
		defaultPrev: 'Anterior',
		defaultSelected: 'Selecionado'
	},
	rate: {
		error1: 'A avaliação não pode estar vazia!',
		error2: 'A avaliação precisa ser maior que 1!',
		error3: 'Uma avaliação parcial deve ter pelo menos 1 valor!',
		error4: 'Uma avaliação parcial não pode ter mais de 1 valor!',
		error5: 'Largura ou altura inferior a 20, não permitido clicar em dispositivos móveis.'
	},
	timePicker: {
		defaultTitle: 'Por favor selecione',
		defaultCancel: 'Cancelar',
		defaultConfirm: 'Confirmar',
		defaultYear: 'Ano',
		defaultMonth: 'Mês',
		defaultDay: 'Dia',
		defaultHour: 'Hora',
		defaultMinute: 'Minuto',
		defaultSecond: 'Segundo'
	},
	calendar: {
		weekTextList: ['Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb', 'Dom'],
		weekSundayStartTextList: ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'],
		monthTextList: [
			'Janeiro',
			'Fevereiro',
			'Março',
			'Abril',
			'Maio',
			'Junho',
			'Julho',
			'Agosto',
			'Setembro',
			'Outubro',
			'Novembro',
			'Dezembro'
		],
		confirmText: 'Confirmar',
		selectedText: 'Selecionado',
		dayText: 'Dia',
		beforeText: 'Antes',
		afterText: 'Depois',
		currentWeekText: 'Esta semana',
		currentMonthText: 'Este mês',
		currentQuarterText: 'Este trimestre'
	}
};

export default pt_BR;



================================================
FILE: packages/stdf/src/lib/lang/pt_PT.ts
================================================
import type { LangProps } from './index.js';

const pt_PT: LangProps = {
	common: {
		slotEmpty: 'Este espaço está vazio!',
		loading: 'A carregar...',
		noData: 'Sem dados',
		noMoreData: 'Não há mais dados',
		done: 'Feito'
	},
	actionSheet: {
		cancelText: 'Cancelar'
	},
	bottomSheet: {
		title: 'Título'
	},
	dialog: {
		title: 'Título',
		content: 'Conteúdo',
		primaryText: 'Confirmar',
		secondaryText: 'Cancelar'
	},
	input: {
		pleaseInput: 'Por favor, insira'
	},
	modal: {
		title: 'Título',
		content: 'Conteúdo',
		btnText: 'OK'
	},
	navBar: {
		title: 'Título'
	},
	pagination: {
		defaultOnlyOnePage: 'Apenas uma página'
	},
	picker: {
		defaultTitle: 'Por favor selecione',
		defaultCancel: 'Cancelar',
		defaultConfirm: 'Confirmar'
	},
	asyncPicker: {
		defaultTitle: 'Por favor selecione',
		defaultCancel: 'Cancelar',
		defaultConfirm: 'Confirmar',
		defaultNext: 'Próximo',
		defaultPrev: 'Anterior',
		defaultSelected: 'Selecionado'
	},
	rate: {
		error1: 'A avaliação não pode estar vazia!',
		error2: 'A avaliação precisa ser maior que 1!',
		error3: 'Uma avaliação parcial deve ter pelo menos 1 valor!',
		error4: 'Uma avaliação parcial não pode ter mais de 1 valor!',
		error5: 'Largura ou altura inferior a 20, não permitido clicar em dispositivos móveis.'
	},
	timePicker: {
		defaultTitle: 'Por favor selecione',
		defaultCancel: 'Cancelar',
		defaultConfirm: 'Confirmar',
		defaultYear: 'Ano',
		defaultMonth: 'Mês',
		defaultDay: 'Dia',
		defaultHour: 'Hora',
		defaultMinute: 'Minuto',
		defaultSecond: 'Segundo'
	},
	calendar: {
		weekTextList: ['Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb', 'Dom'],
		weekSundayStartTextList: ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'],
		monthTextList: [
			'Janeiro',
			'Fevereiro',
			'Março',
			'Abril',
			'Maio',
			'Junho',
			'Julho',
			'Agosto',
			'Setembro',
			'Outubro',
			'Novembro',
			'Dezembro'
		],
		confirmText: 'Confirmar',
		selectedText: 'Selecionado',
		dayText: 'Dia',
		beforeText: 'Antes',
		afterText: 'Depois',
		currentWeekText: 'Esta semana',
		currentMonthText: 'Este mês',
		currentQuarterText: 'Este trimestre'
	}
};

export default pt_PT;



================================================
FILE: packages/stdf/src/lib/lang/ro_RO.ts
================================================
import type { LangProps } from './index.js';

const ro_RO: LangProps = {
	common: {
		slotEmpty: 'Acest spațiu este gol!',
		loading: 'Se încarcă...',
		noData: 'Fără date',
		noMoreData: 'Nu mai există date',
		done: 'Gata'
	},
	actionSheet: {
		cancelText: 'Anulează'
	},
	bottomSheet: {
		title: 'Titlu'
	},
	dialog: {
		title: 'Titlu',
		content: 'Conținut',
		primaryText: 'Confirmă',
		secondaryText: 'Anulează'
	},
	input: {
		pleaseInput: 'Introduceți'
	},
	modal: {
		title: 'Titlu',
		content: 'Conținut',
		btnText: 'OK'
	},
	navBar: {
		title: 'Titlu'
	},
	pagination: {
		defaultOnlyOnePage: 'Doar o pagină'
	},
	picker: {
		defaultTitle: 'Selectați vă rog',
		defaultCancel: 'Anulează',
		defaultConfirm: 'Confirmă'
	},
	asyncPicker: {
		defaultTitle: 'Selectați vă rog',
		defaultCancel: 'Anulează',
		defaultConfirm: 'Confirmă',
		defaultNext: 'Următorul',
		defaultPrev: 'Anteriorul',
		defaultSelected: 'Selectat'
	},
	rate: {
		error1: 'Evaluarea nu poate fi goală!',
		error2: 'Evaluarea trebuie să fie mai mare de 1!',
		error3: 'O evaluare parțială trebuie să aibă cel puțin 1 valoare!',
		error4: 'O evaluare parțială nu poate avea mai mult de 1 valoare!',
		error5: 'Lățimea sau înălțimea este mai mică de 20, fără clic disponibil pe dispozitivele mobile.'
	},
	timePicker: {
		defaultTitle: 'Selectați vă rog',
		defaultCancel: 'Anulează',
		defaultConfirm: 'Confirmă',
		defaultYear: 'An',
		defaultMonth: 'Lună',
		defaultDay: 'Zi',
		defaultHour: 'Oră',
		defaultMinute: 'Minut',
		defaultSecond: 'Secundă'
	},
	calendar: {
		weekTextList: ['Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sâm', 'Dum'],
		weekSundayStartTextList: ['Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sâm'],
		monthTextList: [
			'Ianuarie',
			'Februarie',
			'Martie',
			'Aprilie',
			'Mai',
			'Iunie',
			'Iulie',
			'August',
			'Septembrie',
			'Octombrie',
			'Noiembrie',
			'Decembrie'
		],
		confirmText: 'Confirmă',
		selectedText: 'Selectat',
		dayText: 'Zi',
		beforeText: 'Anterior',
		afterText: 'Următor',
		currentWeekText: 'Săptămâna aceasta',
		currentMonthText: 'Luna aceasta',
		currentQuarterText: 'Acest trimestru'
	}
};

export default ro_RO;



================================================
FILE: packages/stdf/src/lib/lang/ru_RU.ts
================================================
import type { LangProps } from './index.js';

const ru_RU: LangProps = {
	common: {
		slotEmpty: 'Это место пустое!',
		loading: 'Загрузка...',
		noData: 'Нет данных',
		noMoreData: 'Больше нет данных',
		done: 'Готово'
	},
	actionSheet: {
		cancelText: 'Отмена'
	},
	bottomSheet: {
		title: 'Заголовок'
	},
	dialog: {
		title: 'Заголовок',
		content: 'Содержание',
		primaryText: 'Подтвердить',
		secondaryText: 'Отмена'
	},
	input: {
		pleaseInput: 'Пожалуйста, введите'
	},
	modal: {
		title: 'Заголовок',
		content: 'Содержание',
		btnText: 'OK'
	},
	navBar: {
		title: 'Заголовок'
	},
	pagination: {
		defaultOnlyOnePage: 'Только одна страница'
	},
	picker: {
		defaultTitle: 'Пожалуйста, выберите',
		defaultCancel: 'Отмена',
		defaultConfirm: 'Подтвердить'
	},
	asyncPicker: {
		defaultTitle: 'Пожалуйста, выберите',
		defaultCancel: 'Отмена',
		defaultConfirm: 'Подтвердить',
		defaultNext: 'Следующий',
		defaultPrev: 'Предыдущий',
		defaultSelected: 'Выбрано'
	},
	rate: {
		error1: 'Рейтинг не может быть пустым!',
		error2: 'Рейтинг должен быть больше 1!',
		error3: 'Для частичной оценки нужно хотя бы 1 значение!',
		error4: 'Для частичной оценки не может быть более 1 значения!',
		error5: 'Ширина или высота меньше 20, на мобильных устройствах нельзя нажать.'
	},
	timePicker: {
		defaultTitle: 'Пожалуйста, выберите',
		defaultCancel: 'Отмена',
		defaultConfirm: 'Подтвердить',
		defaultYear: 'Год',
		defaultMonth: 'Месяц',
		defaultDay: 'День',
		defaultHour: 'Час',
		defaultMinute: 'Минута',
		defaultSecond: 'Секунда'
	},
	calendar: {
		weekTextList: ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'],
		weekSundayStartTextList: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],
		monthTextList: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'],
		confirmText: 'Подтвердить',
		selectedText: 'Выбрано',
		dayText: 'День',
		beforeText: 'До',
		afterText: 'После',
		currentWeekText: 'Текущая неделя',
		currentMonthText: 'Текущий месяц',
		currentQuarterText: 'Текущий квартал'
	}
};

export default ru_RU;



================================================
FILE: packages/stdf/src/lib/lang/si_LK.ts
================================================
import type { LangProps } from './index.js';

const si_LK: LangProps = {
	common: {
		slotEmpty: 'මේ ස්මන්තිය හිස් විය!',
		loading: 'පූරණය වෙමින්...',
		noData: 'දත්ත නැත',
		noMoreData: 'තවත් දත්ත නැත',
		done: 'ක්‍රියාත්මක කරන ලදි'
	},
	actionSheet: {
		cancelText: 'එපා'
	},
	bottomSheet: {
		title: 'මාතෘකාව'
	},
	dialog: {
		title: 'මාතෘකාව',
		content: 'අන්‍යකාරය',
		primaryText: 'තහවුරු කරන්න',
		secondaryText: 'ඉවත් කරන්න'
	},
	input: {
		pleaseInput: 'කරුණාකර ඇතුලත් කරන්න'
	},
	modal: {
		title: 'මාතෘකාව',
		content: 'අන්‍යකාරය',
		btnText: 'හරි'
	},
	navBar: {
		title: 'මාතෘකාව'
	},
	pagination: {
		defaultOnlyOnePage: 'එක් පිටුවක් පමණක් පවතී'
	},
	picker: {
		defaultTitle: 'කරුණාකර තෝරන්න',
		defaultCancel: 'අවලංගු කරන්න',
		defaultConfirm: 'තහවුරු කරන්න'
	},
	asyncPicker: {
		defaultTitle: 'කරුණාකර තෝරන්න',
		defaultCancel: 'අවලංගු කරන්න',
		defaultConfirm: 'තහවුරු කරන්න',
		defaultNext: 'ඊළඟ',
		defaultPrev: 'පෙර',
		defaultSelected: 'තෝරා ඇත'
	},
	rate: {
		error1: 'ශීර්ෂය හිස්ව නොවේ!',
		error2: 'ශීර්ෂය 1 වනිදා වඩාත්ම වැඩි විය යුතුය!',
		error3: 'පැරණි ශීර්ෂය සඳහා හොඳ අගය 1 ක් වැඩි විය යුතුය!',
		error4: 'පැරණි ශීර්ෂය සඳහා වැඩි 1 ක් වන විට 1 අගයක්දි විය යුතුය!',
		error5: 'පළල හෝ උස සීමාව 20 ට වඩා අඩු බව, ජංගම දුරකථන ඇතුළත් සහිතව ඇතිවිය හැකිය.'
	},
	timePicker: {
		defaultTitle: 'කරුණාකර තෝරන්න',
		defaultCancel: 'අවලංගු කරන්න',
		defaultConfirm: 'තහවුරු කරන්න',
		defaultYear: 'වර්ෂය',
		defaultMonth: 'මාසය',
		defaultDay: 'දිනය',
		defaultHour: 'පැය',
		defaultMinute: 'මිනිත්තුව',
		defaultSecond: 'තත්පර'
	},
	calendar: {
		weekTextList: ['අඟ', 'අක්ති', 'බදාදා', 'බදාරහත්', 'පෙරවරු', 'සිකුරාදා', 'ඉරිදා'],
		weekSundayStartTextList: ['ඉරිදා', 'අඟ', 'අක්ති', 'බදාදා', 'බදාරහත්', 'පෙරවරු', 'සිකුරාදා'],
		monthTextList: [
			'ජනවාරි',
			'පෙබරවාරිය',
			'මාර්තු',
			'අප්‍රේල්',
			'මැයි',
			'ජූනි',
			'ජූලි',
			'අගෝස්තු',
			'සැප්තැම්බර්',
			'ඔක්තෝබර්',
			'නොවැම්බර්',
			'දෙසැම්බර්'
		],
		confirmText: 'තහවුරු කරන්න',
		selectedText: 'තෝරා ඇත',
		dayText: 'දිනය',
		beforeText: 'පෙර',
		afterText: 'පසුව',
		currentWeekText: 'මෙම සතිය',
		currentMonthText: 'මෙම මාසය',
		currentQuarterText: 'මෙම කාර්තුව'
	}
};

export default si_LK;



================================================
FILE: packages/stdf/src/lib/lang/sk_SK.ts
================================================
import type { LangProps } from './index.js';

const sk_SK: LangProps = {
	common: {
		slotEmpty: 'Toto miesto je prázdne!',
		loading: 'Načítavam...',
		noData: 'Žiadne dáta',
		noMoreData: 'Žiadne ďalšie dáta',
		done: 'Hotovo'
	},
	actionSheet: {
		cancelText: 'Zrušiť'
	},
	bottomSheet: {
		title: 'Titulok'
	},
	dialog: {
		title: 'Titulok',
		content: 'Obsah',
		primaryText: 'Confirm',
		secondaryText: 'Cancel'
	},
	input: {
		pleaseInput: 'Prosím zadajte'
	},
	modal: {
		title: 'Titulok',
		content: 'Obsah',
		btnText: 'OK'
	},
	navBar: {
		title: 'Titulok'
	},
	pagination: {
		defaultOnlyOnePage: 'Len jedna stránka'
	},
	picker: {
		defaultTitle: 'Prosím vyberte',
		defaultCancel: 'Zrušiť',
		defaultConfirm: 'Potvrdiť'
	},
	asyncPicker: {
		defaultTitle: 'Prosím vyberte',
		defaultCancel: 'Zrušiť',
		defaultConfirm: 'Potvrdiť',
		defaultNext: 'Ďalšie',
		defaultPrev: 'Predchádzajúce',
		defaultSelected: 'Vybrané'
	},
	rate: {
		error1: 'Hodnotenie sa nepodarilo!',
		error2: 'Hodnotenie musí byť aspoň 1 hviezdička!',
		error3: 'Dobré hodnotenie musí byť minimálne 1 hviezdička!',
		error4: 'Priemerné hodnotenie musí byť aspoň 1 hviezdička!',
		error5: 'Dĺžka komentáru musí byť kratšia ako 20 znakov.'
	},
	timePicker: {
		defaultTitle: 'Vyberte čas',
		defaultCancel: 'Zrušiť',
		defaultConfirm: 'Potvrdiť',
		defaultYear: 'Rok',
		defaultMonth: 'Mesiac',
		defaultDay: 'Deň',
		defaultHour: 'Hodina',
		defaultMinute: 'Minúta',
		defaultSecond: 'Sekunda'
	},
	calendar: {
		weekTextList: ['Po', 'Ut', 'St', 'Št', 'Pi', 'So', 'Ne'],
		weekSundayStartTextList: ['Ne', 'Po', 'Ut', 'St', 'Št', 'Pi', 'So'],
		monthTextList: ['Január', 'Február', 'Marec', 'Apríl', 'Máj', 'Jún', 'Júl', 'August', 'September', 'Október', 'November', 'December'],
		confirmText: 'Potvrdiť',
		selectedText: 'Vybrané',
		dayText: 'Deň',
		beforeText: 'Pred',
		afterText: 'Po',
		currentWeekText: 'Tento týždeň',
		currentMonthText: 'Tento mesiac',
		currentQuarterText: 'Tento štvrťrok'
	}
};

export default sk_SK;



================================================
FILE: packages/stdf/src/lib/lang/sl_SI.ts
================================================
import type { LangProps } from './index.js';

const sl_SI: LangProps = {
	common: {
		slotEmpty: 'To mesto je prazno!',
		loading: 'Nalaganje ...',
		noData: 'Ni podatkov',
		noMoreData: 'Ni več podatkov',
		done: 'Končano'
	},
	actionSheet: {
		cancelText: 'Prekliči'
	},
	bottomSheet: {
		title: 'Naslov'
	},
	dialog: {
		title: 'Naslov',
		content: 'Vsebina',
		primaryText: 'Potrdi',
		secondaryText: 'Prekliči'
	},
	input: {
		pleaseInput: 'Prosim vnesite'
	},
	modal: {
		title: 'Naslov',
		content: 'Vsebina',
		btnText: 'V redu'
	},
	navBar: {
		title: 'Naslov'
	},
	pagination: {
		defaultOnlyOnePage: 'Samo ena stran'
	},
	picker: {
		defaultTitle: 'Prosim izberite',
		defaultCancel: 'Prekliči',
		defaultConfirm: 'Potrdi'
	},
	asyncPicker: {
		defaultTitle: 'Prosim izberite',
		defaultCancel: 'Prekliči',
		defaultConfirm: 'Potrdi',
		defaultNext: 'Naslednja',
		defaultPrev: 'Prejšnja',
		defaultSelected: 'Izbrano'
	},
	rate: {
		error1: 'Ocenjevanju ni uspelo!',
		error2: 'Ocena mora biti vsaj 1 zvezdica!',
		error3: 'Dobra ocena mora biti vsaj 1 zvezdica!',
		error4: 'Povprečna ocena mora biti vsaj 1 zvezdica!',
		error5: 'Dolžina komentarja mora biti krajša od 20 znakov.'
	},
	timePicker: {
		defaultTitle: 'Izberite čas',
		defaultCancel: 'Prekliči',
		defaultConfirm: 'Potrdi',
		defaultYear: 'Leto',
		defaultMonth: 'Mesec',
		defaultDay: 'Dan',
		defaultHour: 'Ura',
		defaultMinute: 'Minuta',
		defaultSecond: 'Sekunda'
	},
	calendar: {
		weekTextList: ['Pon', 'Tor', 'Sre', 'Čet', 'Pet', 'Sob', 'Ned'],
		weekSundayStartTextList: ['Ned', 'Pon', 'Tor', 'Sre', 'Čet', 'Pet', 'Sob'],
		monthTextList: [
			'Januar',
			'Februar',
			'Marec',
			'April',
			'Maj',
			'Junij',
			'Julij',
			'Avgust',
			'September',
			'Oktober',
			'November',
			'December'
		],
		confirmText: 'Potrdi',
		selectedText: 'Izbrano',
		dayText: 'Dan',
		beforeText: 'Pred',
		afterText: 'Po',
		currentWeekText: 'Ta teden',
		currentMonthText: 'Ta mesec',
		currentQuarterText: 'To četrtletje'
	}
};

export default sl_SI;



================================================
FILE: packages/stdf/src/lib/lang/sr_RS.ts
================================================
import type { LangProps } from './index.js';

const sr_RS: LangProps = {
	common: {
		slotEmpty: 'Ovo mesto je prazno!',
		loading: 'Učitavam...',
		noData: 'Nema podataka',
		noMoreData: 'Nema više podataka',
		done: 'Gotovo'
	},
	actionSheet: {
		cancelText: 'Otkaži'
	},
	bottomSheet: {
		title: 'Naslov'
	},
	dialog: {
		title: 'Naslov',
		content: 'Sadržaj',
		primaryText: 'Potvrdi',
		secondaryText: 'Otkaži'
	},
	input: {
		pleaseInput: 'Molimo unesite'
	},
	modal: {
		title: 'Naslov',
		content: 'Sadržaj',
		btnText: 'U redu'
	},
	navBar: {
		title: 'Naslov'
	},
	pagination: {
		defaultOnlyOnePage: 'Samo jedna stranica'
	},
	picker: {
		defaultTitle: 'Molimo odaberite',
		defaultCancel: 'Otkaži',
		defaultConfirm: 'Potvrdi'
	},
	asyncPicker: {
		defaultTitle: 'Molimo odaberite',
		defaultCancel: 'Otkaži',
		defaultConfirm: 'Potvrdi',
		defaultNext: 'Sledeće',
		defaultPrev: 'Pređašnje',
		defaultSelected: 'Izabrano'
	},
	rate: {
		error1: 'Ocenjivanje nije uspelo!',
		error2: 'Ocena mora da bude bar 1 zvezdica!',
		error3: 'Dobra ocena mora da bude minimalno 1 zvezdica!',
		error4: 'Prosečna ocena mora da bude bar 1 zvezdica!',
		error5: 'Duljina komentara mora da bude kraća od 20 znakova.'
	},
	timePicker: {
		defaultTitle: 'Odaberite vrijeme',
		defaultCancel: 'Otkaži',
		defaultConfirm: 'Potvrdi',
		defaultYear: 'Godina',
		defaultMonth: 'Mesec',
		defaultDay: 'Dan',
		defaultHour: 'Sati',
		defaultMinute: 'Minute',
		defaultSecond: 'Sekunde'
	},
	calendar: {
		weekTextList: ['Pon', 'Uto', 'Sre', 'Čet', 'Pet', 'Sub', 'Ned'],
		weekSundayStartTextList: ['Ned', 'Pon', 'Uto', 'Sre', 'Čet', 'Pet', 'Sub'],
		monthTextList: ['Januar', 'Februar', 'Mart', 'April', 'Maj', 'Jun', 'Jul', 'Avgust', 'Septembar', 'Oktobar', 'Novembar', 'Decembar'],
		confirmText: 'Potvrdi',
		selectedText: 'Izabrano',
		dayText: 'Dan',
		beforeText: 'Pre',
		afterText: 'Posle',
		currentWeekText: 'Ovaj tjedan',
		currentMonthText: 'Ovaj mjesec',
		currentQuarterText: 'Ovaj kvartal'
	}
};

export default sr_RS;



================================================
FILE: packages/stdf/src/lib/lang/sv_SE.ts
================================================
import type { LangProps } from './index.js';

const sv_SE: LangProps = {
	common: {
		slotEmpty: 'Det finns ingen information att visa!',
		loading: 'Laddar...',
		noData: 'Inga data',
		noMoreData: 'Ingen mer data',
		done: 'Klar'
	},
	actionSheet: {
		cancelText: 'Avbryt'
	},
	bottomSheet: {
		title: 'Titel'
	},
	dialog: {
		title: 'Titel',
		content: 'Innehåll',
		primaryText: 'Bekräfta',
		secondaryText: 'Avbryt'
	},
	input: {
		pleaseInput: 'Vänligen fyll i'
	},
	modal: {
		title: 'Titel',
		content: 'Innehåll',
		btnText: 'OK'
	},
	navBar: {
		title: 'Titel'
	},
	pagination: {
		defaultOnlyOnePage: 'Endast en sida'
	},
	picker: {
		defaultTitle: 'Vänligen välj',
		defaultCancel: 'Avbryt',
		defaultConfirm: 'Bekräfta'
	},
	asyncPicker: {
		defaultTitle: 'Vänligen välj',
		defaultCancel: 'Avbryt',
		defaultConfirm: 'Bekräfta',
		defaultNext: 'Nästa',
		defaultPrev: 'Föregående',
		defaultSelected: 'Vald'
	},
	rate: {
		error1: 'Betygsättning misslyckades!',
		error2: 'Betygsättningen måste vara minst en stjärna!',
		error3: 'En bra betyg måste vara minst en stjärna!',
		error4: 'Genomsnittligt betyg måste vara minst en stjärna!',
		error5: 'Kommentarens längd måste vara mindre än 20 tecken.'
	},
	timePicker: {
		defaultTitle: 'Välj tid',
		defaultCancel: 'Avbryt',
		defaultConfirm: 'Bekräfta',
		defaultYear: 'År',
		defaultMonth: 'Månad',
		defaultDay: 'Dag',
		defaultHour: 'Timme',
		defaultMinute: 'Minut',
		defaultSecond: 'Sekund'
	},
	calendar: {
		weekTextList: ['Mån', 'Tis', 'Ons', 'Tor', 'Fre', 'Lör', 'Sön'],
		weekSundayStartTextList: ['Sön', 'Mån', 'Tis', 'Ons', 'Tor', 'Fre', 'Lör'],
		monthTextList: [
			'Januari',
			'Februari',
			'Mars',
			'April',
			'Maj',
			'Juni',
			'Juli',
			'Augusti',
			'September',
			'Oktober',
			'November',
			'December'
		],
		confirmText: 'Bekräfta',
		selectedText: 'Vald',
		dayText: 'Dag',
		beforeText: 'Före',
		afterText: 'Efter',
		currentWeekText: 'Denna vecka',
		currentMonthText: 'Denna månad',
		currentQuarterText: 'Detta kvartal'
	}
};

export default sv_SE;



================================================
FILE: packages/stdf/src/lib/lang/ta_IN.ts
================================================
import type { LangProps } from './index.js';

const ta_IN: LangProps = {
	common: {
		slotEmpty: 'காண்பிக்க தகவல் இல்லை!',
		loading: 'ஏற்றுகிறது...',
		noData: 'தரவு இல்லை',
		noMoreData: 'மேலும் தரவு இல்லை',
		done: 'முடிந்தது'
	},
	actionSheet: {
		cancelText: 'ரத்துசெய்'
	},
	bottomSheet: {
		title: 'தலைப்பு'
	},
	dialog: {
		title: 'தலைப்பு',
		content: 'உள்ளீடு',
		primaryText: 'உறுதிசெய்',
		secondaryText: 'ரத்துசெய்'
	},
	input: {
		pleaseInput: 'தயவு செய்து உள்ளிடவும்'
	},
	modal: {
		title: 'தலைப்பு',
		content: 'உள்ளீடு',
		btnText: 'சரி'
	},
	navBar: {
		title: 'தலைப்பு'
	},
	pagination: {
		defaultOnlyOnePage: 'ஒரு பக்கம் மட்டுமே'
	},
	picker: {
		defaultTitle: 'தயவு செய்து தேர்ந்தெடுக்கவும்',
		defaultCancel: 'ரத்துசெய்',
		defaultConfirm: 'உறுதிசெய்'
	},
	asyncPicker: {
		defaultTitle: 'தயவு செய்து தேர்ந்தெடுக்கவும்',
		defaultCancel: 'ரத்துசெய்',
		defaultConfirm: 'உறுதிசெய்',
		defaultNext: 'அடுத்து',
		defaultPrev: 'முன்',
		defaultSelected: 'தேர்ந்தெடுக்கப்பட்டது'
	},
	rate: {
		error1: 'மதிப்பீடு தோல்வி!',
		error2: 'மதிப்பீடு ஒரு ஸ்டார் குறைவாக இருக்க வேண்டும்!',
		error3: 'ஒரு நல்ல மதிப்பீடு ஒரு ஸ்டார் குறைவாக இருக்க வேண்டும்!',
		error4: 'சராசரி மதிப்பீடு ஒரு ஸ்டார் குறைவாக இருக்க வேண்டும்!',
		error5: 'கருத்து முறையும் குறுகியவற்றை விட குறைவுகளை வேண்டுகின்றது.'
	},
	timePicker: {
		defaultTitle: 'நேரத்தை தேர்ந்தெடுக்கவும்',
		defaultCancel: 'ரத்துசெய்',
		defaultConfirm: 'உறுதிசெய்',
		defaultYear: 'ஆண்டு',
		defaultMonth: 'மாதம்',
		defaultDay: 'நாள்',
		defaultHour: 'மணி',
		defaultMinute: 'நிமிடம்',
		defaultSecond: 'நொடி'
	},
	calendar: {
		weekTextList: ['திங்கள்', 'செவ்வாய்', 'புதன்', 'வியாழன்', 'வெள்ளி', 'வெள்ளிக்கிழமை', 'ஞாயிறு'],
		weekSundayStartTextList: ['ஞாயிறு', 'திங்கள்', 'செவ்வாய்', 'புதன்', 'வியாழன்', 'வெள்ளி', 'வெள்ளிக்கிழமை'],
		monthTextList: [
			'ஜனவரி',
			'பிப்ரவரி',
			'மார்ச்',
			'ஏப்ரல்',
			'மே',
			'ஜூன்',
			'ஜூலை',
			'ஆகஸ்ட்',
			'செப்டம்பர்',
			'அக்டோபர்',
			'நவம்பர்',
			'டிசம்பர்'
		],
		confirmText: 'உறுதிசெய்',
		selectedText: 'தேர்ந்தெடுக்கப்பட்டது',
		dayText: 'நாள்',
		beforeText: 'முன்னுரில்',
		afterText: 'பின்னுரில்',
		currentWeekText: 'இந்த வாரம்',
		currentMonthText: 'இந்த மாதம்',
		currentQuarterText: 'இந்த காலாண்டு'
	}
};

export default ta_IN;



================================================
FILE: packages/stdf/src/lib/lang/th_TH.ts
================================================
import type { LangProps } from './index.js';

const th_TH: LangProps = {
	common: {
		slotEmpty: 'ไม่มีข้อมูล',
		loading: 'กำลังโหลด...',
		noData: 'ไม่มีข้อมูล',
		noMoreData: 'ไม่มีข้อมูลเพิ่มเติม',
		done: 'เสร็จสิ้น'
	},
	actionSheet: {
		cancelText: 'ยกเลิก'
	},
	bottomSheet: {
		title: 'กรุณาเลือก'
	},
	dialog: {
		title: 'แจ้งเตือน',
		content: 'ข้อความ',
		primaryText: 'ตกลง',
		secondaryText: 'ยกเลิก'
	},
	input: {
		pleaseInput: 'กรุณากรอกข้อมูล'
	},
	modal: {
		title: 'กรุณายืนยัน',
		content: 'ข้อความ',
		btnText: 'ตกลง'
	},
	navBar: {
		title: 'หัวเรื่อง'
	},
	pagination: {
		defaultOnlyOnePage: 'เพียงหน้าเดียว'
	},
	picker: {
		defaultTitle: 'กรุณาเลือก',
		defaultCancel: 'ยกเลิก',
		defaultConfirm: 'ตกลง'
	},
	asyncPicker: {
		defaultTitle: 'กรุณาเลือก',
		defaultCancel: 'ยกเลิก',
		defaultConfirm: 'ตกลง',
		defaultNext: 'ต่อไป',
		defaultPrev: 'ก่อนหน้า',
		defaultSelected: 'เลือกแล้ว'
	},
	rate: {
		error1: 'การประเมินผลล้มเหลว!',
		error2: 'การประเมินผลต้องมีอย่างน้อย 1 ดาว!',
		error3: 'การประเมินที่ดีต้องน้อยกว่าหรือเท่ากับ 1 ดาว!',
		error4: 'การประเมินเฉลี่ยต้องน้อยกว่าหรือเท่ากับ 1 ดาว!',
		error5: 'การให้คะแนนต้องน้อยกว่าหรือเท่ากับขีดจำกัด!'
	},
	timePicker: {
		defaultTitle: 'กรุณาเลือกเวลา',
		defaultCancel: 'ยกเลิก',
		defaultConfirm: 'ตกลง',
		defaultYear: 'ปี',
		defaultMonth: 'เดือน',
		defaultDay: 'วัน',
		defaultHour: 'ชั่วโมง',
		defaultMinute: 'นาที',
		defaultSecond: 'วินาที'
	},
	calendar: {
		weekTextList: ['อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.'],
		weekSundayStartTextList: ['อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.'],
		monthTextList: ['ม.ค.', 'ก.พ.', 'มี.ค.', 'เม.ย.', 'พ.ค.', 'มิ.ย.', 'ก.ค.', 'ส.ค.', 'ก.ย.', 'ต.ค.', 'พ.ย.', 'ธ.ค.'],
		confirmText: 'ตกลง',
		selectedText: 'ที่เลือก',
		dayText: 'วัน',
		beforeText: 'ก่อนหน้า',
		afterText: 'หลังจาก',
		currentWeekText: 'สัปดาห์นี้',
		currentMonthText: 'เดือนนี้',
		currentQuarterText: 'ไตรมาสนี้'
	}
};

export default th_TH;



================================================
FILE: packages/stdf/src/lib/lang/tk_TK.ts
================================================
import type { LangProps } from './index.js';

const tk_TK: LangProps = {
	common: {
		slotEmpty: 'Maglumat ýok',
		loading: 'Ýüklenýär...',
		noData: 'Maglumat ýok',
		noMoreData: 'Köp maglumat ýok',
		done: 'Tamam'
	},
	actionSheet: {
		cancelText: 'Gurnama'
	},
	bottomSheet: {
		title: 'Saýlaň'
	},
	dialog: {
		title: 'Bildiriş',
		content: 'Mazmun',
		primaryText: 'OK',
		secondaryText: 'Gurnama'
	},
	input: {
		pleaseInput: 'Eçow giriziň'
	},
	modal: {
		title: 'Tassyklaň',
		content: 'Mazmun',
		btnText: 'OK'
	},
	navBar: {
		title: 'Başlyk'
	},
	pagination: {
		defaultOnlyOnePage: 'Bir sahypa'
	},
	picker: {
		defaultTitle: 'Saýlaň',
		defaultCancel: 'Gurnama',
		defaultConfirm: 'OK'
	},
	asyncPicker: {
		defaultTitle: 'Saýlaň',
		defaultCancel: 'Gurnama',
		defaultConfirm: 'OK',
		defaultNext: 'Indiki',
		defaultPrev: 'Öňki',
		defaultSelected: 'Saýlandy'
	},
	rate: {
		error1: 'Derecelendirme doly bolmady!',
		error2: 'Iň az bir ýyldyz derejesi gerekli!',
		error3: 'Dürli derecelendirme-iň az bir ýyldyz derejesi talap edýär!',
		error4: 'Ýekinç derecelendiriljegine iň az bir ýyldyz derejesi talap edýär!',
		error5: 'Derecelendirme-gatnaşyklaryň derejeleri pişirilme-gatnaşygyndan ýokarny!'
	},
	timePicker: {
		defaultTitle: 'Zaman saýlaň',
		defaultCancel: 'Gurnama',
		defaultConfirm: 'OK',
		defaultYear: 'Ýyl',
		defaultMonth: 'Aý',
		defaultDay: 'Gün',
		defaultHour: 'Sagat',
		defaultMinute: 'Munyt',
		defaultSecond: 'Saniýe'
	},
	calendar: {
		weekTextList: ['Ys', 'Ys', 'Ar', 'Çä', 'Pe', 'Ýa', 'Şe'],
		weekSundayStartTextList: ['Ýs', 'Ýs', 'Ar', 'Çä', 'Pe', 'Ýa', 'Şe'],
		monthTextList: ['Ýan', 'Few', 'Mar', 'Apr', 'Maý', 'Iýun', 'Iýul', 'Awg', 'Sen', 'Okt', 'Noý', 'Dek'],
		confirmText: 'OK',
		selectedText: 'Saýlandy',
		dayText: 'Gün',
		beforeText: 'Öňki',
		afterText: 'Soňky',
		currentWeekText: 'Bu hepde',
		currentMonthText: 'Bu aý',
		currentQuarterText: 'Bu çärýek'
	}
};

export default tk_TK;



================================================
FILE: packages/stdf/src/lib/lang/tr_TR.ts
================================================
import type { LangProps } from './index.js';

const tr_TR: LangProps = {
	common: {
		slotEmpty: 'Veri yok',
		loading: 'Yükleniyor...',
		noData: 'Veri yok',
		noMoreData: 'Daha fazla veri yok',
		done: 'Tamam'
	},
	actionSheet: {
		cancelText: 'İptal'
	},
	bottomSheet: {
		title: 'Lütfen seçiniz'
	},
	dialog: {
		title: 'Uyarı',
		content: 'İçerik',
		primaryText: 'Tamam',
		secondaryText: 'İptal'
	},
	input: {
		pleaseInput: 'Lütfen giriş yapınız'
	},
	modal: {
		title: 'Onay',
		content: 'İçerik',
		btnText: 'Tamam'
	},
	navBar: {
		title: 'Başlık'
	},
	pagination: {
		defaultOnlyOnePage: 'Sadece bir sayfa'
	},
	picker: {
		defaultTitle: 'Lütfen seçiniz',
		defaultCancel: 'İptal',
		defaultConfirm: 'Tamam'
	},
	asyncPicker: {
		defaultTitle: 'Lütfen seçiniz',
		defaultCancel: 'İptal',
		defaultConfirm: 'Tamam',
		defaultNext: 'Sonraki',
		defaultPrev: 'Önceki',
		defaultSelected: 'Seçili'
	},
	rate: {
		error1: 'Oylama başarısız oldu!',
		error2: 'En az 1 yıldız değerlendirmesi gereklidir!',
		error3: 'İyi bir değerlendirme en az 1 yıldız değerlendirmesi gerektirir!',
		error4: 'Ortalama derecelendirme 1 yıldızın altında olmalıdır!',
		error5: 'Oylama, sınırın altında olmalıdır!'
	},
	timePicker: {
		defaultTitle: 'Lütfen bir tarih seçin',
		defaultCancel: 'İptal',
		defaultConfirm: 'Tamam',
		defaultYear: 'Yıl',
		defaultMonth: 'Ay',
		defaultDay: 'Gün',
		defaultHour: 'Saat',
		defaultMinute: 'Dakika',
		defaultSecond: 'Saniye'
	},
	calendar: {
		weekTextList: ['Pz', 'Pt', 'Sa', 'Ça', 'Pe', 'Cu', 'Ct'],
		weekSundayStartTextList: ['Pa', 'Pt', 'Sa', 'Ça', 'Pe', 'Cu', 'Ct'],
		monthTextList: ['Oca', 'Şub', 'Mar', 'Nis', 'May', 'Haz', 'Tem', 'Ağu', 'Eyl', 'Eki', 'Kas', 'Ara'],
		confirmText: 'Tamam',
		selectedText: 'Seçildi',
		dayText: 'Gün',
		beforeText: 'Önce',
		afterText: 'Sonra',
		currentWeekText: 'Bu hafta',
		currentMonthText: 'Bu ay',
		currentQuarterText: 'Bu çeyrek'
	}
};

export default tr_TR;



================================================
FILE: packages/stdf/src/lib/lang/uk_UA.ts
================================================
import type { LangProps } from './index.js';

const uk_UA: LangProps = {
	common: {
		slotEmpty: 'Немає даних',
		loading: 'Завантаження...',
		noData: 'Немає даних',
		noMoreData: 'Немає більше даних',
		done: 'Готово'
	},
	actionSheet: {
		cancelText: 'Скасувати'
	},
	bottomSheet: {
		title: 'Виберіть'
	},
	dialog: {
		title: 'Повідомлення',
		content: 'Зміст',
		primaryText: 'OK',
		secondaryText: 'Скасувати'
	},
	input: {
		pleaseInput: 'Будь ласка, введіть'
	},
	modal: {
		title: 'Підтвердження',
		content: 'Зміст',
		btnText: 'OK'
	},
	navBar: {
		title: 'Назва'
	},
	pagination: {
		defaultOnlyOnePage: 'Тільки одна сторінка'
	},
	picker: {
		defaultTitle: 'Виберіть',
		defaultCancel: 'Скасувати',
		defaultConfirm: 'OK'
	},
	asyncPicker: {
		defaultTitle: 'Виберіть',
		defaultCancel: 'Скасувати',
		defaultConfirm: 'OK',
		defaultNext: 'Далі',
		defaultPrev: 'Назад',
		defaultSelected: 'Обрано'
	},
	rate: {
		error1: 'Невдала оцінка!',
		error2: 'Необхідно хоча б одну зірку!',
		error3: 'Для правильної оцінки потрібно хоча б одну зірку!',
		error4: 'Для середньої оцінки потрібно хоча б одну зірку!',
		error5: 'Оцінка не відповідає принципам рейтингування!'
	},
	timePicker: {
		defaultTitle: 'Виберіть час',
		defaultCancel: 'Скасувати',
		defaultConfirm: 'OK',
		defaultYear: 'Рік',
		defaultMonth: 'Місяць',
		defaultDay: 'День',
		defaultHour: 'Година',
		defaultMinute: 'Хвилина',
		defaultSecond: 'Секунда'
	},
	calendar: {
		weekTextList: ['Нд', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],
		weekSundayStartTextList: ['Нд', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],
		monthTextList: [
			'Січень',
			'Лютий',
			'Березень',
			'Квітень',
			'Травень',
			'Червень',
			'Липень',
			'Серпень',
			'Вересень',
			'Жовтень',
			'Листопад',
			'Грудень'
		],
		confirmText: 'OK',
		selectedText: 'Обрано',
		dayText: 'День ',
		beforeText: 'До ',
		afterText: 'Після ',
		currentWeekText: 'Поточний тиждень',
		currentMonthText: 'Поточний місяць',
		currentQuarterText: 'Поточний квартал'
	}
};

export default uk_UA;



================================================
FILE: packages/stdf/src/lib/lang/ur_PK.ts
================================================
import type { LangProps } from './index.js';

const ur_PK: LangProps = {
	common: {
		slotEmpty: 'کوئی ڈیٹا نہیں',
		loading: 'لوڈ ہو رہا ہے ...',
		noData: 'کوئی ڈیٹا نہیں',
		noMoreData: 'کوئی زیادہ ڈیٹا نہیں',
		done: 'تمام'
	},
	actionSheet: {
		cancelText: 'منسوخ'
	},
	bottomSheet: {
		title: 'منتخب کریں'
	},
	dialog: {
		title: 'الرٹ',
		content: 'مواد',
		primaryText: 'ٹھیک ہے',
		secondaryText: 'منسوخ'
	},
	input: {
		pleaseInput: 'براہ کرم انپٹ کریں'
	},
	modal: {
		title: 'تصدیق کریں',
		content: 'مواد',
		btnText: 'ٹھیک ہے'
	},
	navBar: {
		title: 'عنوان'
	},
	pagination: {
		defaultOnlyOnePage: 'صرف ایک صفحہ'
	},
	picker: {
		defaultTitle: 'منتخب کریں',
		defaultCancel: 'منسوخ',
		defaultConfirm: 'ٹھیک ہے'
	},
	asyncPicker: {
		defaultTitle: 'منتخب کریں',
		defaultCancel: 'منسوخ',
		defaultConfirm: 'ٹھیک ہے',
		defaultNext: 'اگلا',
		defaultPrev: 'پچھلا',
		defaultSelected: 'منتخب'
	},
	rate: {
		error1: 'درجہ بندی ناکام ہوگی!',
		error2: 'کم از کم ایک ستارہ درجہ ضروری ہے!',
		error3: 'ایک درست درجہ کے لئے کم از کم ایک ستارہ کی درجہ بندی درکار ہے!',
		error4: 'ایک اوسط درجہ کے لئے کم از کم ایک ستارہ کی درجہ بندی درکار ہے!',
		error5: 'ریٹنگ بالکل مناسب نہیں ہے!'
	},
	timePicker: {
		defaultTitle: 'وقت منتخب کریں',
		defaultCancel: 'منسوخ',
		defaultConfirm: 'ٹھیک ہے',
		defaultYear: 'سال',
		defaultMonth: 'مہینہ',
		defaultDay: 'دن',
		defaultHour: 'گھنٹہ',
		defaultMinute: 'منٹ',
		defaultSecond: 'سیکنڈ'
	},
	calendar: {
		weekTextList: ['اتوار', 'پیر', 'منگل', 'بدھ', 'جمعرات', 'جمعہ', 'ہفتہ'],
		weekSundayStartTextList: ['ایک', 'دو', 'تین', 'چار', 'پانچ', 'چھہ', 'ہفتہ'],
		monthTextList: ['جنوری', 'فروری', 'مارچ', 'اپریل', 'مئی', 'جون', 'جولائی', 'اگست', 'ستمبر', 'اکتوبر', 'نومبر', 'دسمبر'],
		confirmText: 'ٹھیک ہے',
		selectedText: 'منتخب شدہ',
		dayText: 'دن',
		beforeText: 'پہلے',
		afterText: 'بعد میں',
		currentWeekText: 'اس ہفتے',
		currentMonthText: 'اس مہینہ',
		currentQuarterText: 'اس ترکیب'
	}
};

export default ur_PK;



================================================
FILE: packages/stdf/src/lib/lang/vi_VN.ts
================================================
import type { LangProps } from './index.js';

const vi_VN: LangProps = {
	common: {
		slotEmpty: 'Không có dữ liệu',
		loading: 'Đang tải...',
		noData: 'Không có dữ liệu',
		noMoreData: 'Không còn dữ liệu',
		done: 'Xong'
	},
	actionSheet: {
		cancelText: 'Hủy'
	},
	bottomSheet: {
		title: 'Chọn'
	},
	dialog: {
		title: 'Thông báo',
		content: 'Nội dung',
		primaryText: 'OK',
		secondaryText: 'Hủy'
	},
	input: {
		pleaseInput: 'Vui lòng nhập'
	},
	modal: {
		title: 'Xác nhận',
		content: 'Nội dung',
		btnText: 'OK'
	},
	navBar: {
		title: 'Tiêu đề'
	},
	pagination: {
		defaultOnlyOnePage: 'Chỉ có một trang'
	},
	picker: {
		defaultTitle: 'Chọn',
		defaultCancel: 'Hủy',
		defaultConfirm: 'OK'
	},
	asyncPicker: {
		defaultTitle: 'Chọn',
		defaultCancel: 'Hủy',
		defaultConfirm: 'OK',
		defaultNext: 'Tiếp theo',
		defaultPrev: 'Trước đó',
		defaultSelected: 'Đã chọn'
	},
	rate: {
		error1: 'Đánh giá không thành công!',
		error2: 'Cần ít nhất một sao!',
		error3: 'Cần ít nhất một sao để đánh giá chính xác!',
		error4: 'Cần ít nhất một sao để đánh giá trung bình!',
		error5: 'Đánh giá không phù hợp với nguyên tắc đánh giá!'
	},
	timePicker: {
		defaultTitle: 'Chọn thời gian',
		defaultCancel: 'Hủy',
		defaultConfirm: 'OK',
		defaultYear: 'Năm',
		defaultMonth: 'Tháng',
		defaultDay: 'Ngày',
		defaultHour: 'Giờ',
		defaultMinute: 'Phút',
		defaultSecond: 'Giây'
	},
	calendar: {
		weekTextList: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'],
		weekSundayStartTextList: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'],
		monthTextList: [
			'Tháng 1',
			'Tháng 2',
			'Tháng 3',
			'Tháng 4',
			'Tháng 5',
			'Tháng 6',
			'Tháng 7',
			'Tháng 8',
			'Tháng 9',
			'Tháng 10',
			'Tháng 11',
			'Tháng 12'
		],
		confirmText: 'OK',
		selectedText: 'Đã chọn',
		dayText: 'Ngày ',
		beforeText: 'Trước ',
		afterText: 'Sau ',
		currentWeekText: 'Tuần này',
		currentMonthText: 'Tháng này',
		currentQuarterText: 'Quý này'
	}
};

export default vi_VN;



================================================
FILE: packages/stdf/src/lib/lang/zh_CN.ts
================================================
import type { LangProps } from './index.js';

const zh_CN: LangProps = {
	common: {
		slotEmpty: '插槽内容为空！',
		loading: '加载中...',
		noData: '暂无数据',
		noMoreData: '没有更多数据了',
		done: '完成'
	},
	actionSheet: {
		cancelText: '取消'
	},
	bottomSheet: {
		title: '标题'
	},
	dialog: {
		title: '提示',
		content: '内容',
		primaryText: '确定',
		secondaryText: '取消'
	},
	input: {
		pleaseInput: '请输入'
	},
	modal: {
		title: '标题',
		content: '内容',
		btnText: '我知道了'
	},
	navBar: {
		title: '标题'
	},
	pagination: {
		defaultOnlyOnePage: '只有一页'
	},
	picker: {
		defaultTitle: '请选择',
		defaultCancel: '取消',
		defaultConfirm: '确定'
	},
	asyncPicker: {
		defaultTitle: '请选择',
		defaultCancel: '取消',
		defaultConfirm: '确定',
		defaultNext: '下一步',
		defaultPrev: '上一步',
		defaultSelected: '已选'
	},
	rate: {
		error1: 'value 不能大于 total!',
		error2: 'total 必须能被 1 整除！',
		error3: '非半选时 value 必须能被 1 整除！',
		error4: '半选时 value 必须能被 0.5 整除！',
		error5: 'width 或 height 小于 20 会使移动端点击困难！'
	},
	timePicker: {
		defaultTitle: '请选择',
		defaultCancel: '取消',
		defaultConfirm: '确定',
		defaultYear: '年',
		defaultMonth: '月',
		defaultDay: '日',
		defaultHour: '时',
		defaultMinute: '分',
		defaultSecond: '秒'
	},
	calendar: {
		weekTextList: ['一', '二', '三', '四', '五', '六', '日'],
		weekSundayStartTextList: ['日', '一', '二', '三', '四', '五', '六'],
		monthTextList: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
		confirmText: '确认',
		selectedText: '已选',
		dayText: '天',
		beforeText: '最近',
		afterText: '未来',
		currentWeekText: '本周',
		currentMonthText: '本月',
		currentQuarterText: '本季度'
	}
};

export default zh_CN;



================================================
FILE: packages/stdf/src/lib/lang/zh_HK.ts
================================================
import type { LangProps } from './index.js';

const zh_HK: LangProps = {
	common: {
		slotEmpty: '插槽內容為空！',
		loading: '載入中...',
		noData: '暫無數據',
		noMoreData: '沒有更多數據了',
		done: '完成'
	},
	actionSheet: {
		cancelText: '取消'
	},
	bottomSheet: {
		title: '標題'
	},
	dialog: {
		title: '提示',
		content: '內容',
		primaryText: '確定',
		secondaryText: '取消'
	},
	input: {
		pleaseInput: '請輸入'
	},
	modal: {
		title: '標題',
		content: '內容',
		btnText: '我知道了'
	},
	navBar: {
		title: '標題'
	},
	pagination: {
		defaultOnlyOnePage: '只有一頁'
	},
	picker: {
		defaultTitle: '請選擇',
		defaultCancel: '取消',
		defaultConfirm: '確定'
	},
	asyncPicker: {
		defaultTitle: '請選擇',
		defaultCancel: '取消',
		defaultConfirm: '確定',
		defaultNext: '下一步',
		defaultPrev: '上一步',
		defaultSelected: '已選'
	},
	rate: {
		error1: 'value 不能大於 total !',
		error2: 'total 必須能被 1 整除！',
		error3: '非半選時 value 必須能被 1 整除！',
		error4: '半選時 value 必須能被 0.5 整除！',
		error5: 'width 或 height 小於 20 會使移動端點擊困難！'
	},
	timePicker: {
		defaultTitle: '請選擇',
		defaultCancel: '取消',
		defaultConfirm: '確定',
		defaultYear: '年',
		defaultMonth: '月',
		defaultDay: '日',
		defaultHour: '時',
		defaultMinute: '分',
		defaultSecond: '秒'
	},
	calendar: {
		weekTextList: ['一', '二', '三', '四', '五', '六', '日'],
		weekSundayStartTextList: ['日', '一', '二', '三', '四', '五', '六'],
		monthTextList: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
		confirmText: '確認',
		selectedText: '已選',
		dayText: '天',
		beforeText: '最近',
		afterText: '未來',
		currentWeekText: '本週',
		currentMonthText: '本月',
		currentQuarterText: '本季度'
	}
};

export default zh_HK;



================================================
FILE: packages/stdf/src/lib/lang/zh_TW.ts
================================================
import type { LangProps } from './index.js';

const zh_TW: LangProps = {
	common: {
		slotEmpty: '插槽內容為空！',
		loading: '載入中...',
		noData: '暫無數據',
		noMoreData: '沒有更多數據了',
		done: '完成'
	},
	actionSheet: {
		cancelText: '取消'
	},
	bottomSheet: {
		title: '標題'
	},
	dialog: {
		title: '提示',
		content: '內容',
		primaryText: '確定',
		secondaryText: '取消'
	},
	input: {
		pleaseInput: '請輸入'
	},
	modal: {
		title: '標題',
		content: '內容',
		btnText: '我知道了'
	},
	navBar: {
		title: '標題'
	},
	pagination: {
		defaultOnlyOnePage: '只有一頁'
	},
	picker: {
		defaultTitle: '請選擇',
		defaultCancel: '取消',
		defaultConfirm: '確定'
	},
	asyncPicker: {
		defaultTitle: '請選擇',
		defaultCancel: '取消',
		defaultConfirm: '確定',
		defaultNext: '下一步',
		defaultPrev: '上一步',
		defaultSelected: '已選'
	},
	rate: {
		error1: 'value 不能大於 total !',
		error2: 'total 必須能被 1 整除！',
		error3: '非半選時 value 必須能被 1 整除！',
		error4: '半選時 value 必須能被 0.5 整除！',
		error5: 'width 或 height 小於 20 會使移動端點擊困難！'
	},
	timePicker: {
		defaultTitle: '請選擇',
		defaultCancel: '取消',
		defaultConfirm: '確定',
		defaultYear: '年',
		defaultMonth: '月',
		defaultDay: '日',
		defaultHour: '時',
		defaultMinute: '分',
		defaultSecond: '秒'
	},
	calendar: {
		weekTextList: ['一', '二', '三', '四', '五', '六', '日'],
		weekSundayStartTextList: ['日', '一', '二', '三', '四', '五', '六'],
		monthTextList: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
		confirmText: '確認',
		selectedText: '已選',
		dayText: '天',
		beforeText: '最近',
		afterText: '未來',
		currentWeekText: '本週',
		currentMonthText: '本月',
		currentQuarterText: '本季度'
	}
};

export default zh_TW;



================================================
FILE: packages/stdf/src/lib/theme/darkMode.ts
================================================
/**
 * 给 HTML 元素增加或删除 dark 类名，实现 Mode 切换
 * Add or remove the dark class name to the HTML element to implement Mode switching
 * @example
 * darkMode(true) // 开启 dark 模式
 * darkMode(false) // 关闭 dark 模式
 */
const darkMode = (isDark: boolean = true): void => {
	if (isDark) {
		document.documentElement.classList.add('dark');
	} else {
		document.documentElement.classList.remove('dark');
	}
};

export default darkMode;



================================================
FILE: packages/stdf/src/lib/theme/index.ts
================================================
import darkMode from './darkMode.js';
import switchTheme from './switchTheme.js';
import STDFTheme from './stdf.js';
import type { ThemeProps, PrimaryAndDarkColor } from './types.js';

export { darkMode, switchTheme, STDFTheme, type ThemeProps, type PrimaryAndDarkColor };



================================================
FILE: packages/stdf/src/lib/theme/stdf.ts
================================================
import type { ThemeProps } from './types.js';

const STDFTheme: ThemeProps = {
	name: 'STDF',
	color: {
		primary: {
			50: 'oklch(0.979 0.01 267.36)', // #F5F8FF hsl(222, 100%, 98%)
			100: 'oklch(0.95 0.024 270.343)', // #E8EEFF hsl(224, 100%, 96%)
			200: 'oklch(0.847 0.074 271.188)', // #BBCBFE hsl(226, 97%, 87%)
			300: 'oklch(0.741 0.13 272.232)', // #8FA5FD hsl(228, 97%, 78%)
			400: 'oklch(0.634 0.193 271.595)', // #637CFD hsl(230, 98%, 69%)
			500: 'oklch(0.536 0.252 268.66)', // #3751FC hsl(232, 97%, 60%)
			default: 'oklch(0.467 0.296 264.886)', // #0B24FB hsl(234, 97%, 51%)
			700: 'oklch(0.397 0.26 264.877)', // #0714CF hsl(236, 94%, 42%)
			800: 'oklch(0.331 0.221 264.833)', // #0409A4 hsl(238, 95%, 33%)
			900: 'oklch(0.26 0.178 264.428)', // #010178 hsl(240, 98%, 24%)
			950: 'oklch(0.192 0.13 266.64)' // #03004D hsl(242, 100%, 15%)
		},
		dark: {
			50: 'oklch(0.995 0.012 101.474)', // #FFFEF5 hsl(54, 100%, 98%)
			100: 'oklch(0.986 0.025 97.107)', // #FFFBE8 hsl(50, 100%, 96%)
			200: 'oklch(0.965 0.059 95.884)', // #FFF4C7 hsl(48, 100%, 89%)
			300: 'oklch(0.938 0.089 92.952)', // #FFEAA6 hsl(46, 100%, 83%)
			400: 'oklch(0.91 0.114 89.711)', // #FFDE85 hsl(44, 100%, 76%)
			500: 'oklch(0.88 0.136 86.375)', // #FFD164 hsl(42, 100%, 70%)
			default: 'oklch(0.845 0.153 80.597)', // #FFC043 hsl(40, 100%, 63%)
			700: 'oklch(0.71 0.137 75.734)', // #D29429 hsl(38, 67%, 49%)
			800: 'oklch(0.58 0.118 70.166)', // #A66C16 hsl(36, 77%, 37%)
			900: 'oklch(0.449 0.097 65.209)', // #794808 hsl(34, 88%, 25%)
			950: 'oklch(0.321 0.074 62.379)' // #4D2900 hsl(32, 100%, 15%)
		},
		primaryBlack: 'oklch(0.116 0.054 267.087)', // #010319 hsl(234, 95%, 5%)
		primaryWhite: 'oklch(0.961 0.001 286.375)', // #F2F2F3 hsl(234, 5%, 95%)
		darkBlack: 'oklch(0.183 0.035 86.634)', // #191101 hsl(40, 95%, 5%)
		darkWhite: 'oklch(0.962 0.001 17.178)', // #F3F2F2 hsl(40, 5%, 95%)
		functional: {
			success: 'oklch(0.704 0.142 167.084)', // #11bb8d hsl(164, 83%, 40%)
			warning: 'oklch(0.558 0.154 47.186)', // #b95000 hsl(26, 100%, 36%)
			error: 'oklch(0.564 0.223 28.46)', // #da1414 hsl(0, 83%, 47%)
			info: 'oklch(0.482 0.14 261.518)' // #2e5aac hsl(219, 58%, 43%)
		},
		extend: [
			{
				color: 'oklch(0.703 0.149 235.059)', // #00acee hsl(197, 100%, 47%)
				alias: 'Twitter'
			},
			{
				color: 'oklch(0.702 0.194 38.137)', // #ff6937 hsl(15, 100%, 61%)
				alias: 'Svelte'
			},
			{
				color: 'oklch(0.482 0.107 161.212)', // #00704a hsl(160, 100%, 22%)
				alias: 'Starbucks'
			}
		]
	}
};

export default STDFTheme;



================================================
FILE: packages/stdf/src/lib/theme/switchTheme.ts
================================================
import type { ThemeProps } from './types.js';

/**
 * 给 HTML 元素设置 CSS 变量，用于切换主题
 * Let the HTML element set the CSS variable for switching themes
 * @example
 * setPropertyFunc('--primary', '#000000');
 */
const setPropertyFunc: (name: string, value: string) => void = (name, value) => {
	document.documentElement.style.setProperty(name, value);
};

/**
 * 切换主题
 * Switch theme
 * @example
 * import { stdfTheme } from 'stdf/theme';
 * switchTheme(stdfTheme);
 */
const switchTheme = (theme: ThemeProps): void => {
	const { color } = theme;
	for (const [key, value] of Object.entries(color.primary)) {
		setPropertyFunc(key === 'default' ? '--color-primary' : `--color-primary-${key}`, value);
	}
	for (const [key, value] of Object.entries(color.dark)) {
		setPropertyFunc(key === 'default' ? '--color-dark' : `--color-dark-${key}`, value);
	}
	setPropertyFunc('--color-success', color.functional.success);
	setPropertyFunc('--color-warning', color.functional.warning);
	setPropertyFunc('--color-error', color.functional.error);
	setPropertyFunc('--color-info', color.functional.info);
	setPropertyFunc('--color-primaryBlack', color.primaryBlack);
	setPropertyFunc('--color-primaryWhite', color.primaryWhite);
	setPropertyFunc('--color-darkBlack', color.darkBlack);
	setPropertyFunc('--color-darkWhite', color.darkWhite);
	if (color.extend.length > 0) {
		color.extend.forEach((item, i) => {
			if ('color' in item) {
				setPropertyFunc(`--color-extend${i}`, item.color);
				setPropertyFunc(`--color-${item.alias}`, item.color);
			}
		});
	}
};

export default switchTheme;



================================================
FILE: packages/stdf/src/lib/theme/types.ts
================================================
export type PrimaryAndDarkColor = {
	50: string;
	100: string;
	200: string;
	300: string;
	400: string;
	500: string;
	default: string;
	700: string;
	800: string;
	900: string;
	950: string;
};

export type ThemeProps = {
	name: string;
	color: {
		primary: PrimaryAndDarkColor;
		dark: PrimaryAndDarkColor;
		primaryBlack: string;
		primaryWhite: string;
		darkBlack: string;
		darkWhite: string;
		functional: { success: string; warning: string; error: string; info: string };
		extend: { color: string; alias: string }[];
	};
};



================================================
FILE: packages/stdf/src/lib/types/index.ts
================================================
import type { Snippet, Component } from 'svelte';

export type ActionProps = {
	content: string;
	style?: 'normal' | 'theme' | 'danger' | 'disabled';
	desc?: string;
	showImg?: boolean;
	imgRadius?: 'none' | 'sm' | 'full' | 'lg';
	imgSrc?: string;
};
export type ActionSheetProps = {
	visible?: boolean;
	title?: string;
	titleAlign?: 'left' | 'center' | 'right';
	actions?: ActionProps[];
	popup?: PopupProps;
	showCancel?: boolean;
	cancelText?: string;
	actionClosable?: boolean;
	align?: 'left' | 'center' | 'right';
	oncancel?: () => void;
	onclickAction?: (index: number, action: ActionProps) => void;
	onclose?: () => void;
};

export type AsyncPickerProps = {
	visible?: boolean;
	data?: Record<string, unknown>[];
	lastLevel?: boolean;
	firstLevel?: boolean;
	showRow?: 3 | 5 | 7;
	labelKey?: string;
	align?: 'left' | 'center' | 'right';
	cancelText?: string;
	confirmText?: string;
	title?: string;
	nextText?: string;
	prevText?: string;
	showSelected?: boolean;
	selectedText?: string;
	popup?: PopupProps;
	loading?: LoadingProps;
	oncancel?: () => void;
	onprev?: () => void;
	onconfirm?: (items: Record<string, unknown>[], indexs: number[]) => void;
	onnext?: (index: number) => void;
	onclose?: () => void;
};

export type AvatarProps = {
	image?: string;
	alt?: string;
	icon?: IconProps;
	altSize?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
	radius?: 'none' | 'sm' | 'xl' | '2xl' | '3xl' | 'full';
	size?: 'xs' | 'sm' | 'base' | 'md' | 'lg' | 'xl' | '2xl';
	imgSize?: 's' | 'm' | 'l';
	line?: 'none' | 'solid' | 'dashed' | 'dotted';
	injClass?: string;
	onclick?: () => void;
};
export type AvatarsProps = {
	data: AvatarProps[];
	radius?: 'none' | 'sm' | 'xl' | '2xl' | '3xl' | 'full';
	size?: 'xs' | 'sm' | 'base' | 'md' | 'lg' | 'xl' | '2xl';
	compact?: number;
	lineWidth?: '0' | '1' | '2' | '3' | '4' | '8';
	reverse?: boolean;
	max?: number;
	top?: 'totle' | 'add' | null | Snippet;
	injClass?: string;
	onclick?: () => void;
};

export type BadgeProps = {
	text?: string;
	radius?: 'full' | 'sm' | 'none' | 'leaf';
	isLeft?: boolean;
	isShow?: boolean;
	offsetY?: number;
	offsetX?: number;
	isInner?: boolean;
	injClass?: string;
	children?: Snippet;
};

export type BottomSheetProps = {
	visible?: boolean;
	title?: string;
	titleAlign?: 'left' | 'center' | 'right';
	showBackIcon?: boolean;
	closeContent?: 'downIcon' | 'closeIcon' | '' | string;
	showDivider?: boolean;
	duration?: number;
	outDuration?: number;
	mask?: MaskProps;
	maskClosable?: boolean;
	zIndex?: number;
	stayHeightList?: number[];
	stayHeightIndex?: number;
	closeHeight?: number;
	radius?: 'none' | 'middle' | 'full';
	children?: Snippet;
	onheightChange?: (height: number) => void;
	onclickMask?: () => void;
	onclose?: () => void;
	onback?: () => void;
};

export type ButtonProps = {
	fill?: 'base' | 'line' | 'lineLight' | 'lineTheme' | 'text' | 'textTheme' | 'colorLight';
	state?: 'theme' | 'success' | 'warning' | 'error' | 'info';
	radius?: 'none' | 'sm' | 'xl' | '2xl' | 'full';
	size?: 'full' | 'big' | 'md' | 'sm' | 'auto';
	line?: 'solid' | 'dashed' | 'dotted';
	injClass?: string;
	love?: boolean;
	heightOut?: '0' | '1' | '2' | '3' | '4';
	heightIn?: '0' | '1' | '2' | '3' | '4';
	group?: boolean;
	disabled?: boolean;
	customSize?: boolean;
	customWidth?: number;
	customHeight?: number;
	icon?: IconProps | null;
	loading?: LoadingProps | null;
	disabledLoading?: boolean;
	type?: 'submit' | 'reset' | 'button';
	children?: Snippet;
	onclick?: () => void;
};

export type InfoDateProps = { text: string; info: string };
export type CalendarProps = {
	visible?: boolean;
	startMonth?: string;
	endMonth?: string;
	initMonth?: string;
	mode?: 'single' | 'multiple' | 'range';
	startSunday?: boolean;
	weekendRed?: boolean;
	monthCard?: boolean;
	monthMark?: boolean;
	monthMarkSize?: '3xl' | '4xl' | '5xl' | '6xl' | '7xl' | '8xl' | '9xl';
	height?: number;
	infoDates?: InfoDateProps[];
	disabledDates?: string[];
	radius?: 'none' | 'sm' | 'xl' | '2xl';
	showSelectedDay?: boolean;
	confirmText?: string;
	selectedText?: string;
	dayText?: string;
	quickSelects?: ('week' | 'month' | 'quarter' | number)[];
	includeToday?: boolean;
	useAnimation?: boolean;
	highlightToday?: boolean;
	outFormat?: string;
	popup?: PopupProps;
	button?: ButtonProps;
	clear?: boolean;
	onconfirm?: (dates: string[]) => void;
	onclose?: () => void;
};

export type CellRightProps = { type: 'switch' | 'icon'; switch?: SwitchProps; icon?: IconProps };
export type CellProps = {
	title?: string;
	detail?: string;
	right?: null | 'arrow' | CellRightProps;
	left?: null | IconProps;
	subTitle?: string;
	info?: string;
	line?: boolean;
	my?: '0' | '1' | '2' | '3' | '4' | '6' | '8';
	mx?: '0' | '1' | '2' | '3' | '4' | '6' | '8';
	radius?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full';
	switchActive?: boolean;
	shadow?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
	injClass?: string;
	love?: boolean;
	clickAll?: boolean;
	leftChild?: Snippet;
	rightChild?: Snippet;
	detailChild?: Snippet;
	onclick?: () => void;
};
export type CellGroupProps = {
	radius?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full';
	shadow?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
	my?: '0' | '1' | '2' | '3' | '4' | '6' | '8';
	mx?: '0' | '1' | '2' | '3' | '4' | '6' | '8';
	children?: Snippet;
};

export type CheckboxItemProps = {
	name: string;
	label?: string;
	layout?: 'h' | 'v' | 'inline';
	textPosition?: 'l' | 'r' | 't' | 'b';
	icon?: null | 'default' | IconProps;
	iconChecked?: null | 'default' | IconProps;
	checked?: boolean;
	children?: Snippet;
	onclick?: (name: string) => void;
};
export type CheckboxProps = {
	data: CheckboxItemProps[];
	layout?: 'h' | 'v' | 'inline';
	checkeds?: string[];
	textPosition?: 'l' | 'r' | 't' | 'b';
	icon?: null | 'default' | IconProps;
	iconChecked?: null | 'default' | IconProps;
	checkboxChild?: Snippet<[{ item: CheckboxItemProps & Record<string, unknown> }]>;
	onchange?: (checkeds: string[]) => void;
};

export type DialogProps = {
	visible?: boolean;
	title?: string;
	titleAlign?: 'left' | 'center' | 'right';
	content?: string;
	popup?: PopupProps;
	showIcon?: boolean;
	icon?: IconProps;
	btnStyle?: 'button' | 'text' | 'textLine';
	primaryText?: string;
	primaryButton?: ButtonProps;
	secondaryText?: string;
	secondaryButton?: ButtonProps;
	btnRatio?: [number, number];
	btnReverse?: boolean;
	secondaryClose?: boolean;
	btnGap?: '0' | '1' | '2' | '4' | '8' | '12' | '16';
	onsecondary?: () => void;
	onprimary?: () => void;
	onclose?: () => void;
	contentChild?: Snippet;
	primaryChild?: Snippet;
};

export type DividerProps = {
	layout?: 'h' | 'v';
	px?: '0' | '4' | '8' | '16' | '36';
	py?: '0' | '4' | '8';
	text?: string;
	align?: 'left' | 'center' | 'right';
	line?: 'solid' | 'dashed' | 'dotted';
	mx?: '1' | '2' | '4';
	weight?: '1' | '2' | '4';
	injClass?: string;
};

export type GridProps = {
	col?: '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12';
	row?: '1' | '2' | '3' | '4' | '5' | '6';
	children?: Snippet;
};
export type GridsProps = {
	cols?: '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12';
	gap?: '0' | '1' | '2' | '4' | '8';
	mx?: '0' | '1' | '2' | '4' | '8';
	my?: '0' | '1' | '2' | '4' | '8';
	children?: Snippet;
};

export type IconProps = {
	name?: string;
	size?: number | 'full';
	theme?: boolean;
	alpha?: number;
	path?: string;
	top?: number;
	injClass?: string;
	children?: Snippet;
	onclick?: () => void;
};

export type IndexBarItemProps = {
	index: string;
	title: string;
	child: string[];
	height?: number;
};
export type IndexBarProps = {
	data: IndexBarItemProps[];
	current?: number;
	top?: number;
	height: number;
	radius?: 'none' | 'middle' | 'full';
	scrollAlign?: boolean;
	titleInjClass?: string;
	textInjClass?: string;
	onclickChild?: (index: number, group: IndexBarItemProps, childIndex: number, child: string) => void;
};

export type InputProps = {
	title?: string;
	titlePosition?: 'in' | 'out' | null;
	inputPosition?: 'left' | 'right';
	placeholder?: string;
	radius?: 'none' | 'sm' | 'xl' | 'full';
	inputStyle?: 'block' | 'line';
	lineTransition?: null | 'center' | 'left';
	duration?: 'fast' | 'base' | 'slow' | 'slower';
	autocomplete?: boolean;
	py?: '0' | '0.5' | '1' | '2' | '3' | '4' | '6';
	disabled?: boolean;
	state?: 'theme' | 'success' | 'warning' | 'error' | 'info';
	type?: 'text' | 'decimal' | 'email' | 'none' | 'numeric' | 'search' | 'tel' | 'url' | 'password' | 'number' | 'textarea';
	inputmode?: 'text' | 'decimal' | 'email' | 'none' | 'numeric' | 'search' | 'tel' | 'url' | '';
	maxlength?: number;
	textareaMaxlength?: number;
	rows?: number;
	autosize?: boolean;
	negative?: boolean;
	label1?: null | IconProps;
	label2?: null | string;
	label3?: null | IconProps;
	label4?: null | IconProps;
	label5?: null | string;
	label6?: null | IconProps;
	tip?: string | null;
	data1?: null | string;
	data2?: null | string;
	data3?: null | string;
	value?: string;
	clear?: boolean;
	onfocus?: (value: string) => void;
	onblur?: (value: string) => void;
	onchange?: (value: string) => void;
	onclear?: () => void;
	onclickLabel1?: () => void;
	onclickLabel2?: () => void;
	onclickLabel3?: () => void;
	onclickLabel4?: () => void;
	onclickLabel5?: () => void;
	onclickLabel6?: () => void;
	onkeydown?: (key: string) => void;
	titleChild?: Snippet;
	data1Child?: Snippet;
	data2Child?: Snippet;
	data3Child?: Snippet;
	label1Child?: Snippet;
	label2Child?: Snippet;
	label3Child?: Snippet;
	label4Child?: Snippet;
	label5Child?: Snippet;
	label6Child?: Snippet;
	tipChild?: Snippet;
};

export type LoadingProps = {
	type?: string;
	height?: '2' | '4' | '6' | '8' | '12' | '16' | '20' | '28' | '36' | '48' | '56' | '64' | '72' | '80' | '96' | 'full';
	width?: '2' | '4' | '6' | '8' | '12' | '16' | '20' | '28' | '36' | '48' | '56' | '64' | '72' | '80' | '96' | 'full';
	theme?: boolean;
	inverse?: boolean;
	customColor?: string[];
	lazyAnimation?: boolean;
	speed?: number;
};

export type MaskProps = {
	visible?: boolean;
	opacity?: '0' | '0.1' | '0.2' | '0.3' | '0.4' | '0.5' | '0.6' | '0.7' | '0.8' | '0.9' | '1';
	clickable?: boolean;
	inverse?: boolean;
	backdropBlur?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl';
	duration?: number;
	outDuration?: number;
	zIndex?: number;
	children?: Snippet;
	onclickMask?: () => void;
};

export type ModalProps = {
	visible?: boolean;
	title?: string;
	titleAlign?: 'left' | 'center' | 'right';
	content?: string;
	popup?: PopupProps;
	showIcon?: boolean;
	icon?: IconProps;
	showBtn?: boolean;
	btnText?: string;
	button?: ButtonProps;
	contentChild?: Snippet;
	onclose?: () => void;
};

export type NavBarProps = {
	title?: string;
	titleAlign?: 'left' | 'center' | 'right';
	left?: 'back' | null | IconProps;
	rights?: IconProps[];
	line?: boolean;
	injClass?: string;
	love?: boolean;
	onclickLeft?: () => void;
	onclickRight?: (index: number) => void;
	titleChild?: Snippet;
	leftChild?: Snippet;
	rightChild?: Snippet;
};

export type NoticeBarProps = {
	textList: string[];
	leftIcon?: IconProps | null;
	rightIcon?: 'close' | 'arrow' | null;
	fontSize?: 'xs' | 'sm' | 'base' | 'lg';
	space?: number;
	speed?: number;
	vertical?: boolean;
	duration?: 100 | 300 | 500 | 700 | 1000;
	interval?: number;
	injClass?: string;
	leftChild?: Snippet;
	rightChild?: Snippet;
	onclickRight?: () => void;
};

export type NumKeyboardProps = {
	value?: string;
	type?: 'button' | 'block';
	visible?: boolean;
	height?: '8' | '10' | '12' | '14' | '16' | '20';
	space?: '0' | '1' | '2' | '3' | '4';
	p?: '0' | '1' | '2' | '3' | '4';
	reverse?: boolean;
	done?: boolean;
	dot?: boolean;
	close?: boolean;
	doneText?: string;
	doneDisabled?: boolean;
	radius?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full';
	clear?: boolean;
	panelClass?: string;
	keyClass?: string;
	doneClass?: string;
	popup?: PopupProps;
	onclick?: (key: string) => void;
	onopen?: (height: number) => void;
	onclose?: () => void;
};

export type PaginationProps = {
	total: number;
	pageSize?: number;
	current?: number;
	maxShowPage?: 5 | 7 | 9 | 11;
	radius?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
	type?: 'border' | 'block' | 'bold';
	pageCol?: number;
	showNextOmitPage?: boolean;
	showPreOmitPage?: boolean;
	injClass?: string;
	noDataText?: string;
	onePageText?: string;
	continuous?: boolean;
	onchange?: (current: number) => void;
	onnext?: (current: number) => void;
	onpre?: (current: number) => void;
};

export type PickerDataChildProps = {
	[key: string]: string | PickerDataChildProps[] | undefined | number;
	children?: PickerDataChildProps[];
	initIndex?: number;
};
export type PickerDatasProps = {
	data: { [key: string]: string }[];
	showRow?: 3 | 5 | 7;
	initIndex?: number;
	useAnimation?: boolean;
	labelKey?: string;
	flex?: number;
	align?: 'left' | 'center' | 'right';
	lastSelectedIndex?: number;
};
export type PickerProps = {
	visible?: boolean;
	datas?: PickerDatasProps[] | PickerDataChildProps[];
	autoScrollToLast?: boolean;
	cancelText?: string;
	confirmText?: string;
	title?: string;
	isLinkage?: boolean;
	linkageInitIndexs?: number[];
	linkageShowRows?: number[];
	linkageFlexs?: number[];
	linkageAligns?: ('left' | 'center' | 'right')[];
	linkageLabelKeys?: string[];
	linkageChildrenKey?: string;
	popup?: PopupProps;
	onclose?: () => void;
	onconfirm?: (items: { [key: string]: string }[], indexs: number[]) => void;
	oncancel?: () => void;
};

export type PlaceholderProps = {
	py?: '0' | '1' | '2' | '3' | '4' | '8';
	height?: 'full' | '1' | '2' | '4' | '8' | '16' | '24' | '32' | '48' | '64' | '96';
	radius?: 'none' | 'sm' | 'md' | 'xl' | '2xl' | '3xl' | 'full';
	shadow?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
	injClass?: string;
	children?: Snippet;
};

export type PopupProps = {
	visible?: boolean;
	size?: number;
	position?: 'center' | 'top' | 'bottom' | 'left' | 'right';
	duration?: number;
	outDuration?: number;
	easeType?: SvelteEasingProps;
	easeOutType?: SvelteEasingProps;
	px?: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '8' | '10' | '12' | '16' | '20';
	py?: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '8' | '10' | '12' | '16' | '24' | '32' | '48' | '64';
	mask?: MaskProps;
	maskClosable?: boolean;
	radiusPosition?: 'all' | 'top' | 'bottom' | 'left' | 'right';
	radius?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full';
	transitionDistance?: number;
	transparent?: boolean;
	allowBodyScroll?: boolean;
	zIndex?: number;
	dynamicFixed?: boolean;
	hideScrollbar?: boolean;
	children?: Snippet;
	onclose?: () => void;
	onclickMask?: () => void;
};

export type ProgressProps = {
	percent?: number;
	percentPosition?: 'inner' | 'right' | 'block' | null;
	height?: '1' | '2' | '3' | '4';
	radius?: 'full' | 'middle' | 'none';
	inactive?: boolean;
	overflowPercent?: number;
	duration?: '150' | '300' | '500' | '700' | '1000';
	injClass?: string;
	trackInjClass?: string;
	children?: Snippet;
};

export type ProgressLoopProps = {
	percent?: number;
	strokeWidth?: number;
	butt?: boolean;
	reverse?: boolean;
	duration?: '150' | '300' | '500' | '700' | '1000';
	gradient?: [string, string] | null;
	injClass?: string;
	trackInjClass?: string;
	children?: Snippet;
};

export type RadioItemProps = {
	name: string;
	label?: string;
	layout?: 'v' | 'h' | 'inline';
	textPosition?: 'l' | 'r' | 't' | 'b';
	icon?: 'default' | null | IconProps;
	iconChecked?: 'default' | null | IconProps;
	checked?: boolean;
	children?: Snippet;
	onclick?: (name: string) => void;
};
export type RadioProps = {
	data: RadioItemProps[];
	layout?: 'v' | 'h' | 'inline';
	value?: string;
	textPosition?: 'l' | 'r' | 't' | 'b';
	icon?: 'default' | null | IconProps;
	iconChecked?: 'default' | null | IconProps;
	radioChild?: Snippet<[{ item: RadioItemProps & Record<string, unknown> }]>;
	onchange?: (value: string) => void;
};

export type RateProps = {
	value?: number;
	total?: number;
	height?: number;
	width?: number;
	opacity?: '0.05' | '0.1' | '0.2' | '0.3' | '0.4' | '0.5' | '0.6' | '0.7' | '0.8' | '0.9' | '1';
	space?: '0' | '1' | '2' | '3' | '4' | '8';
	half?: boolean;
	zero?: boolean;
	vertical?: boolean;
	disabled?: boolean;
	readonly?: boolean;
	animation?: 'current' | 'active' | null;
	children?: Snippet;
	onclick?: (value: number) => void;
};

export type SkeletonProps = {
	type?: 'div' | 'p' | 'img' | 'video' | 'code' | 'qrcode' | 'barcode';
	width?: 'full' | '2' | '4' | '6' | '8' | '12' | '16' | '24' | '32' | '48' | '64' | '96';
	height?: '1' | '2' | '4' | '6' | '8' | '12' | '16' | '24' | '32' | '48' | '64' | '96';
	radius?: 'none' | 'sm' | 'md' | 'xl' | '2xl' | '3xl' | 'full';
	space?: '0.5' | '1' | '2' | '4' | '8';
	lines?: number;
	iconRatio?: number;
};

export type SliderProps = {
	value?: number;
	step?: number;
	minRange?: number;
	maxRange?: number;
	isRange?: boolean;
	valueRange?: [number, number];
	startValue?: number;
	endValue?: number;
	showTip?: 'always' | 'touch' | 'never';
	radius?: 'none' | 'sm' | 'xl' | 'full';
	lineBlock?: boolean;
	disabled?: boolean;
	readonly?: boolean;
	children?: Snippet;
	onchange?: (value: number, valueRange?: [number, number]) => void;
};

export type StepperProps = {
	value?: number;
	min?: number;
	max?: number;
	step?: number;
	vertical?: boolean;
	numberHighlight?: boolean;
	theme?: boolean;
	radius?: 'none' | 'sm' | 'xl' | 'full';
	decimal?: number;
	async?: boolean;
	asyncLoading?: boolean;
	loading?: LoadingProps;
	padding?: boolean;
	injClassOut?: string;
	injClassBtn?: string;
	injClassNum?: string;
	onchange?: (value: number) => void;
	ondecrease?: () => void;
	onincrease?: () => void;
};

export type StepsStepBarIconProps = { type: 'icon'; content: IconProps };
export type StepsStepBarImageProps = { type: 'image'; content: string };
export type StepsStepBarStringProps = { type: 'string'; content: string };
export type StepsStepProps = {
	title?: string;
	desc?: string;
	bar?: StepsStepBarIconProps | StepsStepBarImageProps | StepsStepBarStringProps;
	injComponent?: Component;
};
export type StepsFinishStepProps = {
	title?: string;
	desc?: string;
	bar?: StepsStepBarIconProps | StepsStepBarImageProps | StepsStepBarStringProps;
	injComponent?: Component;
};
export type StepsItemProps = {
	step: StepsStepProps;
	finishStep?: StepsFinishStepProps;
	height?: number;
};
export type StepsProps = {
	steps: StepsItemProps[];
	current?: number;
	radius?: 'none' | 'sm' | 'xl' | 'full';
	barBorder?: boolean;
	vertical?: boolean;
};

export type SwiperImgProps = { type: 'img'; url: string };
export type SwiperComponentProps = { type: 'component'; component: Component };
export type SwiperProps = {
	data: (SwiperImgProps | SwiperComponentProps)[];
	interval?: number;
	duration?: number;
	autoplay?: boolean;
	lazyplay?: boolean;
	initActive?: number;
	indicatePosition?: 'inner' | 'out' | null;
	indicateAlign?: 'center' | 'right' | 'left';
	indicateStyle?: 'point' | 'line' | 'pointLine' | 'longLine';
	indicateRadius?: boolean;
	indicateInjClass?: string;
	indicateColor?: string;
	indicateActiveColor?: string;
	aspectRatio?: [number, number];
	containerWidth?: number;
	px?: '0' | '1' | '2' | '4' | '6' | '8' | '12' | '16' | '24';
	py?: '0' | '1' | '2' | '4' | '6' | '8' | '12';
	translateX?: number;
	translateZ?: number;
	rotateX?: number;
	rotateY?: number;
	rotateZ?: number;
	activeInjClass?: string;
	notActiveInjClass?: string;
	radius?: 'none' | 'sm' | 'xl' | '2xl' | 'full';
	triggerLong?: number;
	notTriggerLong?: number;
	triggerSpeed?: number;
	innerInjClass?: string;
	onchange?: (current: number) => void;
	onclick?: (current: number) => void;
};

export type SwitchProps = {
	active?: boolean;
	radius?: 'none' | 'middle' | 'full';
	inside?: 'state' | 'loading' | [string, string] | null;
	injClass?: string;
	disabled?: boolean;
	async?: boolean;
	loading?: LoadingProps;
	trueChild?: Snippet;
	falseChild?: Snippet;
	onchange?: (active: boolean) => void;
	onclick?: () => void;
};

export type TabBarLabelProps = { text?: string; icon?: IconProps; activeIcon?: IconProps };
export type TabBarProps = {
	labels: TabBarLabelProps[];
	active?: number;
	line?: boolean;
	lineW?: number;
	love?: boolean;
	injClass?: string;
	tabInjClass?: string;
	activeTabInjClass?: string;
	activeInjClass?: string;
	onchange?: (active: number) => void;
};

export type TabContentProps = { show?: boolean; children?: Snippet };
export type TabLabelProps = { text?: string; icon?: IconProps };
export type TabProps = {
	labels?: TabLabelProps[];
	active?: number;
	lineType?: boolean;
	radius?: 'none' | 'sm' | 'xl' | 'full';
	duration?: 'fast' | 'base' | 'slow' | 'slower';
	layout?: 'h' | 'v';
	love?: boolean;
	injClass?: string;
	tabInjClass?: string;
	activeTabInjClass?: string;
	activeInjClass?: string;
	mx?: '0' | '1' | '2' | '3' | '4' | '6' | '8' | '12' | '16' | '20';
	overflow?: boolean;
	showNum?: number;
	autoScroll?: boolean;
	onclickTab?: (active: number) => void;
};
export type TabsProps = {
	tab: TabProps;
	duration?: 'fast' | 'base' | 'slow' | 'slower';
	position?: 't' | 'b' | 'l' | 'r';
	transition?: boolean;
	active?: number;
	onchange?: (active: number) => void;
	children?: Snippet<[{ active: number }]>;
};

export type TimePickerItemProps = {
	showRow?: 3 | 5 | 7;
	flex?: number;
	align?: 'left' | 'center' | 'right';
};
export type TimePickerObjProps = {
	YYYY: string;
	MM: string;
	DD: string;
	hh: string;
	mm: string;
	ss: string;
};
export type TimePickerTypeProps =
	| 'YYYY'
	| 'MM'
	| 'hh'
	| 'mm'
	| 'ss'
	| 'YYYYMM'
	| 'hhmm'
	| 'mmss'
	| 'YYYYMMDD'
	| 'hhmmss'
	| 'YYYYMMDDhh'
	| 'YYYYMMDDhhmm'
	| 'YYYYMMDDhhmmss';
export type TimePickerProps = {
	visible?: boolean;
	type?: TimePickerTypeProps;
	yearProps?: TimePickerItemProps;
	monthProps?: TimePickerItemProps;
	dayProps?: TimePickerItemProps;
	hourProps?: TimePickerItemProps;
	minuteProps?: TimePickerItemProps;
	secondProps?: TimePickerItemProps;
	initYear?: string;
	initMonth?: string;
	initDay?: string;
	initHour?: string;
	initMinute?: string;
	initSecond?: string;
	minuteStep?: number;
	secondStep?: number;
	yearRange?: [number, number] | [];
	monthRange?: [number, number];
	hourRange?: [number, number];
	minuteRange?: [number, number];
	secondRange?: [number, number];
	showTips?: boolean;
	cancelText?: string;
	confirmText?: string;
	title?: string;
	yearText?: string;
	monthText?: string;
	dayText?: string;
	hourText?: string;
	minuteText?: string;
	secondText?: string;
	outFormat?: string;
	popup?: PopupProps;
	oncancel?: () => void;
	onconfirm?: (timeStr: string, timeObj: TimePickerObjProps) => void;
	onclose?: () => void;
};

export type ToastProps = {
	message?: string;
	visible?: boolean;
	duration?: number;
	position?: 'center' | 'top' | 'bottom';
	py?: '0' | '10' | '20' | '40' | '60' | '80';
	radius?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full';
	transitionType?: 'scale' | 'fly' | 'fade' | 'slide' | 'blur' | null;
	transitionParams?: object;
	outDuration?: number;
	type?: 'success' | 'error' | 'warning' | 'info' | 'loading' | 'icon' | null;
	mask?: MaskProps;
	loading?: LoadingProps;
	icon?: IconProps;
	zIndex?: number;
	clickable?: boolean;
	dynamicFixed?: boolean;
	children?: Snippet;
	onclose?: () => void;
};

export type SvelteEasingProps =
	| 'backIn'
	| 'backInOut'
	| 'backOut'
	| 'bounceIn'
	| 'bounceInOut'
	| 'bounceOut'
	| 'circIn'
	| 'circInOut'
	| 'circOut'
	| 'cubicIn'
	| 'cubicInOut'
	| 'cubicOut'
	| 'elasticIn'
	| 'elasticInOut'
	| 'elasticOut'
	| 'expoIn'
	| 'expoInOut'
	| 'expoOut'
	| 'linear'
	| 'quadIn'
	| 'quadInOut'
	| 'quadOut'
	| 'quartIn'
	| 'quartInOut'
	| 'quartOut'
	| 'quintIn'
	| 'quintInOut'
	| 'quintOut'
	| 'sineIn'
	| 'sineInOut'
	| 'sineOut';



================================================
FILE: packages/stdf/src/routes/+layout.svelte
================================================
<script lang="ts">
	import { setContext, onMount } from 'svelte';
	import { page } from '$app/stores';
	import { goto } from '$app/navigation';
	import { NavBar, Icon } from '$lib/index.js';
	import { zh_CN, en_US } from '$lib/lang/index.js';
	import '../app.css';
	import { menuList, type MenuListChild } from '../data/menuList.js';
	import ThemeSwitch from './components/ThemeSwitch.svelte';
	import { darkMode } from '$lib/theme/index.js';

	import { switchTheme } from '$lib/theme/index.js';
	import themes from '../data/themes/index.js';

	let { children } = $props();

	// 循环 menuList，将所有元素的 childs 组成一个数组
	// Cycle menuList, and combine the childs of all elements into an array
	const menuListArr: MenuListChild[] = menuList.reduce((acc: MenuListChild[], cur) => {
		if (cur.childs) {
			acc.push(...cur.childs);
		}
		return acc;
	}, []);

	// 使用 `URLSearchParams` 对象来获取 URL 查询参数
	// Use the `URLSearchParams` object to get the URL query parameters
	const urlParams = new URLSearchParams($page.url.search);
	const channel = urlParams.get('channel');
	// 判断是否是 iframe
	// judge whether it is iframe
	const isIframe = channel && channel === 'iframe' ? '1' : '0';
	// 设置 iframe
	// setting iframe
	setContext('iframe', isIframe);

	let lang = 'zh_CN';

	if (isIframe === '1') {
		// 获取 url 中的 theme 和 darkMode 和 lang
		// get theme, darkMode and lang from url
		const urlTheme = urlParams.get('theme');
		const urlDarkMode = urlParams.get('darkMode');
		const currentTheme = themes.find((item) => item.name === urlTheme);
		if (currentTheme) {
			switchTheme(currentTheme.theme);
		}
		if (urlDarkMode === 'dark') {
			darkMode();
			localStorage.setItem('theme', 'dark');
		} else if (urlDarkMode === 'light') {
			darkMode(false);
			localStorage.setItem('theme', 'light');
		}
		const urlLang = urlParams.get('lang');
		if (urlLang) {
			lang = urlLang;
		}
	}

	// 环境变量
	// environment variables
	const mode = import.meta.env.MODE;

	// mode 是否是指定组件模式
	// whether mode is specified component mode
	const isComponentMode = mode != 'production' && mode != 'development' && mode != 'english';

	let showLeft = $derived(!(isIframe === '1' || $page.url.pathname === '/' || isComponentMode));

	let theme = $state(localStorage.getItem('theme') === 'dark' ? 'dark' : 'light');

	// 设置亮暗模式
	// Set light and dark mode
	if (localStorage.getItem('theme') === 'dark') {
		darkMode();
	} else if (localStorage.getItem('theme') === 'light') {
		darkMode(false);
	} else {
		darkMode(false);
	}
	//手动切换亮暗模式
	// manually switch light and dark mode
	const toggleFun = () => {
		if (theme === 'dark') {
			// 切换到 light
			// switch to light
			theme = 'light';
			localStorage.setItem('theme', 'light');
			darkMode(false);
		} else {
			// 切换到 dark
			// switch to dark
			theme = 'dark';
			localStorage.setItem('theme', 'dark');
			darkMode();
		}
	};

	// 判断 mode 是否是 English 模式
	// Determine whether mode is English mode
	const englishMode = mode.slice(-3) === '_en' || mode === 'english';

	if (englishMode) {
		// 固定为英文
		// Fixed to English
		lang = 'en_US';
	} else {
		// 根据 url 或 urlParams 或 sessionStorage 获取语言，优先级为 urlParams > url  > sessionStorage
		// Get the language according to the url or urlParams or sessionStorage, the priority is urlParams > url > sessionStorage
		// 如果 urlParams 中有 ?lang=en_US，则设置为英文，如果有 ?lang=zh_CN，则设置为中文
		// If there is ?lang=en_US in urlParams, set it to English, if there is ?lang=zh_CN, set it to Chinese
		const urlParamsLang = urlParams.get('lang');
		if (urlParamsLang) {
			lang = urlParamsLang;
			// 将 url 的 ?lang=en_US 或 ?lang=zh_CN 去掉
			// Remove ?lang=en_US or ?lang=zh_CN from url
			setTimeout(() => {
				history.replaceState(null, '', location.href.replace(`?lang=${urlParamsLang}`, ''));
			}, 100);
		} else {
			// 如果 URL 中包含 /en_US/ 或 /zh_CN/，则设置为英文或中文
			// If the URL contains /en_US/ or /zh_CN/, set it to English or Chinese
			const urlLang = $page.url.pathname.split('/')[1];
			if (urlLang === 'en_US' || urlLang === 'zh_CN') {
				lang = urlLang;
			} else {
				// 如果 sessionStorage 中有 lang，则设置为 sessionStorage 中的 lang
				// If there is lang in sessionStorage, set it to lang in sessionStorage
				const sessionStorageLang = sessionStorage.getItem('lang');
				if (sessionStorageLang) {
					lang = sessionStorageLang;
				} else {
					// 如果 sessionStorage 中没有 lang，则设置为中文
					// If there is no lang in sessionStorage, set it to Chinese
					lang = 'zh_CN';
				}
			}
		}
	}
	sessionStorage.setItem('lang', lang);
	const isZh = lang === 'zh_CN';
	setContext('STDF_lang', isZh ? zh_CN : en_US);

	onMount(() => {
		if (isComponentMode) {
			// 英文模式去掉 mode 后面的 _en 作为 nav
			// English mode removes _en after mode as nav
			const nav = englishMode ? mode.slice(0, -3) : mode;
			goto(`/${nav}/${englishMode ? 'en_US' : 'zh_CN'}`);
		}
	});

	let showTheme = $state(false);
	// 切换主题
	// switch theme
	const switchThemeFunc = () => {
		showTheme = !showTheme;
	};
</script>

<div class="sticky top-0 z-[100]">
	<NavBar
		title={$page.url.pathname === '/'
			? isZh
				? 'STDF 示例'
				: 'STDF Demo'
			: menuListArr.filter((item) => item.nav === $page.url.pathname.split('/')[1])[0][isZh ? 'title_zh' : 'title_en'] +
				(isZh ? '示例' : ' Demo')}
		left={showLeft ? 'back' : null}
		injClass="bg-white/60 dark:bg-black/60 backdrop-blur-sm"
		onclickLeft={() => window.history.back()}
	>
		{#snippet rightChild()}
			<div class="flex text-center">
				{#if isIframe === '0'}
					<div class="h-12 w-10">
						<a href="https://github.com/any-tdf/stdf" target="_blank" rel="noreferrer">
							<Icon name="ri-github-fill" />
						</a>
					</div>
					<div class="h-12 w-10">
						<a
							href={`https://stdf.design${$page.url.pathname === '/' ? '' : `/components?nav=${$page.url.pathname.split('/')[1]}&tab=0`}`}
							target="_blank"
							rel="noreferrer"
						>
							<Icon name="ri-compass-line" />
						</a>
					</div>
				{/if}
				<button class="h-12 w-10" onclick={toggleFun} aria-label={theme === 'dark' ? '切换到亮色模式' : '切换到暗色模式'}>
					<Icon name={theme === 'dark' ? 'ri-moon-fill' : 'ri-sun-line'} theme />
				</button>
				<button class="h-12 w-10" onclick={switchThemeFunc} aria-label="切换主题">
					<Icon name="ri-palette-line" theme />
				</button>
			</div>
		{/snippet}
	</NavBar>
</div>
{@render children?.()}
<div
	class="fixed z-[1000] {showTheme
		? 'right-0'
		: '-right-80'} top-12 rounded-lg bg-white px-2 shadow-sm transition-all duration-500 dark:bg-black"
>
	<ThemeSwitch />
</div>



================================================
FILE: packages/stdf/src/routes/+layout.ts
================================================
// 修改 ssr 为 false，使其不再使用服务端渲染，而是使用客户端渲染
// Change ssr to false to use client-side rendering instead of server-side rendering
export const ssr = false;

export const prerender = true;



================================================
FILE: packages/stdf/src/routes/+page.svelte
================================================
<script lang="ts">
	import { CellGroup, Cell } from '$lib/index.js';
	import { menuList, type MenuListChild } from '../data/menuList.js';

	const menuListArr: MenuListChild[] = menuList.reduce((acc, cur) => {
		if (cur.childs) {
			acc.push(...cur.childs);
		}
		return acc;
	}, [] as MenuListChild[]);
	const isZh = sessionStorage.getItem('lang') === 'zh_CN';
	const changeLangFunc = () => {
		sessionStorage.setItem('lang', isZh ? 'en_US' : 'zh_CN');
		window.location.reload();
	};
</script>

<div class="mb-2 mt-8 flex h-14 flex-col items-center justify-center">
	<svg viewBox="0 0 90 80">
		<path
			class="fill-primary dark:fill-dark"
			d="M0 0H20H40H50C64.8056 0 77.7325 8.04398 84.6487 20H50H40V22.6757V30H50C55.5229 30 60 34.4771 60 40C60 45.5229 55.5229 50 50 50H40V57.3243V78.7398V80H20V66.4583V20H15.3513H0V0ZM50 80C72.0914 80 90 62.0914 90 40C90 36.547 89.5625 33.1962 88.7398 30H67.3244C69.0261 32.9417 70 36.3571 70 40C70 51.0457 61.0457 60 50 60V80Z"
		/>
		<path class="fill-dark dark:fill-primary" d="M20 30V0L0 50H20V80L40 30H20Z" />
	</svg>
</div>
<a href="https://stdf.design" target="_blank" rel="noreferrer">
	<div class="text-center text-lg underline">stdf.design</div>
</a>
<div class="flex flex-col py-4">
	<div>
		{#each menuList as menu (menu.class)}
			<div class="mb-2 mt-8 px-4 text-sm text-gray-500">{isZh ? menu.class : menu.class_en}</div>
			<CellGroup>
				{#each menu.childs as child, i (child.nav)}
					<a href={child.nav + (isZh ? '/zh_CN' : '/en_US')}>
						<Cell
							title={isZh ? child.title : child.title_en}
							mx="0"
							my="0"
							shadow="none"
							radius="none"
							line={i !== menu.childs.length - 1}
						/>
					</a>
				{/each}
			</CellGroup>
		{/each}
	</div>
	<div class="p-4">{isZh ? '当前组件总数：' : 'Current number of components: '}{menuListArr.length}</div>
	<div class="text-primary dark:text-dark flex justify-around p-4 text-xs underline">
		<button on:click={changeLangFunc} class="text-primary dark:text-dark">{isZh ? 'English' : '简体中文'}</button>
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/actionSheet/en_US/+page.svelte
================================================
<!-- ActionSheet Demo -->
<script lang="ts">
	import { Cell, ActionSheet, Toast } from '$lib/index.js';
	import { type ActionProps } from '$lib/types/index.js';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);

	const actions = [{ content: 'Option one' }, { content: 'Option two' }, { content: 'Option three' }];

	const actions1: ActionProps[] = [
		{ content: 'Normal option' },
		{ content: 'Theme option', style: 'theme' },
		{ content: 'Disabled option', style: 'disabled' },
		{ content: 'Danger option', style: 'danger' }
	];
	const actions2: ActionProps[] = [
		{ content: 'Option one' },
		{ content: 'Option two', desc: 'Here is the description information' },
		{ content: 'Option three', style: 'danger', desc: 'Here is the description information' }
	];
	const actions3: ActionProps[] = [
		{ content: 'Lina', showImg: true, imgSrc: '/assets/images/dota_火女.png', imgRadius: 'sm' },
		{ content: 'SB', showImg: true, imgSrc: '/assets/images/dota_小牛.png', imgRadius: 'sm' },
		{ content: 'Morph', showImg: true, imgSrc: '/assets/images/dota_水人.png', imgRadius: 'sm' }
	];
	const actions4: ActionProps[] = [
		{ content: 'Apple', showImg: true, imgSrc: '/assets/logos/apple.png', imgRadius: 'none' },
		{ content: 'Google', showImg: true, imgSrc: '/assets/logos/google.png', imgRadius: 'none' },
		{ content: 'Microsoft', showImg: true, imgSrc: '/assets/logos/microsoft.png', imgRadius: 'none' },
		{ content: 'Adobe', showImg: true, imgSrc: '/assets/logos/adobe.png', imgRadius: 'none' },
		{ content: 'Figma', showImg: true, imgSrc: '/assets/logos/figma.png', imgRadius: 'none' }
	];

	let toastVisible1 = $state(false);
	let toastVisible2 = $state(false);
	let toastVisible3 = $state(false);
	let index = $state(0);
	let item = $state({ content: '' });
	const clickActionFunc = (i: number, action: ActionProps) => {
		index = i;
		item = action;
		toastVisible3 = true;
	};
</script>

<div class="py-4">
	<Cell title="Basic usage" onclick={() => (visible1 = true)} />
	<ActionSheet bind:visible={visible1} {actions} />

	<Cell title="With cancel operation and click mask not closable" onclick={() => (visible2 = true)} />
	<ActionSheet bind:visible={visible2} {actions} showCancel popup={{ maskClosable: false }} />

	<Cell title="Different styles" onclick={() => (visible3 = true)} />
	<ActionSheet bind:visible={visible3} actions={actions1} />

	<Cell title="With title and description information" onclick={() => (visible4 = true)} />
	<ActionSheet bind:visible={visible4} actions={actions2} title="Here is the title, which can briefly explain the following operations." />

	<Cell title="Top corner rounded" onclick={() => (visible5 = true)} />
	<ActionSheet bind:visible={visible5} {actions} popup={{ radius: 'xl' }} />

	<Cell title="With spacing on both sides" onclick={() => (visible6 = true)} />
	<ActionSheet bind:visible={visible6} {actions} popup={{ radius: 'xl', px: '2' }} />

	<Cell title="Listen to close event" onclick={() => (visible7 = true)} />
	<ActionSheet bind:visible={visible7} {actions} onclose={() => (toastVisible1 = true)} />
	<Toast bind:visible={toastVisible1} message="Closed ActionSheet！" />

	<Cell title="Listen to cancel event" onclick={() => (visible8 = true)} />
	<ActionSheet bind:visible={visible8} {actions} showCancel oncancel={() => (toastVisible2 = true)} />
	<Toast bind:visible={toastVisible2} message="Clicked cancel！" />

	<Cell title="Listen to option click event" onclick={() => (visible9 = true)} />
	<ActionSheet bind:visible={visible9} {actions} onclickAction={clickActionFunc} />
	<Toast bind:visible={toastVisible3} message={`Clicked the ${index + 1} item, ${item.content}!`} />

	<Cell title="Click option not close" onclick={() => (visible10 = true)} />
	<ActionSheet bind:visible={visible10} {actions} actionClosable={false} />

	<Cell title="Option with image" onclick={() => (visible11 = true)} />
	<ActionSheet bind:visible={visible11} actions={actions3} />

	<Cell title="Option left aligned" onclick={() => (visible12 = true)} />
	<ActionSheet bind:visible={visible12} actions={actions4} align="left" />
</div>



================================================
FILE: packages/stdf/src/routes/actionSheet/zh_CN/+page.svelte
================================================
<!-- ActionSheet Demo -->
<script lang="ts">
	import { Cell, ActionSheet, Toast } from '$lib/index.js';
	import { type ActionProps } from '$lib/types/index.js';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);

	const actions: ActionProps[] = [{ content: '选项一' }, { content: '选项二' }, { content: '选项三' }];

	const actions1: ActionProps[] = [
		{ content: '常规选项' },
		{ content: '主题选项', style: 'theme' },
		{ content: '禁用选项', style: 'disabled' },
		{ content: '警告选项', style: 'danger' }
	];
	const actions2: ActionProps[] = [
		{ content: '选项一' },
		{ content: '选项二', desc: '这里是描述信息' },
		{ content: '选项三', style: 'danger', desc: '这里是描述信息' }
	];
	const actions3: ActionProps[] = [
		{ content: '火女', showImg: true, imgSrc: '/assets/images/dota_火女.png', imgRadius: 'sm' },
		{ content: '小牛', showImg: true, imgSrc: '/assets/images/dota_小牛.png', imgRadius: 'sm' },
		{ content: '水人', showImg: true, imgSrc: '/assets/images/dota_水人.png', imgRadius: 'sm' }
	];
	const actions4: ActionProps[] = [
		{ content: 'Apple', showImg: true, imgSrc: '/assets/logos/apple.png', imgRadius: 'none' },
		{ content: 'Google', showImg: true, imgSrc: '/assets/logos/google.png', imgRadius: 'none' },
		{ content: 'Microsoft', showImg: true, imgSrc: '/assets/logos/microsoft.png', imgRadius: 'none' },
		{ content: 'Adobe', showImg: true, imgSrc: '/assets/logos/adobe.png', imgRadius: 'none' },
		{ content: 'Figma', showImg: true, imgSrc: '/assets/logos/figma.png', imgRadius: 'none' }
	];

	let toastVisible1 = $state(false);
	let toastVisible2 = $state(false);
	let toastVisible3 = $state(false);
	let index = $state(0);
	let item = $state({ content: '' });
	const clickActionFunc = (i: number, action: ActionProps) => {
		index = i;
		item = action;
		toastVisible3 = true;
	};
</script>

<div class="py-4">
	<Cell title="基础用法" onclick={() => (visible1 = true)} />
	<ActionSheet bind:visible={visible1} {actions} />

	<Cell title="有取消操作且点击遮罩不可关闭" onclick={() => (visible2 = true)} />
	<ActionSheet bind:visible={visible2} {actions} showCancel popup={{ maskClosable: false }} />

	<Cell title="不同样式" onclick={() => (visible3 = true)} />
	<ActionSheet bind:visible={visible3} actions={actions1} />

	<Cell title="带标题和描述信息" onclick={() => (visible4 = true)} />
	<ActionSheet bind:visible={visible4} actions={actions2} title="这里是标题，可以简要说明以下操作。" />

	<Cell title="顶部来点圆角" onclick={() => (visible5 = true)} />
	<ActionSheet bind:visible={visible5} {actions} popup={{ radius: 'xl' }} />

	<Cell title="两侧有间距" onclick={() => (visible6 = true)} />
	<ActionSheet bind:visible={visible6} {actions} popup={{ radius: 'xl', px: '2' }} />

	<Cell title="监听关闭事件" onclick={() => (visible7 = true)} />
	<ActionSheet bind:visible={visible7} {actions} onclose={() => (toastVisible1 = true)} />
	<Toast bind:visible={toastVisible1} message="关闭了 ActionSheet！" />

	<Cell title="监听取消事件" onclick={() => (visible8 = true)} />
	<ActionSheet bind:visible={visible8} {actions} showCancel oncancel={() => (toastVisible2 = true)} />
	<Toast bind:visible={toastVisible2} message="点击了取消！" />

	<Cell title="监听选项点击事件" onclick={() => (visible9 = true)} />
	<ActionSheet bind:visible={visible9} {actions} onclickAction={clickActionFunc} />
	<Toast bind:visible={toastVisible3} message={`点击了第 ${index + 1} 项，${item.content}！`} />

	<Cell title="点击选项不关闭" onclick={() => (visible10 = true)} />
	<ActionSheet bind:visible={visible10} {actions} actionClosable={false} />

	<Cell title="选项带图片" onclick={() => (visible11 = true)} />
	<ActionSheet bind:visible={visible11} actions={actions3} />

	<Cell title="选项左对齐" onclick={() => (visible12 = true)} />
	<ActionSheet bind:visible={visible12} actions={actions4} align="left" />
</div>



================================================
FILE: packages/stdf/src/routes/asyncPicker/en_US/+page.svelte
================================================
<!-- AsyncPicker Demo -->
<script lang="ts">
	import { AsyncPicker, Cell } from '$lib/index.js';
	// For the sake of clarity, the reference data is placed in the data_en.js file, which can be viewed at the bottom of this page.
	import { linkageData, linkageDiffLabeData } from './data_en.js';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);

	let data = $state(linkageData);
	let currentLevel = $state(0);
	let lastLevel = $state(false);
	let firstLevel = $state(true);
	let level1Data = $state(linkageData[0].children);
	let titleBind = $state('Please select state');

	// Simulate data obtained after 2 seconds
	const nextFunc = (index: number) => {
		if (currentLevel === 0) {
			const nextData = linkageData[index].children;
			level1Data = nextData;
			setTimeout(() => {
				data = nextData as { label: string; children: { label: string; children: { label: string }[] }[] }[];
				currentLevel = 1;
				titleBind = 'Please select county';
				firstLevel = false;
			}, 2000);
		} else if (currentLevel === 1) {
			const nextData = level1Data[index].children;
			setTimeout(() => {
				data = nextData as { label: string; children: { label: string; children: { label: string }[] }[] }[];
				currentLevel = 2;
				titleBind = 'Please select district';
				lastLevel = true;
			}, 2000);
		} else {
			console.log('Last level');
		}
	};
	const prevFunc = () => {
		if (currentLevel === 1) {
			const prevData = linkageData;
			setTimeout(() => {
				data = prevData;
				currentLevel = 0;
				titleBind = 'Please select state';
				firstLevel = true;
			}, 2000);
		} else if (currentLevel === 2) {
			const prevData = level1Data;
			setTimeout(() => {
				data = prevData as { label: string; children: { label: string; children: { label: string }[] }[] }[];
				currentLevel = 1;
				titleBind = 'Please select county';
				lastLevel = false;
			}, 2000);
		} else {
			console.log('First level');
		}
	};

	let allIndexs: number[] = $state([]);
	let allItems: { label: string }[] = $state([]);
	const getAllDataFunc = (items: { label: string }[], indexs: number[]) => {
		allItems = items;
		allIndexs = indexs;
	};

	// 每一级对应的 labelKey 不同时的处理逻辑
	let diffLabelKeyData = $state(linkageDiffLabeData);
	let labelKey = $state('province');
	let diffLabelKeyCurrentLevel = $state(0);
	let diffLabelKeyLastLevel = $state(false);
	let diffLabelKeyFirstLevel = $state(true);
	let diffLabelKeyLevel1Data = $state(linkageDiffLabeData[0].children);
	const diffLabelKeyNextFunc = (index: number) => {
		if (diffLabelKeyCurrentLevel === 0) {
			const nextData = linkageDiffLabeData[index].children;
			diffLabelKeyLevel1Data = nextData;
			setTimeout(() => {
				diffLabelKeyData = nextData as unknown as { province: string; children: { city: string; children: { region: string }[] }[] }[];
				labelKey = 'city';
				diffLabelKeyCurrentLevel = 1;
				diffLabelKeyFirstLevel = false;
			}, 2000);
		} else if (diffLabelKeyCurrentLevel === 1) {
			const nextData = diffLabelKeyLevel1Data[index].children;
			setTimeout(() => {
				diffLabelKeyData = nextData as unknown as { province: string; children: { city: string; children: { region: string }[] }[] }[];
				diffLabelKeyCurrentLevel = 2;
				labelKey = 'region';
				diffLabelKeyLastLevel = true;
			}, 2000);
		} else {
			console.log('Last level');
		}
	};
	const diffLabelKeyPrevFunc = () => {
		if (diffLabelKeyCurrentLevel === 1) {
			const prevData = linkageDiffLabeData;
			setTimeout(() => {
				diffLabelKeyData = prevData;
				diffLabelKeyCurrentLevel = 0;
				diffLabelKeyFirstLevel = true;
				labelKey = 'province';
			}, 2000);
		} else if (diffLabelKeyCurrentLevel === 2) {
			const prevData = diffLabelKeyLevel1Data;
			setTimeout(() => {
				diffLabelKeyData = prevData as unknown as { province: string; children: { city: string; children: { region: string }[] }[] }[];
				diffLabelKeyCurrentLevel = 1;
				labelKey = 'city';
				diffLabelKeyLastLevel = false;
			}, 2000);
		} else {
			console.log('First level');
		}
	};
</script>

<div class="py-4">
	<div class="px-4">
		{#if allItems.length}
			Currently selected:
			{#each allItems as item}
				<span class="mr-2 text-primary dark:text-dark">{item.label}</span>
			{/each}
		{:else}
			<div>Please select data</div>
		{/if}
	</div>
	<div class="px-4">
		{#if allIndexs.length}
			The index values of current selections in their respective columns are:
			{#each allIndexs as index}
				<span class="mr-2 text-primary dark:text-dark">{index}</span>
			{/each}
		{:else}
			<div>Please select data</div>
		{/if}
	</div>
	<Cell
		title="Basic Usage"
		onclick={() => {
			visible1 = true;
			data = linkageData;
			lastLevel = false;
			firstLevel = true;
			currentLevel = 0;
			level1Data = linkageData[0].children;
		}}
	/>
	<AsyncPicker
		bind:visible={visible1}
		bind:data
		bind:lastLevel
		bind:firstLevel
		onnext={nextFunc}
		onprev={prevFunc}
		onconfirm={getAllDataFunc as (items: Record<string, unknown>[], indexs: number[]) => void}
	/>

	<Cell
		title="Show 7 Rows"
		onclick={() => {
			visible2 = true;
			data = linkageData;
			lastLevel = false;
			firstLevel = true;
			currentLevel = 0;
			level1Data = linkageData[0].children;
		}}
	/>
	<AsyncPicker bind:visible={visible2} bind:data bind:lastLevel bind:firstLevel onnext={nextFunc} onprev={prevFunc} showRow={7} />

	<Cell
		title="Left Align"
		onclick={() => {
			visible3 = true;
			data = linkageData;
			lastLevel = false;
			firstLevel = true;
			currentLevel = 0;
			level1Data = linkageData[0].children;
		}}
	/>
	<AsyncPicker bind:visible={visible3} bind:data bind:lastLevel bind:firstLevel align="left" onnext={nextFunc} onprev={prevFunc} />

	<Cell
		title="Custom Next/Previous Text"
		onclick={() => {
			visible5 = true;
			data = linkageData;
			lastLevel = false;
			firstLevel = true;
			currentLevel = 0;
			level1Data = linkageData[0].children;
		}}
	/>
	<AsyncPicker
		bind:visible={visible5}
		bind:data
		bind:lastLevel
		bind:firstLevel
		onnext={nextFunc}
		onprev={prevFunc}
		nextText="Continue"
		prevText="Back"
	/>

	<Cell
		title="Different labelKey for Each Level"
		onclick={() => {
			visible4 = true;
			diffLabelKeyData = linkageDiffLabeData;
			labelKey = 'province';
			diffLabelKeyCurrentLevel = 0;
			diffLabelKeyLastLevel = false;
			diffLabelKeyFirstLevel = true;
			diffLabelKeyLevel1Data = linkageDiffLabeData[0].children;
		}}
	/>
	<AsyncPicker
		bind:visible={visible4}
		bind:data={diffLabelKeyData}
		bind:lastLevel={diffLabelKeyLastLevel}
		bind:firstLevel={diffLabelKeyFirstLevel}
		bind:labelKey
		onnext={diffLabelKeyNextFunc}
		onprev={diffLabelKeyPrevFunc}
	/>

	<Cell
		title="Different Loading Effect"
		onclick={() => {
			visible6 = true;
			data = linkageData;
			lastLevel = false;
			firstLevel = true;
			currentLevel = 0;
			level1Data = linkageData[0].children;
		}}
	/>
	<AsyncPicker
		bind:visible={visible6}
		bind:data
		bind:lastLevel
		bind:firstLevel
		onnext={nextFunc}
		onprev={prevFunc}
		loading={{ type: '1_15', width: '12', height: '12' }}
	/>

	<Cell
		title="Rounded Top Corners"
		onclick={() => {
			visible8 = true;
			data = linkageData;
			lastLevel = false;
			firstLevel = true;
			currentLevel = 0;
			level1Data = linkageData[0].children;
		}}
	/>
	<AsyncPicker
		bind:visible={visible8}
		bind:data
		bind:lastLevel
		bind:firstLevel
		onnext={nextFunc}
		onprev={prevFunc}
		popup={{ radius: 'xl' }}
	/>

	<Cell
		title="Show Selected Options"
		onclick={() => {
			visible7 = true;
			data = linkageData;
			lastLevel = false;
			firstLevel = true;
			currentLevel = 0;
			level1Data = linkageData[0].children;
		}}
	/>
	<AsyncPicker bind:visible={visible7} bind:data bind:lastLevel bind:firstLevel onnext={nextFunc} onprev={prevFunc} showSelected />

	<Cell
		title="Dynamic Title"
		onclick={() => {
			visible9 = true;
			data = linkageData;
			lastLevel = false;
			firstLevel = true;
			currentLevel = 0;
			titleBind = 'Please select state';
			level1Data = linkageData[0].children;
		}}
	/>
	<AsyncPicker
		bind:visible={visible9}
		bind:data
		bind:lastLevel
		bind:firstLevel
		bind:title={titleBind}
		onnext={nextFunc}
		onprev={prevFunc}
	/>
</div>
<!-- 
const linkageData = [
	{
		label: 'California',
		children: [
			{
				label: 'Los Angeles',
				children: [
					{ label: 'Downtown' },
					{ label: 'Hollywood' },
					{ label: 'Venice' },
					{ label: 'Santa Monica' },
					{ label: 'Beverly Hills' }
				]
			},
			{
				label: 'San Francisco',
				children: [
					{ label: 'Downtown' },
					{ label: 'Mission District' },
					{ label: 'North Beach' },
					{ label: 'Chinatown' },
					{ label: 'Haight-Ashbury' }
				]
			},
			{
				label: 'San Diego',
				children: [
					{ label: 'Downtown' },
					{ label: 'La Jolla' },
					{ label: 'Pacific Beach' },
					{ label: 'Mission Beach' },
					{ label: 'Coronado' }
				]
			}
		]
	},
	{
		label: 'New York',
		children: [
			{
				label: 'New York City',
				children: [{ label: 'Manhattan' }, { label: 'Brooklyn' }, { label: 'Queens' }, { label: 'The Bronx' }, { label: 'Staten Island' }]
			},
			{
				label: 'Buffalo',
				children: [
					{ label: 'Downtown' },
					{ label: 'North Buffalo' },
					{ label: 'South Buffalo' },
					{ label: 'East Side' },
					{ label: 'West Side' }
				]
			}
		]
	},
	{
		label: 'Texas',
		children: [
			{
				label: 'Houston',
				children: [{ label: 'Downtown' }, { label: 'Midtown' }, { label: 'The Heights' }, { label: 'River Oaks' }, { label: 'Memorial' }]
			},
			{
				label: 'Dallas',
				children: [{ label: 'Downtown' }, { label: 'Uptown' }, { label: 'Deep Ellum' }, { label: 'Oak Lawn' }, { label: 'Highland Park' }]
			},
			{
				label: 'Austin',
				children: [
					{ label: 'Downtown' },
					{ label: 'South Congress' },
					{ label: 'East Austin' },
					{ label: 'West Lake Hills' },
					{ label: 'North Loop' }
				]
			}
		]
	},
	{
		label: 'Florida',
		children: [
			{
				label: 'Miami',
				children: [
					{ label: 'Downtown' },
					{ label: 'South Beach' },
					{ label: 'Brickell' },
					{ label: 'Coconut Grove' },
					{ label: 'Little Havana' }
				]
			},
			{
				label: 'Orlando',
				children: [
					{ label: 'Downtown' },
					{ label: 'Winter Park' },
					{ label: 'Lake Nona' },
					{ label: 'College Park' },
					{ label: 'Baldwin Park' }
				]
			}
		]
	},
	{
		label: 'Illinois',
		children: [
			{
				label: 'Chicago',
				children: [
					{ label: 'The Loop' },
					{ label: 'River North' },
					{ label: 'Lincoln Park' },
					{ label: 'Wicker Park' },
					{ label: 'Gold Coast' }
				]
			},
			{
				label: 'Springfield',
				children: [{ label: 'Downtown' }, { label: 'West Side' }, { label: 'East Side' }, { label: 'North End' }, { label: 'South Side' }]
			}
		]
	}
];

const linkageDiffLabeData = [
	{
		province: 'California',
		children: [
			{
				city: 'Los Angeles',
				children: [
					{ region: 'Downtown' },
					{ region: 'Hollywood' },
					{ region: 'Venice' },
					{ region: 'Santa Monica' },
					{ region: 'Beverly Hills' },
					{ region: 'Pasadena' },
					{ region: 'Long Beach' }
				]
			},
			{
				city: 'San Francisco',
				children: [
					{ region: 'Downtown' },
					{ region: 'Mission District' },
					{ region: 'North Beach' },
					{ region: 'Chinatown' },
					{ region: 'Haight-Ashbury' },
					{ region: 'Castro' },
					{ region: 'Pacific Heights' }
				]
			},
			{
				city: 'San Diego',
				children: [
					{ region: 'Downtown' },
					{ region: 'La Jolla' },
					{ region: 'Pacific Beach' },
					{ region: 'Mission Beach' },
					{ region: 'Coronado' },
					{ region: 'North Park' },
					{ region: 'Hillcrest' }
				]
			}
		]
	},
	{
		province: 'New York',
		children: [
			{
				city: 'New York City',
				children: [
					{ region: 'Manhattan' },
					{ region: 'Brooklyn' },
					{ region: 'Queens' },
					{ region: 'The Bronx' },
					{ region: 'Staten Island' },
					{ region: 'Upper East Side' },
					{ region: 'Upper West Side' },
					{ region: 'Greenwich Village' }
				]
			},
			{
				city: 'Buffalo',
				children: [
					{ region: 'Downtown' },
					{ region: 'North Buffalo' },
					{ region: 'South Buffalo' },
					{ region: 'East Side' },
					{ region: 'West Side' },
					{ region: 'Elmwood Village' }
				]
			}
		]
	}
];

export { linkageData, linkageDiffLabeData };
-->



================================================
FILE: packages/stdf/src/routes/asyncPicker/en_US/data_en.js
================================================
const linkageData = [
	{
		label: 'California',
		children: [
			{
				label: 'Los Angeles',
				children: [
					{ label: 'Downtown' },
					{ label: 'Hollywood' },
					{ label: 'Venice' },
					{ label: 'Santa Monica' },
					{ label: 'Beverly Hills' }
				]
			},
			{
				label: 'San Francisco',
				children: [
					{ label: 'Downtown' },
					{ label: 'Mission District' },
					{ label: 'North Beach' },
					{ label: 'Chinatown' },
					{ label: 'Haight-Ashbury' }
				]
			},
			{
				label: 'San Diego',
				children: [
					{ label: 'Downtown' },
					{ label: 'La Jolla' },
					{ label: 'Pacific Beach' },
					{ label: 'Mission Beach' },
					{ label: 'Coronado' }
				]
			}
		]
	},
	{
		label: 'New York',
		children: [
			{
				label: 'New York City',
				children: [{ label: 'Manhattan' }, { label: 'Brooklyn' }, { label: 'Queens' }, { label: 'The Bronx' }, { label: 'Staten Island' }]
			},
			{
				label: 'Buffalo',
				children: [
					{ label: 'Downtown' },
					{ label: 'North Buffalo' },
					{ label: 'South Buffalo' },
					{ label: 'East Side' },
					{ label: 'West Side' }
				]
			}
		]
	},
	{
		label: 'Texas',
		children: [
			{
				label: 'Houston',
				children: [{ label: 'Downtown' }, { label: 'Midtown' }, { label: 'The Heights' }, { label: 'River Oaks' }, { label: 'Memorial' }]
			},
			{
				label: 'Dallas',
				children: [{ label: 'Downtown' }, { label: 'Uptown' }, { label: 'Deep Ellum' }, { label: 'Oak Lawn' }, { label: 'Highland Park' }]
			},
			{
				label: 'Austin',
				children: [
					{ label: 'Downtown' },
					{ label: 'South Congress' },
					{ label: 'East Austin' },
					{ label: 'West Lake Hills' },
					{ label: 'North Loop' }
				]
			}
		]
	},
	{
		label: 'Florida',
		children: [
			{
				label: 'Miami',
				children: [
					{ label: 'Downtown' },
					{ label: 'South Beach' },
					{ label: 'Brickell' },
					{ label: 'Coconut Grove' },
					{ label: 'Little Havana' }
				]
			},
			{
				label: 'Orlando',
				children: [
					{ label: 'Downtown' },
					{ label: 'Winter Park' },
					{ label: 'Lake Nona' },
					{ label: 'College Park' },
					{ label: 'Baldwin Park' }
				]
			}
		]
	},
	{
		label: 'Illinois',
		children: [
			{
				label: 'Chicago',
				children: [
					{ label: 'The Loop' },
					{ label: 'River North' },
					{ label: 'Lincoln Park' },
					{ label: 'Wicker Park' },
					{ label: 'Gold Coast' }
				]
			},
			{
				label: 'Springfield',
				children: [{ label: 'Downtown' }, { label: 'West Side' }, { label: 'East Side' }, { label: 'North End' }, { label: 'South Side' }]
			}
		]
	}
];

const linkageDiffLabeData = [
	{
		province: 'California',
		children: [
			{
				city: 'Los Angeles',
				children: [
					{ region: 'Downtown' },
					{ region: 'Hollywood' },
					{ region: 'Venice' },
					{ region: 'Santa Monica' },
					{ region: 'Beverly Hills' },
					{ region: 'Pasadena' },
					{ region: 'Long Beach' }
				]
			},
			{
				city: 'San Francisco',
				children: [
					{ region: 'Downtown' },
					{ region: 'Mission District' },
					{ region: 'North Beach' },
					{ region: 'Chinatown' },
					{ region: 'Haight-Ashbury' },
					{ region: 'Castro' },
					{ region: 'Pacific Heights' }
				]
			},
			{
				city: 'San Diego',
				children: [
					{ region: 'Downtown' },
					{ region: 'La Jolla' },
					{ region: 'Pacific Beach' },
					{ region: 'Mission Beach' },
					{ region: 'Coronado' },
					{ region: 'North Park' },
					{ region: 'Hillcrest' }
				]
			}
		]
	},
	{
		province: 'New York',
		children: [
			{
				city: 'New York City',
				children: [
					{ region: 'Manhattan' },
					{ region: 'Brooklyn' },
					{ region: 'Queens' },
					{ region: 'The Bronx' },
					{ region: 'Staten Island' },
					{ region: 'Upper East Side' },
					{ region: 'Upper West Side' },
					{ region: 'Greenwich Village' }
				]
			},
			{
				city: 'Buffalo',
				children: [
					{ region: 'Downtown' },
					{ region: 'North Buffalo' },
					{ region: 'South Buffalo' },
					{ region: 'East Side' },
					{ region: 'West Side' },
					{ region: 'Elmwood Village' }
				]
			}
		]
	}
];

export { linkageData, linkageDiffLabeData };



================================================
FILE: packages/stdf/src/routes/asyncPicker/zh_CN/+page.svelte
================================================
<script lang="ts">
	import { AsyncPicker, Cell } from '$lib/index.js';
	// 为避免 Demo 页面杂乱，具体参考数据放在 data.js 文件内，可查看此页面底部注释。
	import { linkageData, linkageDiffLabeData } from './data.js';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);

	let data: { label: string; children: { label: string; children: { label: string }[] }[] }[] = $state(linkageData);
	let currentLevel = $state(0);
	let lastLevel = $state(false);
	let firstLevel = $state(true);
	let level1Data = $state(linkageData[0].children);
	let titleBind = $state('请选择省级');

	// 模拟 2 秒后获取到数据
	const nextFunc = (index: number) => {
		if (currentLevel === 0) {
			const nextData = linkageData[index].children;
			level1Data = nextData;
			setTimeout(() => {
				data = nextData as { label: string; children: { label: string; children: { label: string }[] }[] }[];
				currentLevel = 1;
				titleBind = '请选择市级';
				firstLevel = false;
			}, 2000);
		} else if (currentLevel === 1) {
			const nextData = level1Data[index].children;
			setTimeout(() => {
				data = nextData as { label: string; children: { label: string; children: { label: string }[] }[] }[];
				currentLevel = 2;
				titleBind = '请选择区级';
				lastLevel = true;
			}, 2000);
		} else {
			console.log('最后一级');
		}
	};
	const prevFunc = () => {
		if (currentLevel === 1) {
			const prevData = linkageData;
			setTimeout(() => {
				data = prevData;
				currentLevel = 0;
				titleBind = '请选择省级';
				firstLevel = true;
			}, 2000);
		} else if (currentLevel === 2) {
			const prevData = level1Data;
			setTimeout(() => {
				data = prevData as { label: string; children: { label: string; children: { label: string }[] }[] }[];
				currentLevel = 1;
				titleBind = '请选择市级';
				lastLevel = false;
			}, 2000);
		} else {
			console.log('第一级');
		}
	};

	let allIndexs: number[] = $state([]);
	let allItems: { label: string }[] = $state([]);
	const getAllDataFunc = (items: { label: string }[], indexs: number[]) => {
		allItems = items;
		allIndexs = indexs;
	};

	// 每一级对应的 labelKey 不同时的处理逻辑
	type DiffLabelKeyDataCity = { city: string; children: { region: string }[] };
	type DiffLabelKeyData = { province: string; children: DiffLabelKeyDataCity[] };
	let diffLabelKeyData: DiffLabelKeyData[] = $state(linkageDiffLabeData);
	let labelKey = $state('province');
	let diffLabelKeyCurrentLevel = $state(0);
	let diffLabelKeyLastLevel = $state(false);
	let diffLabelKeyFirstLevel = $state(true);
	let diffLabelKeyLevel1Data: DiffLabelKeyDataCity[] = $state(linkageDiffLabeData[0].children);
	const diffLabelKeyNextFunc = (index: number) => {
		if (diffLabelKeyCurrentLevel === 0) {
			const nextData: DiffLabelKeyDataCity[] = linkageDiffLabeData[index].children;
			diffLabelKeyLevel1Data = nextData;
			setTimeout(() => {
				diffLabelKeyData = nextData as unknown as DiffLabelKeyData[];
				labelKey = 'city';
				diffLabelKeyCurrentLevel = 1;
				diffLabelKeyFirstLevel = false;
			}, 2000);
		} else if (diffLabelKeyCurrentLevel === 1) {
			const nextData = diffLabelKeyLevel1Data[index].children;
			setTimeout(() => {
				diffLabelKeyData = nextData as unknown as DiffLabelKeyData[];
				diffLabelKeyCurrentLevel = 2;
				labelKey = 'region';
				diffLabelKeyLastLevel = true;
			}, 2000);
		} else {
			console.log('最后一级');
		}
	};
	const diffLabelKeyPrevFunc = () => {
		if (diffLabelKeyCurrentLevel === 1) {
			const prevData = linkageDiffLabeData;
			setTimeout(() => {
				diffLabelKeyData = prevData as unknown as DiffLabelKeyData[];
				diffLabelKeyCurrentLevel = 0;
				diffLabelKeyFirstLevel = true;
				labelKey = 'province';
			}, 2000);
		} else if (diffLabelKeyCurrentLevel === 2) {
			const prevData = diffLabelKeyLevel1Data;
			setTimeout(() => {
				diffLabelKeyData = prevData as unknown as DiffLabelKeyData[];
				diffLabelKeyCurrentLevel = 1;
				labelKey = 'city';
				diffLabelKeyLastLevel = false;
			}, 2000);
		} else {
			console.log('第一级');
		}
	};
</script>

<div class="py-4">
	<div class="px-4">
		{#if allItems.length}
			当前选定了：
			{#each allItems as item}
				<span class="mr-2 text-primary dark:text-dark">{item.label}</span>
			{/each}
		{:else}
			<div>请选定数据</div>
		{/if}
	</div>
	<div class="px-4">
		{#if allIndexs.length}
			当前选定值位于所在列的索引值分别为：
			{#each allIndexs as index}
				<span class="mr-2 text-primary dark:text-dark">{index}</span>
			{/each}
		{:else}
			<div>请选定数据</div>
		{/if}
	</div>
	<Cell
		title="基础用法"
		onclick={() => {
			visible1 = true;
			data = linkageData;
			lastLevel = false;
			firstLevel = true;
			currentLevel = 0;
			level1Data = linkageData[0].children;
		}}
	/>
	<AsyncPicker
		bind:visible={visible1}
		bind:data
		bind:lastLevel
		bind:firstLevel
		onnext={nextFunc}
		onprev={prevFunc}
		onconfirm={getAllDataFunc as (items: Record<string, unknown>[], indexs: number[]) => void}
	/>

	<Cell
		title="可见 7 行数为"
		onclick={() => {
			visible2 = true;
			data = linkageData;
			lastLevel = false;
			firstLevel = true;
			currentLevel = 0;
			level1Data = linkageData[0].children;
		}}
	/>
	<AsyncPicker bind:visible={visible2} bind:data bind:lastLevel bind:firstLevel onnext={nextFunc} onprev={prevFunc} showRow={7} />

	<Cell
		title="左对齐"
		onclick={() => {
			visible3 = true;
			data = linkageData;
			lastLevel = false;
			firstLevel = true;
			currentLevel = 0;
			level1Data = linkageData[0].children;
		}}
	/>
	<AsyncPicker bind:visible={visible3} bind:data bind:lastLevel bind:firstLevel align="left" onnext={nextFunc} onprev={prevFunc} />

	<Cell
		title="自定义上下一步文字"
		onclick={() => {
			visible5 = true;
			data = linkageData;
			lastLevel = false;
			firstLevel = true;
			currentLevel = 0;
			level1Data = linkageData[0].children;
		}}
	/>
	<AsyncPicker
		bind:visible={visible5}
		bind:data
		bind:lastLevel
		bind:firstLevel
		onnext={nextFunc}
		onprev={prevFunc}
		nextText="继续"
		prevText="返回"
	/>

	<Cell
		title="不同级别使用不同的 labelKey"
		onclick={() => {
			visible4 = true;
			diffLabelKeyData = linkageDiffLabeData;
			labelKey = 'province';
			diffLabelKeyCurrentLevel = 0;
			diffLabelKeyLastLevel = false;
			diffLabelKeyFirstLevel = true;
			diffLabelKeyLevel1Data = linkageDiffLabeData[0].children;
		}}
	/>
	<AsyncPicker
		bind:visible={visible4}
		bind:data={diffLabelKeyData}
		bind:lastLevel={diffLabelKeyLastLevel}
		bind:firstLevel={diffLabelKeyFirstLevel}
		bind:labelKey
		onnext={diffLabelKeyNextFunc}
		onprev={diffLabelKeyPrevFunc}
	/>

	<Cell
		title="换一个 Loading 效果"
		onclick={() => {
			visible6 = true;
			data = linkageData;
			lastLevel = false;
			firstLevel = true;
			currentLevel = 0;
			level1Data = linkageData[0].children;
		}}
	/>
	<AsyncPicker
		bind:visible={visible6}
		bind:data
		bind:lastLevel
		bind:firstLevel
		onnext={nextFunc}
		onprev={prevFunc}
		loading={{ type: '1_15', width: '12', height: '12' }}
	/>

	<Cell
		title="顶部来点圆角"
		onclick={() => {
			visible8 = true;
			data = linkageData;
			lastLevel = false;
			firstLevel = true;
			currentLevel = 0;
			level1Data = linkageData[0].children;
		}}
	/>
	<AsyncPicker
		bind:visible={visible8}
		bind:data
		bind:lastLevel
		bind:firstLevel
		onnext={nextFunc}
		onprev={prevFunc}
		popup={{ radius: 'xl' }}
	/>

	<Cell
		title="显示已选选项"
		onclick={() => {
			visible7 = true;
			data = linkageData;
			lastLevel = false;
			firstLevel = true;
			currentLevel = 0;
			level1Data = linkageData[0].children;
		}}
	/>
	<AsyncPicker bind:visible={visible7} bind:data bind:lastLevel bind:firstLevel onnext={nextFunc} onprev={prevFunc} showSelected />

	<Cell
		title="动态改变标题"
		onclick={() => {
			visible9 = true;
			data = linkageData;
			lastLevel = false;
			firstLevel = true;
			currentLevel = 0;
			titleBind = '请选择省级';
			level1Data = linkageData[0].children;
		}}
	/>
	<AsyncPicker
		bind:visible={visible9}
		bind:data
		bind:lastLevel
		bind:firstLevel
		bind:title={titleBind}
		onnext={nextFunc}
		onprev={prevFunc}
	/>
</div>
<!-- 
const linkageData = [
    {
        label: '云南',
        children: [
            {
                label: '昆明',
                children: [
                    { label: '盘龙区' },
                    { label: '五华区' },
                    { label: '官渡区' },
                    { label: '西山区' },
                    { label: '东川区' },
                    { label: '呈贡区' },
                    { label: '晋宁区' },
                    { label: '富民县' },
                    { label: '宜良县' },
                    { label: '石林彝族自治县' },
                    { label: '嵩明县' },
                    { label: '禄劝彝族苗族自治县' },
                    { label: '寻甸回族彝族自治县' },
                    { label: '安宁市' },
                ],
            },
            {
                label: '曲靖',
                children: [
                    { label: '麒麟区' },
                    { label: '沾益区' },
                    { label: '马龙县' },
                    { label: '陆良县' },
                    { label: '师宗县' },
                    { label: '罗平县' },
                    { label: '富源县' },
                    { label: '会泽县' },
                    { label: '宣威市' },
                ],
            },
            {
                label: '玉溪',
                children: [
                    { label: '红塔区' },
                    { label: '江川区' },
                    { label: '澄江县' },
                    { label: '通海县' },
                    { label: '华宁县' },
                    { label: '易门县' },
                    { label: '峨山彝族自治县' },
                    { label: '新平彝族傣族自治县' },
                    { label: '元江哈尼族彝族傣族自治县' },
                ],
            },
            {
                label: '保山',
                children: [
                    { label: '隆阳区' },
                    { label: '施甸县' },
                    { label: '龙陵县' },
                    { label: '昌宁县' },
                    { label: '腾冲市' },
                    { label: '龙陵县' },
                ],
            },
            {
                label: '丽江',
                children: [
                    { label: '古城区' },
                    { label: '永胜县' },
                    { label: '华坪县' },
                    { label: '玉龙纳西族自治县' },
                    { label: '宁蒗彝族自治县' },
                ],
            },
            {
                label: '普洱',
                children: [
                    { label: '思茅区' },
                    { label: '宁洱哈尼族彝族自治县' },
                    { label: '墨江哈尼族自治县' },
                    { label: '景东彝族自治县' },
                    { label: '景谷傣族彝族自治县' },
                    { label: '镇沅彝族哈尼族拉祜族自治县' },
                    { label: '江城哈尼族彝族自治县' },
                    { label: '孟连傣族拉祜族佤族自治县' },
                    { label: '澜沧拉祜族自治县' },
                    { label: '西盟佤族自治县' },
                ],
            },
            {
                label: '临沧',
                children: [
                    { label: '临翔区' },
                    { label: '凤庆县' },
                    { label: '云县' },
                    { label: '永德县' },
                    { label: '镇康县' },
                    { label: '双江拉祜族佤族布朗族傣族自治县' },
                    { label: '耿马傣族佤族自治县' },
                    { label: '沧源佤族自治县' },
                ],
            },
            {
                label: '楚雄',
                children: [
                    { label: '楚雄市' },
                    { label: '双柏县' },
                    { label: '牟定县' },
                    { label: '南华县' },
                    { label: '姚安县' },
                    { label: '大姚县' },
                    { label: '永仁县' },
                    { label: '元谋县' },
                    { label: '武定县' },
                    { label: '禄丰县' },
                ],
            },
            {
                label: '红河',
                children: [
                    { label: '个旧市' },
                    { label: '开远市' },
                    { label: '蒙自市' },
                    { label: '弥勒市' },
                    { label: '屏边苗族自治县' },
                    { label: '建水县' },
                    { label: '石屏县' },
                    { label: '泸西县' },
                    { label: '元阳县' },
                    { label: '红河县' },
                    { label: '金平苗族瑶族傣族自治县' },
                    { label: '绿春县' },
                    { label: '河口瑶族自治县' },
                ],
            },
            {
                label: '文山',
                children: [
                    { label: '文山市' },
                    { label: '砚山县' },
                    { label: '西畴县' },
                    { label: '麻栗坡县' },
                    { label: '马关县' },
                    { label: '丘北县' },
                    { label: '广南县' },
                    { label: '富宁县' },
                ],
            },
        ],
    },
    {
        label: '广东',
        children: [
            {
                label: '广州',
                children: [
                    { label: '天河区' },
                    { label: '海珠区' },
                    { label: '荔湾区' },
                    { label: '越秀区' },
                    { label: '白云区' },
                    { label: '黄埔区' },
                ],
            },
            {
                label: '深圳',
                children: [
                    { label: '罗湖区' },
                    { label: '福田区' },
                    { label: '南山区' },
                    { label: '宝安区' },
                    { label: '龙岗区' },
                    { label: '盐田区' },
                ],
            },
            {
                label: '珠海',
                children: [{ label: '香洲区' }, { label: '斗门区' }, { label: '金湾区' }],
            },
            {
                label: '汕头',
                children: [
                    { label: '龙湖区' },
                    { label: '金平区' },
                    { label: '濠江区' },
                    { label: '潮阳区' },
                    { label: '潮南区' },
                    { label: '澄海区' },
                ],
            },
            {
                label: '佛山',
                children: [{ label: '禅城区' }, { label: '南海区' }, { label: '顺德区' }, { label: '三水区' }, { label: '高明区' }],
            },
        ],
    },
    {
        label: '四川',
        children: [
            {
                label: '成都',
                children: [
                    { label: '锦江区' },
                    { label: '青羊区' },
                    { label: '金牛区' },
                    { label: '武侯区' },
                    { label: '成华区' },
                    { label: '龙泉驿区' },
                ],
            },
            {
                label: '绵阳',
                children: [
                    { label: '涪城区' },
                    { label: '游仙区' },
                    { label: '安州区' },
                    { label: '三台县' },
                    { label: '盐亭县' },
                    { label: '梓潼县' },
                ],
            },
            {
                label: '自贡',
                children: [
                    { label: '自流井区' },
                    { label: '贡井区' },
                    { label: '大安区' },
                    { label: '沿滩区' },
                    { label: '荣县' },
                    { label: '富顺县' },
                ],
            },
            {
                label: '攀枝花',
                children: [{ label: '东区' }, { label: '西区' }, { label: '仁和区' }, { label: '米易县' }, { label: '盐边县' }],
            },
        ],
    },
    {
        label: '北京',
        children: [
            {
                label: '北京市',
                children: [
                    { label: '东城区' },
                    { label: '西城区' },
                    { label: '朝阳区' },
                    { label: '丰台区' },
                    { label: '石景山区' },
                    { label: '海淀区' },
                ],
            },
        ],
    },
    {
        label: '浙江',
        children: [
            {
                label: '杭州',
                children: [
                    { label: '上城区' },
                    { label: '下城区' },
                    { label: '江干区' },
                    { label: '拱墅区' },
                    { label: '西湖区' },
                    { label: '滨江区' },
                ],
            },
            {
                label: '宁波',
                children: [
                    { label: '海曙区' },
                    { label: '江东区' },
                    { label: '江北区' },
                    { label: '北仑区' },
                    { label: '镇海区' },
                    { label: '鄞州区' },
                ],
            },
            {
                label: '温州',
                children: [
                    { label: '鹿城区' },
                    { label: '龙湾区' },
                    { label: '瓯海区' },
                    { label: '洞头区' },
                    { label: '永嘉县' },
                    { label: '平阳县' },
                ],
            },
            {
                label: '嘉兴',
                children: [
                    { label: '南湖区' },
                    { label: '秀洲区' },
                    { label: '嘉善县' },
                    { label: '海盐县' },
                    { label: '海宁市' },
                    { label: '平湖市' },
                ],
            },
            {
                label: '湖州',
                children: [{ label: '吴兴区' }, { label: '南浔区' }, { label: '德清县' }, { label: '长兴县' }, { label: '安吉县' }],
            },
        ],
    },
];

const linkageDiffLabeData = [
    {
        province: '云南',
        children: [
            {
                city: '昆明',
                children: [
                    { region: '盘龙区' },
                    { region: '五华区' },
                    { region: '官渡区' },
                    { region: '西山区' },
                    { region: '东川区' },
                    { region: '呈贡区' },
                    { region: '晋宁区' },
                    { region: '富民县' },
                    { region: '宜良县' },
                    { region: '石林彝族自治县' },
                    { region: '嵩明县' },
                    { region: '禄劝彝族苗族自治县' },
                    { region: '寻甸回族彝族自治县' },
                    { region: '安宁市' },
                ],
            },
            {
                city: '曲靖',
                children: [
                    { region: '麒麟区' },
                    { region: '沾益区' },
                    { region: '马龙县' },
                    { region: '陆良县' },
                    { region: '师宗县' },
                    { region: '罗平县' },
                    { region: '富源县' },
                    { region: '会泽县' },
                    { region: '宣威市' },
                ],
            },
            {
                city: '玉溪',
                children: [
                    { region: '红塔区' },
                    { region: '江川区' },
                    { region: '澄江县' },
                    { region: '通海县' },
                    { region: '华宁县' },
                    { region: '易门县' },
                    { region: '峨山彝族自治县' },
                    { region: '新平彝族傣族自治县' },
                    { region: '元江哈尼族彝族傣族自治县' },
                ],
            },
            {
                city: '保山',
                children: [
                    { region: '隆阳区' },
                    { region: '施甸县' },
                    { region: '龙陵县' },
                    { region: '昌宁县' },
                    { region: '腾冲市' },
                    { region: '龙陵县' },
                ],
            },
            {
                city: '丽江',
                children: [
                    { region: '古城区' },
                    { region: '永胜县' },
                    { region: '华坪县' },
                    { region: '玉龙纳西族自治县' },
                    { region: '宁蒗彝族自治县' },
                ],
            },
            {
                city: '普洱',
                children: [
                    { region: '思茅区' },
                    { region: '宁洱哈尼族彝族自治县' },
                    { region: '墨江哈尼族自治县' },
                    { region: '景东彝族自治县' },
                    { region: '景谷傣族彝族自治县' },
                    { region: '镇沅彝族哈尼族拉祜族自治县' },
                    { region: '江城哈尼族彝族自治县' },
                    { region: '孟连傣族拉祜族佤族自治县' },
                    { region: '澜沧拉祜族自治县' },
                    { region: '西盟佤族自治县' },
                ],
            },
        ],
    },
    {
        province: '广东',
        children: [
            {
                city: '广州',
                children: [
                    { region: '天河区' },
                    { region: '海珠区' },
                    { region: '荔湾区' },
                    { region: '越秀区' },
                    { region: '白云区' },
                    { region: '黄埔区' },
                ],
            },
            {
                city: '深圳',
                children: [
                    { region: '罗湖区' },
                    { region: '福田区' },
                    { region: '南山区' },
                    { region: '宝安区' },
                    { region: '龙岗区' },
                    { region: '盐田区' },
                ],
            },
        ],
    },
];

export { linkageData, linkageDiffLabeData }; -->



================================================
FILE: packages/stdf/src/routes/asyncPicker/zh_CN/data.js
================================================
const linkageData = [
	{
		label: '云南',
		children: [
			{
				label: '昆明',
				children: [
					{ label: '盘龙区' },
					{ label: '五华区' },
					{ label: '官渡区' },
					{ label: '西山区' },
					{ label: '东川区' },
					{ label: '呈贡区' },
					{ label: '晋宁区' },
					{ label: '富民县' },
					{ label: '宜良县' },
					{ label: '石林彝族自治县' },
					{ label: '嵩明县' },
					{ label: '禄劝彝族苗族自治县' },
					{ label: '寻甸回族彝族自治县' },
					{ label: '安宁市' },
				],
			},
			{
				label: '曲靖',
				children: [
					{ label: '麒麟区' },
					{ label: '沾益区' },
					{ label: '马龙县' },
					{ label: '陆良县' },
					{ label: '师宗县' },
					{ label: '罗平县' },
					{ label: '富源县' },
					{ label: '会泽县' },
					{ label: '宣威市' },
				],
			},
			{
				label: '玉溪',
				children: [
					{ label: '红塔区' },
					{ label: '江川区' },
					{ label: '澄江县' },
					{ label: '通海县' },
					{ label: '华宁县' },
					{ label: '易门县' },
					{ label: '峨山彝族自治县' },
					{ label: '新平彝族傣族自治县' },
					{ label: '元江哈尼族彝族傣族自治县' },
				],
			},
			{
				label: '保山',
				children: [
					{ label: '隆阳区' },
					{ label: '施甸县' },
					{ label: '龙陵县' },
					{ label: '昌宁县' },
					{ label: '腾冲市' },
					{ label: '龙陵县' },
				],
			},
			{
				label: '丽江',
				children: [
					{ label: '古城区' },
					{ label: '永胜县' },
					{ label: '华坪县' },
					{ label: '玉龙纳西族自治县' },
					{ label: '宁蒗彝族自治县' },
				],
			},
			{
				label: '普洱',
				children: [
					{ label: '思茅区' },
					{ label: '宁洱哈尼族彝族自治县' },
					{ label: '墨江哈尼族自治县' },
					{ label: '景东彝族自治县' },
					{ label: '景谷傣族彝族自治县' },
					{ label: '镇沅彝族哈尼族拉祜族自治县' },
					{ label: '江城哈尼族彝族自治县' },
					{ label: '孟连傣族拉祜族佤族自治县' },
					{ label: '澜沧拉祜族自治县' },
					{ label: '西盟佤族自治县' },
				],
			},
			{
				label: '临沧',
				children: [
					{ label: '临翔区' },
					{ label: '凤庆县' },
					{ label: '云县' },
					{ label: '永德县' },
					{ label: '镇康县' },
					{ label: '双江拉祜族佤族布朗族傣族自治县' },
					{ label: '耿马傣族佤族自治县' },
					{ label: '沧源佤族自治县' },
				],
			},
			{
				label: '楚雄',
				children: [
					{ label: '楚雄市' },
					{ label: '双柏县' },
					{ label: '牟定县' },
					{ label: '南华县' },
					{ label: '姚安县' },
					{ label: '大姚县' },
					{ label: '永仁县' },
					{ label: '元谋县' },
					{ label: '武定县' },
					{ label: '禄丰县' },
				],
			},
			{
				label: '红河',
				children: [
					{ label: '个旧市' },
					{ label: '开远市' },
					{ label: '蒙自市' },
					{ label: '弥勒市' },
					{ label: '屏边苗族自治县' },
					{ label: '建水县' },
					{ label: '石屏县' },
					{ label: '泸西县' },
					{ label: '元阳县' },
					{ label: '红河县' },
					{ label: '金平苗族瑶族傣族自治县' },
					{ label: '绿春县' },
					{ label: '河口瑶族自治县' },
				],
			},
			{
				label: '文山',
				children: [
					{ label: '文山市' },
					{ label: '砚山县' },
					{ label: '西畴县' },
					{ label: '麻栗坡县' },
					{ label: '马关县' },
					{ label: '丘北县' },
					{ label: '广南县' },
					{ label: '富宁县' },
				],
			},
		],
	},
	{
		label: '广东',
		children: [
			{
				label: '广州',
				children: [
					{ label: '天河区' },
					{ label: '海珠区' },
					{ label: '荔湾区' },
					{ label: '越秀区' },
					{ label: '白云区' },
					{ label: '黄埔区' },
				],
			},
			{
				label: '深圳',
				children: [
					{ label: '罗湖区' },
					{ label: '福田区' },
					{ label: '南山区' },
					{ label: '宝安区' },
					{ label: '龙岗区' },
					{ label: '盐田区' },
				],
			},
			{
				label: '珠海',
				children: [{ label: '香洲区' }, { label: '斗门区' }, { label: '金湾区' }],
			},
			{
				label: '汕头',
				children: [
					{ label: '龙湖区' },
					{ label: '金平区' },
					{ label: '濠江区' },
					{ label: '潮阳区' },
					{ label: '潮南区' },
					{ label: '澄海区' },
				],
			},
			{
				label: '佛山',
				children: [{ label: '禅城区' }, { label: '南海区' }, { label: '顺德区' }, { label: '三水区' }, { label: '高明区' }],
			},
		],
	},
	{
		label: '四川',
		children: [
			{
				label: '成都',
				children: [
					{ label: '锦江区' },
					{ label: '青羊区' },
					{ label: '金牛区' },
					{ label: '武侯区' },
					{ label: '成华区' },
					{ label: '龙泉驿区' },
				],
			},
			{
				label: '绵阳',
				children: [
					{ label: '涪城区' },
					{ label: '游仙区' },
					{ label: '安州区' },
					{ label: '三台县' },
					{ label: '盐亭县' },
					{ label: '梓潼县' },
				],
			},
			{
				label: '自贡',
				children: [
					{ label: '自流井区' },
					{ label: '贡井区' },
					{ label: '大安区' },
					{ label: '沿滩区' },
					{ label: '荣县' },
					{ label: '富顺县' },
				],
			},
			{
				label: '攀枝花',
				children: [{ label: '东区' }, { label: '西区' }, { label: '仁和区' }, { label: '米易县' }, { label: '盐边县' }],
			},
		],
	},
	{
		label: '北京',
		children: [
			{
				label: '北京市',
				children: [
					{ label: '东城区' },
					{ label: '西城区' },
					{ label: '朝阳区' },
					{ label: '丰台区' },
					{ label: '石景山区' },
					{ label: '海淀区' },
				],
			},
		],
	},
	{
		label: '浙江',
		children: [
			{
				label: '杭州',
				children: [
					{ label: '上城区' },
					{ label: '下城区' },
					{ label: '江干区' },
					{ label: '拱墅区' },
					{ label: '西湖区' },
					{ label: '滨江区' },
				],
			},
			{
				label: '宁波',
				children: [
					{ label: '海曙区' },
					{ label: '江东区' },
					{ label: '江北区' },
					{ label: '北仑区' },
					{ label: '镇海区' },
					{ label: '鄞州区' },
				],
			},
			{
				label: '温州',
				children: [
					{ label: '鹿城区' },
					{ label: '龙湾区' },
					{ label: '瓯海区' },
					{ label: '洞头区' },
					{ label: '永嘉县' },
					{ label: '平阳县' },
				],
			},
			{
				label: '嘉兴',
				children: [
					{ label: '南湖区' },
					{ label: '秀洲区' },
					{ label: '嘉善县' },
					{ label: '海盐县' },
					{ label: '海宁市' },
					{ label: '平湖市' },
				],
			},
			{
				label: '湖州',
				children: [{ label: '吴兴区' }, { label: '南浔区' }, { label: '德清县' }, { label: '长兴县' }, { label: '安吉县' }],
			},
		],
	},
];

const linkageDiffLabeData = [
	{
		province: '云南',
		children: [
			{
				city: '昆明',
				children: [
					{ region: '盘龙区' },
					{ region: '五华区' },
					{ region: '官渡区' },
					{ region: '西山区' },
					{ region: '东川区' },
					{ region: '呈贡区' },
					{ region: '晋宁区' },
					{ region: '富民县' },
					{ region: '宜良县' },
					{ region: '石林彝族自治县' },
					{ region: '嵩明县' },
					{ region: '禄劝彝族苗族自治县' },
					{ region: '寻甸回族彝族自治县' },
					{ region: '安宁市' },
				],
			},
			{
				city: '曲靖',
				children: [
					{ region: '麒麟区' },
					{ region: '沾益区' },
					{ region: '马龙县' },
					{ region: '陆良县' },
					{ region: '师宗县' },
					{ region: '罗平县' },
					{ region: '富源县' },
					{ region: '会泽县' },
					{ region: '宣威市' },
				],
			},
			{
				city: '玉溪',
				children: [
					{ region: '红塔区' },
					{ region: '江川区' },
					{ region: '澄江县' },
					{ region: '通海县' },
					{ region: '华宁县' },
					{ region: '易门县' },
					{ region: '峨山彝族自治县' },
					{ region: '新平彝族傣族自治县' },
					{ region: '元江哈尼族彝族傣族自治县' },
				],
			},
			{
				city: '保山',
				children: [
					{ region: '隆阳区' },
					{ region: '施甸县' },
					{ region: '龙陵县' },
					{ region: '昌宁县' },
					{ region: '腾冲市' },
					{ region: '龙陵县' },
				],
			},
			{
				city: '丽江',
				children: [
					{ region: '古城区' },
					{ region: '永胜县' },
					{ region: '华坪县' },
					{ region: '玉龙纳西族自治县' },
					{ region: '宁蒗彝族自治县' },
				],
			},
			{
				city: '普洱',
				children: [
					{ region: '思茅区' },
					{ region: '宁洱哈尼族彝族自治县' },
					{ region: '墨江哈尼族自治县' },
					{ region: '景东彝族自治县' },
					{ region: '景谷傣族彝族自治县' },
					{ region: '镇沅彝族哈尼族拉祜族自治县' },
					{ region: '江城哈尼族彝族自治县' },
					{ region: '孟连傣族拉祜族佤族自治县' },
					{ region: '澜沧拉祜族自治县' },
					{ region: '西盟佤族自治县' },
				],
			},
		],
	},
	{
		province: '广东',
		children: [
			{
				city: '广州',
				children: [
					{ region: '天河区' },
					{ region: '海珠区' },
					{ region: '荔湾区' },
					{ region: '越秀区' },
					{ region: '白云区' },
					{ region: '黄埔区' },
				],
			},
			{
				city: '深圳',
				children: [
					{ region: '罗湖区' },
					{ region: '福田区' },
					{ region: '南山区' },
					{ region: '宝安区' },
					{ region: '龙岗区' },
					{ region: '盐田区' },
				],
			},
		],
	},
];

export { linkageData, linkageDiffLabeData };



================================================
FILE: packages/stdf/src/routes/avatar/en_US/+page.svelte
================================================
<!-- Avatar Demo -->
<script lang="ts">
	import { Avatar, Avatars, Divider, Icon } from '$lib/index.js';

	const icons = [
		{ name: 'ri-aliens-fill', theme: true, top: -1, size: 16 },
		{ name: 'ri-user-smile-line', top: -1 },
		{ name: 'ri-shield-user-line', theme: true, top: 0, size: 32 },
		{ name: 'ri-emotion-line', theme: true, top: -1, size: 46 }
	];

	const imgNames = [
		'dota_火女.png',
		'dota_火枪.png',
		'dota_小牛.png',
		'wall_1.jpg',
		'dota_斯温.png',
		'dota_水人.png',
		'wall_2.jpg',
		'wall_3.jpg',
		'wall_4.jpg',
		'avatar_1.jpg',
		'dota_火枪.png',
		'dota_小牛.png',
		'dota_斯温.png'
	];
	const data = imgNames.map((name) => ({ image: `/assets/images/${name}` }));
</script>

<div class="px-4 py-8">
	<div class="font-bold">Different rounded corners</div>
	<div class="mb-8 mt-4 flex justify-between">
		<Avatar radius="none" />
		<Avatar />
		<Avatar radius="xl" />
		<Avatar radius="2xl" />
		<Avatar radius="full" />
	</div>

	<div class="font-bold">Different picture types and size</div>
	<div class="mb-8 mt-4 flex justify-between">
		<Avatar image="/assets/images/avatar_2.png" imgSize="s" />
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" />
		<Avatar image="/assets/images/avatar_2.png" />
		<Avatar image="/assets/images/avatar_1.jpg" />
	</div>

	<div class="font-bold">Custom background color</div>
	<div class="mb-8 mt-4 flex justify-between">
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" injClass="!bg-success" />
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" injClass="!bg-[#D65786]" />
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" injClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0] !text-white" />
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" injClass="!bg-[rgba(0,0,0,0)]" />
	</div>

	<div class="font-bold">Different border</div>
	<div class="mb-8 mt-4 flex justify-between">
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" line="solid" />
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" line="dashed" />
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" line="dotted" />
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" line="solid" injClass="border-[red] dark:border-extend1" />
	</div>

	<div class="font-bold">Replace text</div>
	<div class="mb-8 mt-4 flex justify-between">
		<Avatar alt="A" altSize="xs" />
		<Avatar alt="A" altSize="sm" />
		<Avatar alt="A" />
		<Avatar alt="A" altSize="lg" />
	</div>

	<div class="font-bold">Replace Icon</div>
	<div class="mb-8 mt-4 flex justify-between">
		{#each icons as icon}
			<Avatar {icon} />
		{/each}
	</div>

	<div class="font-bold">Different size</div>
	<div class="flex justify-between">
		<div class="mb-8 mt-4 flex flex-col items-center space-y-4">
			<Avatar size="xs" icon={{ name: 'ri-bear-smile-line', size: 16, theme: true }} />
			<Avatar size="sm" image="/assets/images/avatar_1.jpg" />
			<Avatar line="solid" />
			<Avatar size="lg" image="/assets/images/avatar_2.png" imgSize="m" />
			<Avatar size="xl" alt="A" altSize="xl" />
		</div>
		<div class="mb-8 mt-4 flex flex-col items-center space-y-4">
			<Avatar radius="full" size="xs" icon={{ name: 'ri-bear-smile-line', size: 16, theme: true }} />
			<Avatar radius="full" size="sm" image="/assets/images/avatar_1.jpg" />
			<Avatar radius="full" line="solid" />
			<Avatar radius="full" size="lg" image="/assets/images/avatar_2.png" imgSize="m" />
			<Avatar radius="full" size="xl" alt="A" altSize="xl" />
		</div>
	</div>

	<Divider />

	<div class="my-4 text-2xl font-bold">Avatar group</div>
	<div class="mb-2 mt-6 font-bold">Default</div>
	<Avatars {data} />

	<div class="mb-2 mt-6 font-bold">smaller</div>
	<Avatars {data} size="sm" lineWidth="1" />

	<div class="mb-2 mt-6 font-bold">loose</div>
	<Avatars {data} compact={4} />

	<div class="mb-2 mt-6 font-bold">Border thick point</div>
	<Avatars {data} lineWidth="8" />

	<div class="mb-2 mt-6 font-bold">Make the corners smaller</div>
	<Avatars {data} radius="2xl" />

	<div class="mb-2 mt-6 font-bold">Reverse</div>
	<Avatars {data} reverse />

	<div class="mb-2 mt-6 font-bold">A maximum of 6 are displayed</div>
	<Avatars {data} max={6} />

	<div class="mb-2 mt-6 font-bold">Top layer display increase</div>
	<Avatars {data} top="add" />

	<div class="mb-2 mt-6 font-bold">Do not show top layer</div>
	<Avatars {data} top={null} />

	<div class="mb-2 mt-6 font-bold">Custom top layer</div>
	<Avatars {data}>
		{#snippet top()}
			<button class="relative flex h-12 w-12 justify-center overflow-hidden rounded-full bg-primary-200 dark:bg-dark-200">
				<div class="flex h-full w-full items-center justify-center text-primary-950 dark:text-dark-950">
					<Icon name="ri-svelte-line" />
				</div>
			</button>
		{/snippet}
	</Avatars>
</div>



================================================
FILE: packages/stdf/src/routes/avatar/zh_CN/+page.svelte
================================================
<!-- Avatar Demo -->
<script lang="ts">
	import { Avatar, Avatars, Divider, Icon } from '$lib/index.js';

	const icons = [
		{ name: 'ri-aliens-fill', theme: true, top: -1, size: 16 },
		{ name: 'ri-user-smile-line', top: -1 },
		{ name: 'ri-shield-user-line', theme: true, top: 0, size: 32 },
		{ name: 'ri-emotion-line', theme: true, top: -1, size: 46 }
	];

	const imgNames = [
		'dota_火女.png',
		'dota_火枪.png',
		'dota_小牛.png',
		'wall_1.jpg',
		'dota_斯温.png',
		'dota_水人.png',
		'wall_2.jpg',
		'wall_3.jpg',
		'wall_4.jpg',
		'avatar_1.jpg',
		'dota_火枪.png',
		'dota_小牛.png',
		'dota_斯温.png'
	];
	const data = imgNames.map((name) => ({ image: `/assets/images/${name}` }));
</script>

<div class="px-4 py-8">
	<div class="font-bold">不同圆角</div>
	<div class="mb-8 mt-4 flex justify-between">
		<Avatar radius="none" />
		<Avatar />
		<Avatar radius="xl" />
		<Avatar radius="2xl" />
		<Avatar radius="full" />
	</div>

	<div class="font-bold">不同图片类型与大小</div>
	<div class="mb-8 mt-4 flex justify-between">
		<Avatar image="/assets/images/avatar_2.png" imgSize="s" />
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" />
		<Avatar image="/assets/images/avatar_2.png" />
		<Avatar image="/assets/images/avatar_1.jpg" />
	</div>

	<div class="font-bold">自定义背景色</div>
	<div class="mb-8 mt-4 flex justify-between">
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" injClass="!bg-success" />
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" injClass="!bg-[#D65786]" />
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" injClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0] !text-white" />
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" injClass="!bg-[rgba(0,0,0,0)]" />
	</div>

	<div class="font-bold">不同边框</div>
	<div class="mb-8 mt-4 flex justify-between">
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" line="solid" />
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" line="dashed" />
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" line="dotted" />
		<Avatar image="/assets/images/avatar_2.png" imgSize="m" line="solid" injClass="border-[red] dark:border-extend1" />
	</div>

	<div class="font-bold">替换文本</div>
	<div class="mb-8 mt-4 flex justify-between">
		<Avatar alt="张" altSize="xs" />
		<Avatar alt="张" altSize="sm" />
		<Avatar alt="张" />
		<Avatar alt="张" altSize="lg" />
	</div>

	<div class="font-bold">替换 Icon</div>
	<div class="mb-8 mt-4 flex justify-between">
		{#each icons as icon}
			<Avatar {icon} />
		{/each}
	</div>

	<div class="font-bold">不同大小</div>
	<div class="flex justify-between">
		<div class="mb-8 mt-4 flex flex-col items-center space-y-4">
			<Avatar size="xs" icon={{ name: 'ri-bear-smile-line', theme: true }} />
			<Avatar size="sm" image="/assets/images/avatar_1.jpg" />
			<Avatar line="solid" />
			<Avatar size="lg" image="/assets/images/avatar_2.png" imgSize="m" />
			<Avatar size="xl" alt="张" altSize="xl" />
		</div>
		<div class="mb-8 mt-4 flex flex-col items-center space-y-4">
			<Avatar radius="full" size="xs" icon={{ name: 'ri-bear-smile-line', theme: true }} />
			<Avatar radius="full" size="sm" image="/assets/images/avatar_1.jpg" />
			<Avatar radius="full" line="solid" />
			<Avatar radius="full" size="lg" image="/assets/images/avatar_2.png" imgSize="m" />
			<Avatar radius="full" size="xl" alt="张" altSize="xl" />
		</div>
	</div>

	<Divider />

	<div class="my-4 text-2xl font-bold">头像组</div>
	<div class="mb-2 mt-6 font-bold">默认</div>
	<Avatars {data} />

	<div class="mb-2 mt-6 font-bold">小点</div>
	<Avatars {data} size="sm" lineWidth="1" />

	<div class="mb-2 mt-6 font-bold">宽松一点</div>
	<Avatars {data} compact={4} />

	<div class="mb-2 mt-6 font-bold">边框粗点</div>
	<Avatars {data} lineWidth="8" />

	<div class="mb-2 mt-6 font-bold">圆角小点</div>
	<Avatars {data} radius="2xl" />

	<div class="mb-2 mt-6 font-bold">反向</div>
	<Avatars {data} reverse />

	<div class="mb-2 mt-6 font-bold">最多显示 6 个</div>
	<Avatars {data} max={6} />

	<div class="mb-2 mt-6 font-bold">顶层显示增加</div>
	<Avatars {data} top="add" />

	<div class="mb-2 mt-6 font-bold">不显示顶层</div>
	<Avatars {data} top={null} />

	<div class="mb-2 mt-6 font-bold">自定义顶层</div>
	<Avatars {data}>
		{#snippet top()}
			<button class="relative flex h-12 w-12 justify-center overflow-hidden rounded-full bg-primary-200 dark:bg-dark-200">
				<div class="flex h-full w-full items-center justify-center text-primary-950 dark:text-dark-950">
					<Icon name="ri-svelte-line" />
				</div>
			</button>
		{/snippet}
	</Avatars>
</div>



================================================
FILE: packages/stdf/src/routes/badge/en_US/+page.svelte
================================================
<!-- Badge Demo -->
<script lang="ts">
	import { Badge, Avatar, Button, Icon, Input, Cell } from '$lib/index.js';

	let isShow = true;
</script>

<div class="pb-4 pt-1">
	<div class="mx-4 mt-8 text-lg font-bold">Basic usage</div>
	<div class="flex justify-around p-4">
		<Badge><Avatar /></Badge>
		<Badge text="24"><Avatar /></Badge>
		<Badge text="99+"><Avatar /></Badge>
		<Badge text="New"><Avatar /></Badge>
	</div>

	<div class="mx-4 mt-8 text-lg font-bold">Different rounded corners</div>
	<div class="flex justify-around p-4">
		<Badge radius="sm"><Avatar /></Badge>
		<Badge text="24" radius="none"><Avatar /></Badge>
		<Badge text="24" radius="sm"><Avatar /></Badge>
		<Badge text="Hot" radius="leaf"><Avatar /></Badge>
	</div>

	<div class="mx-4 mt-8 text-lg font-bold">Located on the left</div>
	<div class="flex justify-around p-4">
		<Badge isLeft><Avatar /></Badge>
		<Badge isLeft text="24"><Avatar /></Badge>
		<Badge isLeft text="24" radius="leaf"><Avatar /></Badge>
		<Badge isLeft text="sharp"><Avatar /></Badge>
	</div>

	<div class="mx-4 mt-8 text-lg font-bold">Match other components</div>
	<div class="flex justify-around p-4">
		<Badge text="Cool" radius="leaf" offsetX={-6}><Icon name="ri-spy-fill" /></Badge>
		<Badge text="Great" radius="leaf" offsetX={-10}><Icon name="ri-medal-fill" /></Badge>
		<Badge text="Happy" radius="leaf" offsetX={-12}><Icon name="ri-cake-2-fill" /></Badge>
	</div>
	<Badge text="Hot" offsetX={18} offsetY={8}><Button>Match Button</Button></Badge>
	<Badge text="Required" offsetX={30} offsetY={26}><Input title="Match Input" /></Badge>
	<Cell title="Match Cell">
		{#snippet detailChild()}
			<Badge isInner />
		{/snippet}
	</Cell>
	<Cell title="Match Cell" line={false}>
		{#snippet detailChild()}
			<Badge text="99+" isInner />
		{/snippet}
	</Cell>
	<Cell title="Match no radius corner Cell" radius="none">
		{#snippet detailChild()}
			<Badge text="new version" radius="sm" isInner />
		{/snippet}
	</Cell>
	<Cell title="Match full radius Cell" radius="full">
		{#snippet detailChild()}
			<Badge isInner />
		{/snippet}
	</Cell>

	<div class="mx-4 mt-8 text-lg font-bold">Badge animation</div>
	<div class="flex justify-around p-4">
		<Badge {isShow}><Avatar /></Badge>
		<Badge text="24" {isShow}><Avatar /></Badge>
		<Badge text="24" radius="sm" {isShow}><Avatar /></Badge>
		<Badge text="Hot" radius="leaf" {isShow}><Avatar /></Badge>
	</div>
	<Cell title={!isShow ? 'Hidden' : 'Show'}>
		{#snippet detailChild()}
			<Badge isInner {isShow} />
		{/snippet}
	</Cell>
	<Button onclick={() => (isShow = !isShow)}>Click {isShow ? 'Hidden' : 'Show'} Badge</Button>

	<div class="mx-4 mt-8 text-lg font-bold">Custom background color and border</div>
	<div class="flex justify-around p-4">
		<Badge text="Theme" injClass="!bg-primary dark:!bg-dark text-white dark:text-black"><Avatar /></Badge>
		<Badge text="New" injClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0]"><Avatar /></Badge>
		<Badge radius="sm" injClass="ring-2 ring-[#ebeef2] dark:ring-[#414248]"><Avatar image="/assets/images/avatar_1.jpg" /></Badge>
		<Badge offsetX={9} offsetY={9} injClass="ring-2 ring-[#ebeef2] dark:ring-[#414248]">
			<Avatar radius="full" image="/assets/images/avatar_1.jpg" />
		</Badge>
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/badge/zh_CN/+page.svelte
================================================
<!-- Badge Demo -->
<script lang="ts">
	import { Badge, Avatar, Button, Icon, Input, Cell } from '$lib/index.js';

	let isShow = $state(true);
</script>

<div class="pb-4 pt-1">
	<div class="mx-4 mt-8 text-lg font-bold">基础用法</div>
	<div class="flex justify-around p-4">
		<Badge><Avatar /></Badge>
		<Badge text="24"><Avatar /></Badge>
		<Badge text="99+"><Avatar /></Badge>
		<Badge text="New"><Avatar /></Badge>
	</div>

	<div class="mx-4 mt-8 text-lg font-bold">不同圆角</div>
	<div class="flex justify-around p-4">
		<Badge radius="sm"><Avatar /></Badge>
		<Badge text="24" radius="none"><Avatar /></Badge>
		<Badge text="24" radius="sm"><Avatar /></Badge>
		<Badge text="Hot" radius="leaf"><Avatar /></Badge>
	</div>

	<div class="mx-4 mt-8 text-lg font-bold">位于左侧</div>
	<div class="flex justify-around p-4">
		<Badge isLeft><Avatar /></Badge>
		<Badge isLeft text="24"><Avatar /></Badge>
		<Badge isLeft text="24" radius="leaf"><Avatar /></Badge>
		<Badge isLeft text="厉害"><Avatar /></Badge>
	</div>

	<div class="mx-4 mt-8 text-lg font-bold">搭配其他组件</div>
	<div class="flex justify-around p-4">
		<Badge text="帅" radius="leaf"><Icon name="ri-spy-fill" /></Badge>
		<Badge text="棒" radius="leaf"><Icon name="ri-medal-fill" /></Badge>
		<Badge text="Happy" radius="leaf" offsetX={-12}><Icon name="ri-cake-2-fill" /></Badge>
	</div>
	<Badge text="Hot" offsetX={18} offsetY={8}><Button>搭配 Button</Button></Badge>
	<Badge text="必填" offsetX={18} offsetY={26}><Input title="搭配 Input" /></Badge>
	<Cell title="搭配 Cell">
		{#snippet detailChild()}
			<Badge isInner />
		{/snippet}
	</Cell>
	<Cell title="搭配 Cell" line={false}>
		{#snippet detailChild()}
			<Badge text="99+" isInner />
		{/snippet}
	</Cell>
	<Cell title="搭配无圆角 Cell" radius="none">
		{#snippet detailChild()}
			<Badge text="新版本" radius="sm" isInner />
		{/snippet}
	</Cell>
	<Cell title="搭配全圆角 Cell" radius="full">
		{#snippet detailChild()}
			<Badge isInner />
		{/snippet}
	</Cell>

	<div class="mx-4 mt-8 text-lg font-bold">徽标动画</div>
	<div class="flex justify-around p-4">
		<Badge {isShow}><Avatar /></Badge>
		<Badge text="24" {isShow}><Avatar /></Badge>
		<Badge text="24" radius="sm" {isShow}><Avatar /></Badge>
		<Badge text="Hot" radius="leaf" {isShow}><Avatar /></Badge>
	</div>
	<Cell title={!isShow ? '隐藏' : '显示'}>
		{#snippet detailChild()}
			<Badge isInner {isShow} />
		{/snippet}
	</Cell>
	<Button onclick={() => (isShow = !isShow)}>点击{isShow ? '隐藏' : '显示'}徽标</Button>

	<div class="mx-4 mt-8 text-lg font-bold">自定义背景色与边框</div>
	<div class="flex justify-around p-4">
		<Badge text="Theme" injClass="!bg-primary dark:!bg-dark text-white dark:text-black"><Avatar /></Badge>
		<Badge text="New" injClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0]"><Avatar /></Badge>
		<Badge radius="sm" injClass="ring-2 ring-[#ebeef2] dark:ring-[#414248]"><Avatar image="/assets/images/avatar_1.jpg" /></Badge>
		<Badge offsetX={9} offsetY={9} injClass="ring-2 ring-[#ebeef2] dark:ring-[#414248]">
			<Avatar radius="full" image="/assets/images/avatar_1.jpg" />
		</Badge>
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/bottomSheet/en_US/+page.svelte
================================================
<!-- BottomSheet Demo -->
<script lang="ts">
	import { BottomSheet, Cell, Toast, Button } from '$lib/index.js';
	import Aphorism from '../../components/Aphorism.svelte';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);

	let toastBackVisible = $state(false);
	let toastCloseVisible = $state(false);

	const stayHeightList = [40, 60, 80];
	let currentHeight = $state(60);
	const heightChangeFunc = (height: number) => (currentHeight = height);
</script>

<div class="py-4">
	<Cell title="Basic Usage" onclick={() => (visible1 = true)} />
	<BottomSheet bind:visible={visible1} title="This area supports sliding">
		<div class="flex h-full flex-col justify-center text-center">
			<div>This is the content area</div>
		</div>
	</BottomSheet>

	<Cell title="Content area scrolling" onclick={() => (visible8 = true)} />
	<BottomSheet bind:visible={visible8}>
		<Aphorism num={12} />
	</BottomSheet>

	<Cell title="With back button" onclick={() => (visible2 = true)} />
	<BottomSheet
		bind:visible={visible2}
		showBackIcon
		title="Click back and close to trigger events"
		onback={() => (toastBackVisible = true)}
		onclose={() => (toastCloseVisible = true)}
	>
		<Aphorism num={12} />
	</BottomSheet>
	<Toast bind:visible={toastBackVisible} message="Triggered BottomSheet return event!" />
	<Toast bind:visible={toastCloseVisible} message="Triggered BottomSheet close event!" />

	<Cell title="Initial height is 90" onclick={() => (visible3 = true)} />
	<BottomSheet bind:visible={visible3} stayHeightIndex={2}>
		<Aphorism num={12} />
	</BottomSheet>

	<Cell title="Fixed height is 40/60/80" onclick={() => (visible4 = true)} />
	<BottomSheet
		bind:visible={visible4}
		{stayHeightList}
		onheightChange={heightChangeFunc}
		title={`Current fixed height is ${currentHeight}`}
	>
		<Aphorism num={12} />
	</BottomSheet>

	<Cell title="Click mask to close" onclick={() => (visible5 = true)} />
	<BottomSheet bind:visible={visible5} maskClosable>
		<Aphorism num={2} />
	</BottomSheet>

	<Cell title="Transition time is 1 second" onclick={() => (visible6 = true)} />
	<BottomSheet bind:visible={visible6} duration={1000}>
		<Aphorism num={12} />
	</BottomSheet>

	<Cell title="Mask completely transparent and blurry" onclick={() => (visible7 = true)} />
	<BottomSheet bind:visible={visible7} mask={{ opacity: '0', backdropBlur: 'sm' }}>
		<Aphorism num={2} />
	</BottomSheet>

	<Cell title="Header does not display any content" onclick={() => (visible9 = true)} />
	<BottomSheet bind:visible={visible9} showDivider={false} closeContent="" title="">
		<div class="flex h-full flex-col justify-around px-4 py-8 text-center">
			<div>Header area</div>
			<div>Title</div>
			<div>Back and close icon</div>
			<div>Divider</div>
			<div>None</div>
			<div>Position still reserved as a sliding touch area</div>
			<div class="mb-8">
				<Button onclick={() => (visible9 = false)}>Close</Button>
			</div>
		</div>
	</BottomSheet>

	<Cell title="Hide close icon and center title" onclick={() => (visible10 = true)} />
	<BottomSheet bind:visible={visible10} closeContent="" titleAlign="center" maskClosable title="Click mask to close">
		<Aphorism num={2} />
	</BottomSheet>

	<Cell title="Another close icon" onclick={() => (visible13 = true)} />
	<BottomSheet bind:visible={visible13} closeContent="closeIcon">
		<Aphorism num={2} />
	</BottomSheet>

	<Cell title="Custom close text" onclick={() => (visible14 = true)} />
	<BottomSheet bind:visible={visible14} closeContent="Complete">
		<Aphorism num={2} />
	</BottomSheet>

	<Cell title="Different rounded style" onclick={() => (visible12 = true)} />
	<BottomSheet bind:visible={visible12} radius="middle" showBackIcon>
		<Aphorism num={2} />
	</BottomSheet>

	<Cell title="Slide to bottom to close" onclick={() => (visible11 = true)} />
	<BottomSheet bind:visible={visible11} closeHeight={10} closeContent="">
		<div class="p-4">
			Set closeHeight to 10. If the position distance is less than 10% of the page height when sliding ends, it will be automatically
			closed.
		</div>
	</BottomSheet>
</div>

<!-- Aphorism.svelte -->
<!-- 
<script lang="ts">
	// 引入数据
	// import data
	import aphorisms from '../../data/aphorisms';

	/**
	 * @typedef {Object} Props
	 * @property {number} [num] - number of items to display
	 * @property {boolean} [compact] - whether to use compact mode
	 */
	/** @type {Props} */
	let { num = 0, compact = false } = $props();

	// 从 aphorisms 随机取出 num 条数据
	// get num items from aphorisms randomly
	const aphorismsList = aphorisms.sort(() => Math.random() - 0.5).slice(0, num);
</script>

<div class="{compact ? '' : 'px-4 py-8 '}divide-y divide-black/5 dark:divide-white/5">
	{#each aphorismsList as item}
		<div class:py-6={num > 1}>
			<div class="text-sm text-justify">{item.text}</div>
			<div class="text-right mt-1" class:italic={item.fromItalic}>{item.from}</div>
		</div>
	{/each}
</div>
-->



================================================
FILE: packages/stdf/src/routes/bottomSheet/zh_CN/+page.svelte
================================================
<!-- BottomSheet Demo -->
<script lang="ts">
	import { BottomSheet, Cell, Toast, Button } from '$lib/index.js';
	import Aphorism from '../../components/Aphorism.svelte';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);

	let toastBackVisible = $state(false);
	let toastCloseVisible = $state(false);

	const stayHeightList = [40, 60, 80];
	let currentHeight = $state(60);
	const heightChangeFunc = (height: number) => (currentHeight = height);
</script>

<div class="py-4">
	<Cell title="基础用法" onclick={() => (visible1 = true)} />
	<BottomSheet bind:visible={visible1} title="此区域支持滑动">
		<div class="flex h-full flex-col justify-center text-center">
			<div>这里是内容区域</div>
		</div>
	</BottomSheet>

	<Cell title="内容区域滚动" onclick={() => (visible8 = true)} />
	<BottomSheet bind:visible={visible8}>
		<Aphorism num={12} />
	</BottomSheet>

	<Cell title="有返回按钮" onclick={() => (visible2 = true)} />
	<BottomSheet
		bind:visible={visible2}
		showBackIcon
		title="点击返回与关闭可触发事件"
		onback={() => (toastBackVisible = true)}
		onclose={() => (toastCloseVisible = true)}
	>
		<Aphorism num={12} />
	</BottomSheet>
	<Toast bind:visible={toastBackVisible} message="触发了 BottomSheet 返回事件！" />
	<Toast bind:visible={toastCloseVisible} message="触发了 BottomSheet 关闭事件！" />

	<Cell title="初始高度为 90" onclick={() => (visible3 = true)} />
	<BottomSheet bind:visible={visible3} stayHeightIndex={2}>
		<Aphorism num={12} />
	</BottomSheet>

	<Cell title="固定高度为 40/60/80" onclick={() => (visible4 = true)} />
	<BottomSheet bind:visible={visible4} {stayHeightList} onheightChange={heightChangeFunc} title={`当前固定高度为${currentHeight}`}>
		<Aphorism num={12} />
	</BottomSheet>

	<Cell title="点击遮罩可关闭" onclick={() => (visible5 = true)} />
	<BottomSheet bind:visible={visible5} maskClosable>
		<Aphorism num={2} />
	</BottomSheet>

	<Cell title="出现过渡时间为 1 秒" onclick={() => (visible6 = true)} />
	<BottomSheet bind:visible={visible6} duration={1000}>
		<Aphorism num={12} />
	</BottomSheet>

	<Cell title="遮罩完全透明且模糊" onclick={() => (visible7 = true)} />
	<BottomSheet bind:visible={visible7} mask={{ opacity: '0', backdropBlur: 'sm' }}>
		<Aphorism num={2} />
	</BottomSheet>

	<Cell title="头部不显示任何内容" onclick={() => (visible9 = true)} />
	<BottomSheet bind:visible={visible9} showDivider={false} closeContent="" title="">
		<div class="flex h-full flex-col justify-around px-4 py-8 text-center">
			<div>头部区域</div>
			<div>标题</div>
			<div>返回与关闭图标</div>
			<div>分割线</div>
			<div>都不显示</div>
			<div>位置依旧保留作为滑动触控区域</div>
			<div class="mb-8">
				<Button onclick={() => (visible9 = false)}>关闭</Button>
			</div>
		</div>
	</BottomSheet>

	<Cell title="隐藏关闭图标且标题居中" onclick={() => (visible10 = true)} />
	<BottomSheet bind:visible={visible10} closeContent="" titleAlign="center" maskClosable title="点击遮罩关闭">
		<Aphorism num={2} />
	</BottomSheet>

	<Cell title="另一种关闭图标" onclick={() => (visible13 = true)} />
	<BottomSheet bind:visible={visible13} closeContent="closeIcon">
		<Aphorism num={2} />
	</BottomSheet>

	<Cell title="关闭区域自定义文字" onclick={() => (visible14 = true)} />
	<BottomSheet bind:visible={visible14} closeContent="完成">
		<Aphorism num={2} />
	</BottomSheet>

	<Cell title="图标不同圆角风格" onclick={() => (visible12 = true)} />
	<BottomSheet bind:visible={visible12} radius="middle" showBackIcon>
		<Aphorism num={2} />
	</BottomSheet>

	<Cell title="可下滑到底部关闭" onclick={() => (visible11 = true)} />
	<BottomSheet bind:visible={visible11} closeHeight={10} closeContent="">
		<div class="p-4">将 closeHeight 设置为 10，如果滑动结束时位置距离页面底部小于页面高度的 10% 则自动关闭。</div>
	</BottomSheet>
</div>

<!-- Aphorism.svelte -->
<!-- 
<script lang=""ts>
	// 引入数据
	// import data
	import aphorisms from '../../data/aphorisms';

	/**
	 * @typedef {Object} Props
	 * @property {number} [num] - number of items to display
	 * @property {boolean} [compact] - whether to use compact mode
	 */
	/** @type {Props} */
	let { num = 0, compact = false } = $props();

	// 从 aphorisms 随机取出 num 条数据
	// get num items from aphorisms randomly
	const aphorismsList = aphorisms.sort(() => Math.random() - 0.5).slice(0, num);
</script>

<div class="{compact ? '' : 'px-4 py-8 '}divide-y divide-black/5 dark:divide-white/5">
	{#each aphorismsList as item}
		<div class:py-6={num > 1}>
			<div class="text-sm text-justify">{item.text}</div>
			<div class="text-right mt-1" class:italic={item.fromItalic}>{item.from}</div>
		</div>
	{/each}
</div>
-->



================================================
FILE: packages/stdf/src/routes/button/en_US/+page.svelte
================================================
<!-- Button Demo -->
<script lang="ts">
	import { Button, Icon, Toast, Loading } from '$lib/index.js';

	let visible = $state(false);
</script>

<div class="flex flex-col space-y-8 py-8">
	<div>
		<div class="p-4 font-bold">Different states</div>
		<Button>Default</Button>
		<Button state="success">Success</Button>
		<Button state="warning">Warning</Button>
		<Button state="error">Error</Button>
		<Button state="info">Information</Button>
	</div>
	<div>
		<div class="p-4 font-bold">Different rounded style</div>
		<Button>Default</Button>
		<Button radius="none">No rounded</Button>
		<Button radius="xl">Large rounded corner</Button>
		<Button radius="2xl">Larger corner</Button>
		<Button radius="full">Full rounded corner</Button>
	</div>
	<div>
		<div class="p-4 font-bold">Different fill mode</div>
		<Button>Default</Button>
		<Button fill="line">Colorless linear</Button>
		<Button fill="lineLight">Light color linearity</Button>
		<Button fill="lineTheme">Theme color linear</Button>
		<Button fill="text">Colorless pure text</Button>
		<Button fill="textTheme">Pure text of theme color</Button>
		<Button fill="colorLight">Light color filling</Button>
	</div>
	<div>
		<div class="p-4 font-bold">Different border style</div>
		<Button fill="lineTheme">Solid line</Button>
		<Button fill="lineTheme" line="dashed">Dashed line</Button>
		<Button fill="lineTheme" line="dotted">Dotted line</Button>
	</div>
	<div>
		<div class="p-4 font-bold">Different size</div>
		<Button size="full" radius="none">There is no rounded corner</Button>
		<Button>Default</Button>
		<Button size="md">Medium</Button>
		<Button size="sm">Small</Button>
		<Button size="auto">AUTO</Button>
		<Button size="auto">
			<div class="px-1">
				<Icon name="ri-plane-fill" size={20} top={-2} />
			</div>
		</Button>
	</div>
	<div>
		<div class="p-4 font-bold">Different heights</div>
		<Button heightOut="0">The external height is 0</Button>
		<Button heightIn="0">Internal height is 0</Button>
	</div>
	<div>
		<div class="p-4 font-bold">Fixed size</div>
		<div class="flex items-center justify-around">
			<Button customSize customWidth={40} customHeight={40} radius="full">W</Button>
			<Button customSize customWidth={40} customHeight={40} radius="xl">&</Button>
			<Button customSize customWidth={40} customHeight={40}>H</Button>
			<Button customSize customWidth={40} customHeight={40} radius="none">equal</Button>
			<Button fill="lineTheme" customSize customWidth={40} customHeight={40}>
				<Icon name="ri-plane-fill" size={20} top={-2} />
			</Button>
			<Button radius="full" fill="lineTheme" customSize customWidth={40} customHeight={40}>
				<Icon name="ri-plane-fill" size={20} top={-2} />
			</Button>
			<Button radius="full" line="dashed" fill="lineTheme" customSize customWidth={40} customHeight={40}>
				<Icon name="ri-plane-fill" size={20} top={-2} />
			</Button>
			<Button radius="full" customSize customWidth={24} customHeight={24} heightIn="0">
				<Icon name="ri-plane-fill" size={12} top={-2} />
			</Button>
		</div>
	</div>
	<div>
		<div class="p-4 font-bold">Disable</div>
		<Button disabled>Disable</Button>
		<Button fill="lineTheme" disabled>Disable</Button>
	</div>
	<div>
		<div class="p-4 font-bold">With icon</div>
		<Button icon={{ name: 'ri-share-forward-2-fill', size: 18, top: -2 }}>Throw the two way foil</Button>
		<Button fill="lineTheme" icon={{ name: 'ri-mic-off-fill', size: 16, top: -2 }}>Start the surface wall plan</Button>
	</div>
	<div>
		<div class="p-4 font-bold">With loading (disabled by default)</div>
		<Button loading={{ inverse: true, height: '6', width: '6' }}>Loading</Button>
		<Button loading={{ inverse: true, width: '16', height: '6', type: '1_28' }}>Loading</Button>
		<Button loading={{ inverse: true, height: '6', width: '6' }} disabledLoading={false}>Loading</Button>
	</div>
	<div>
		<div class="p-4 font-bold">With icon (passed through Snippet)</div>
		<Button>
			<Icon name="ri-share-forward-2-fill" size={18} top={-2} />
			Throw the two way foil
		</Button>
		<Button fill="lineTheme">
			<Icon name="ri-mic-off-fill" size={16} top={-2} />
			Start the surface wall plan
		</Button>
	</div>
	<div>
		<div class="p-4 font-bold">Load (passed through Snippet)</div>
		<Button>
			<Loading inverse height="6" width="6" />
		</Button>
		<Button>
			<Loading inverse width="16" height="6" type="1_17" />
		</Button>
	</div>
	<div>
		<div class="p-4 font-bold">Love version</div>
		<Button love>Care version button</Button>
		<Button love fill="lineTheme">
			<Icon name="ri-hand-heart-line" size={22} top={-2} />
			Care version button
		</Button>
	</div>
	<div>
		<div class="p-4 font-bold">Customize</div>
		<Button injClass="bg-[#C84031] dark:bg-[#77B941]">Solid color filling</Button>
		<Button injClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0] !text-white">Gradient filling</Button>
		<Button fill="line" injClass="border-[#C84031] dark:border-[#77B941] !text-[#C84031] dark:!text-[#77B941]">Linear</Button>
		<Button injClass="shadow-md shadow-black/30 dark:shadow-white/30">Shadow</Button>
		<Button radius="full" injClass="shadow-lg shadow-primary/40 dark:shadow-dark/40">Shadow</Button>
	</div>
	<div>
		<div class="p-4 font-bold">Button group</div>
		<Button fill="lineTheme" heightIn="0" group>
			<div class="flex w-full">
				<button class="flex-1 border-r border-primary py-2 active:opacity-80 dark:border-dark">
					<Icon name="ri-apps-2-line" size={18} top={-2} />
					Application
				</button>
				<button class="flex-1 border-r border-primary py-2 active:opacity-80 dark:border-dark">
					<Icon name="ri-star-line" size={18} top={-2} />
					Collect
				</button>
				<button class="flex-1 py-2 active:opacity-80" onclick={() => (visible = true)}>
					<Icon name="ri-share-forward-line" size={18} top={-2} />
					Share
				</button>
			</div>
		</Button>
		<Button radius="full" heightIn="0" group>
			<div class="flex w-full">
				<button class="flex-1 border-r border-white py-2 active:opacity-80 dark:border-black">
					<Icon name="ri-apps-2-line" size={18} top={-2} />
					Application
				</button>
				<button class="flex-1 border-r border-white py-2 active:opacity-80 dark:border-black">
					<Icon name="ri-star-line" size={18} top={-2} />
					Collect
				</button>
				<button class="flex-1 py-2 active:opacity-80" onclick={() => (visible = true)}>
					<Icon name="ri-share-forward-line" size={18} top={-2} />
					Share
				</button>
			</div>
		</Button>
	</div>
</div>
<Toast bind:visible message="Click share in the button group!" />



================================================
FILE: packages/stdf/src/routes/button/zh_CN/+page.svelte
================================================
<!-- Button Demo -->
<script lang="ts">
	import { Button, Icon, Toast, Loading } from '$lib/index.js';

	let visible = $state(false);
</script>

<div class="flex flex-col space-y-8 py-8">
	<div>
		<div class="p-4 font-bold">不同状态色</div>
		<Button>默认</Button>
		<Button state="success">成功</Button>
		<Button state="warning">警告</Button>
		<Button state="error">错误</Button>
		<Button state="info">信息</Button>
	</div>
	<div>
		<div class="p-4 font-bold">不同圆角风格</div>
		<Button>默认</Button>
		<Button radius="none">无圆角</Button>
		<Button radius="xl">大圆角</Button>
		<Button radius="2xl">更大圆角</Button>
		<Button radius="full">全圆角</Button>
	</div>
	<div>
		<div class="p-4 font-bold">不同填充模式</div>
		<Button>默认</Button>
		<Button fill="line">无色线性</Button>
		<Button fill="lineLight">浅色线性</Button>
		<Button fill="lineTheme">主题色线性</Button>
		<Button fill="text">无色纯文本</Button>
		<Button fill="textTheme">主题色纯文本</Button>
		<Button fill="colorLight">浅色填充</Button>
	</div>
	<div>
		<div class="p-4 font-bold">不同边框风格</div>
		<Button fill="lineTheme">实线</Button>
		<Button fill="lineTheme" line="dashed">虚线</Button>
		<Button fill="lineTheme" line="dotted">点线</Button>
	</div>
	<div>
		<div class="p-4 font-bold">不同大小</div>
		<Button size="full" radius="none">通栏且无圆角</Button>
		<Button>默认</Button>
		<Button size="md">中号</Button>
		<Button size="sm">小号</Button>
		<Button size="auto">AUTO</Button>
		<Button size="auto">
			<div class="px-1">
				<Icon name="ri-plane-fill" size={20} top={-2} />
			</div>
		</Button>
	</div>
	<div>
		<div class="p-4 font-bold">不同高度</div>
		<Button heightOut="0">外部高度为 0</Button>
		<Button heightIn="0">内部高度为 0</Button>
	</div>
	<div>
		<div class="p-4 font-bold">固定大小</div>
		<div class="flex items-center justify-around">
			<Button customSize customWidth={40} customHeight={40} radius="full">宽</Button>
			<Button customSize customWidth={40} customHeight={40} radius="xl">高</Button>
			<Button customSize customWidth={40} customHeight={40}>一</Button>
			<Button customSize customWidth={40} customHeight={40} radius="none">致</Button>
			<Button fill="lineTheme" customSize customWidth={40} customHeight={40}>
				<Icon name="ri-plane-fill" size={20} top={-2} />
			</Button>
			<Button radius="full" fill="lineTheme" customSize customWidth={40} customHeight={40}>
				<Icon name="ri-plane-fill" size={20} top={-2} />
			</Button>
			<Button radius="full" line="dashed" fill="lineTheme" customSize customWidth={40} customHeight={40}>
				<Icon name="ri-plane-fill" size={20} top={-2} />
			</Button>
			<Button radius="full" customSize customWidth={24} customHeight={24} heightIn="0">
				<Icon name="ri-plane-fill" size={12} top={-2} />
			</Button>
		</div>
	</div>
	<div>
		<div class="p-4 font-bold">禁用</div>
		<Button disabled>禁用</Button>
		<Button fill="lineTheme" disabled>禁用</Button>
	</div>
	<div>
		<div class="p-4 font-bold">带图标</div>
		<Button icon={{ name: 'ri-share-forward-2-fill', size: 18, top: -2 }}>投掷二向箔</Button>
		<Button fill="lineTheme" icon={{ name: 'ri-mic-off-fill', size: 16, top: -2 }}>启动面壁计划</Button>
	</div>
	<div>
		<div class="p-4 font-bold">带加载（默认禁用）</div>
		<Button loading={{ inverse: true, height: '6', width: '6' }}>加载中</Button>
		<Button loading={{ inverse: true, height: '6', width: '6', type: '1_28' }}>加载中</Button>
		<Button loading={{ inverse: true, height: '6', width: '6' }} disabledLoading={false}>加载中</Button>
	</div>
	<div>
		<div class="p-4 font-bold">带图标（通过 Snippet 传入）</div>
		<Button>
			<Icon name="ri-share-forward-2-fill" size={18} top={-2} />
			投掷二向箔
		</Button>
		<Button fill="lineTheme">
			<Icon name="ri-mic-off-fill" size={16} top={-2} />
			启动面壁计划
		</Button>
	</div>
	<div>
		<div class="p-4 font-bold">加载（通过 Snippet 传入）</div>
		<Button>
			<Loading inverse height="6" width="6" />
		</Button>
		<Button>
			<Loading inverse width="16" height="6" type="1_17" />
		</Button>
	</div>
	<div>
		<div class="p-4 font-bold">关爱版</div>
		<Button love>关爱版按钮</Button>
		<Button love fill="lineTheme">
			<Icon name="ri-hand-heart-line" size={22} top={-2} />
			关爱版按钮
		</Button>
	</div>
	<div>
		<div class="p-4 font-bold">自定义</div>
		<Button injClass="bg-[#C84031] dark:bg-[#77B941]">纯色填充</Button>
		<Button injClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0] !text-white">渐变填充</Button>
		<Button fill="line" injClass="border-[#C84031] dark:border-[#77B941] !text-[#C84031] dark:!text-[#77B941]">线性</Button>
		<Button injClass="shadow-md shadow-black/30 dark:shadow-white/30">阴影</Button>
		<Button radius="full" injClass="shadow-lg shadow-primary/40 dark:shadow-dark/40">颜色阴影</Button>
	</div>
	<div>
		<div class="p-4 font-bold">按钮组</div>
		<Button fill="lineTheme" heightIn="0" group>
			<div class="flex w-full">
				<button class="flex-1 border-r border-primary py-2 active:opacity-80 dark:border-dark">
					<Icon name="ri-apps-2-line" size={18} top={-2} />
					应用
				</button>
				<button class="flex-1 border-r border-primary py-2 active:opacity-80 dark:border-dark">
					<Icon name="ri-star-line" size={18} top={-2} />
					收藏
				</button>
				<button class="flex-1 py-2 active:opacity-80" onclick={() => (visible = true)}>
					<Icon name="ri-share-forward-line" size={18} top={-2} />
					分享
				</button>
			</div>
		</Button>
		<Button radius="full" heightIn="0" group>
			<div class="flex w-full">
				<button class="flex-1 border-r border-white py-2 active:opacity-80 dark:border-black">
					<Icon name="ri-apps-2-line" size={18} top={-2} />
					应用
				</button>
				<button class="flex-1 border-r border-white py-2 active:opacity-80 dark:border-black">
					<Icon name="ri-star-line" size={18} top={-2} />
					收藏
				</button>
				<button class="flex-1 py-2 active:opacity-80" onclick={() => (visible = true)}>
					<Icon name="ri-share-forward-line" size={18} top={-2} />
					分享
				</button>
			</div>
		</Button>
	</div>
</div>
<Toast bind:visible message="点击了按钮组中的分享！" />



================================================
FILE: packages/stdf/src/routes/calendar/en_US/+page.svelte
================================================
<!-- Calendar Demo -->
<script lang="ts">
	import { Cell, Calendar } from '$lib/index.js';
	import type { InfoDateProps } from '$lib/types/index.js';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);
	let visible15 = $state(false);
	let visible16 = $state(false);
	let visible17 = $state(false);
	let visible18 = $state(false);
	let visible19 = $state(false);
	let visible20 = $state(false);
	let visible21 = $state(false);
	let visible22 = $state(false);
	let visible23 = $state(false);
	let visible24 = $state(false);

	// The 6 days after the current date randomly takes out the INFODATES array, the Date format is yyyymmdd, and the month and day make up for 2 digits
	const now = new Date();
	const infoDates: InfoDateProps[] = $state([]);
	for (let i = 0; i < 6; i++) {
		const date = new Date(now.getTime() + i * 24 * 60 * 60 * 1000);
		infoDates.push({
			text: `${date.getFullYear()}${(date.getMonth() + 1).toString().padStart(2, '0')}${date.getDate().toString().padStart(2, '0')}`,
			info: ''
		});
	}
	// Loop infoDates, in turn, each item is converted to an object, date is the date, and info is respectively departure, check-in, shopping, photography, check-out, and return
	infoDates.forEach((date, index) => {
		infoDates[index] = {
			text: date.text,
			info: ['Set off', 'Stay', 'Shopping', 'Photo', 'Leave', 'Return'][index]
		};
	});

	// For a total of 14 days before the current date and 7 days after 7 days, the formation of the array DisableDates. The DATE format is yyyymmdd, and the month and day are added.
	const disabledDates: string[] = [];
	const before7 = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
	for (let i = 0; i < 14; i++) {
		const date = new Date(before7.getTime() + i * 24 * 60 * 60 * 1000);
		disabledDates.push(
			`${date.getFullYear()}${(date.getMonth() + 1).toString().padStart(2, '0')}${date.getDate().toString().padStart(2, '0')}`
		);
	}
	// Pass the number N and return to the month of the N -month month in the current month. The format is yyyymm, and the month is added 2 digits.
	const getInitMonth = (n: number) => {
		const now = new Date();
		const year = now.getFullYear();
		const month = now.getMonth() + 1;
		const newMonth = month - n;
		if (newMonth > 0) {
			return `${year}${newMonth.toString().padStart(2, '0')}`;
		} else {
			return `${year - 1}${(12 + newMonth).toString().padStart(2, '0')}`;
		}
	};
	const initMonth = getInitMonth(3);

	const quickSelectsDay = [-5, -2, 3, 7];

	let selectedDates: string[] = $state([]);
	const getSelectedDatesFunc = (dates: string[]) => {
		selectedDates = dates;
	};

	let selectedFormatDates: string[] = $state([]);
	const getSelectedFormatDatesFunc = (dates: string[]) => {
		selectedFormatDates = dates;
	};
</script>

<div class="py-4">
	<Cell title="Basic usage" onclick={() => (visible1 = true)} />
	<Calendar bind:visible={visible1} />

	<Cell title="Choice" onclick={() => (visible7 = true)} />
	<Calendar bind:visible={visible7} mode="multiple" />

	<Cell title="Range selection" onclick={() => (visible8 = true)} />
	<Calendar bind:visible={visible8} mode="range" />

	<Cell title="Starting from Sunday" onclick={() => (visible2 = true)} />
	<Calendar bind:visible={visible2} startSunday />

	<Cell title="Weekend text marking red" onclick={() => (visible3 = true)} />
	<Calendar bind:visible={visible3} weekendRed />

	<Cell title="No card style but add watermark" onclick={() => (visible4 = true)} />
	<Calendar bind:visible={visible4} monthCard={false} monthMark />

	<Cell title="Higher" onclick={() => (visible5 = true)} />
	<Calendar bind:visible={visible5} height={60} />

	<Cell title="Customize the date of display information" onclick={() => (visible6 = true)} />
	<Calendar bind:visible={visible6} {infoDates} />

	<Cell title="Do not round the corner" onclick={() => (visible9 = true)} />
	<Calendar bind:visible={visible9} mode="range" radius="none" />

	<Cell title="Increase the corner" onclick={() => (visible10 = true)} />
	<Calendar bind:visible={visible10} mode="range" radius="2xl" />

	<Cell title="Turn off the animation when rolling" onclick={() => (visible18 = true)} />
	<Calendar bind:visible={visible18} useAnimation={false} />

	<Cell title="Configure confirmation button style" onclick={() => (visible11 = true)} />
	<Calendar bind:visible={visible11} button={{ radius: 'full' }} />

	<Cell title="Top rounded corner" onclick={() => (visible19 = true)} />
	<Calendar bind:visible={visible19} popup={{ radius: 'xl' }} />

	<Cell title="Definition start and end month" onclick={() => (visible12 = true)} />
	<Calendar bind:visible={visible12} startMonth="202101" endMonth="202106" />

	<Cell title="Customize the unsalented date" onclick={() => (visible13 = true)} />
	<Calendar bind:visible={visible13} {disabledDates} mode="range" />

	<Cell title="No showed days have been displayed" onclick={() => (visible14 = true)} />
	<Calendar bind:visible={visible14} mode="range" showSelectedDay={false} />

	<Cell title="Customized initial display month" subTitle="Third month before the current month" onclick={() => (visible15 = true)} />
	<Calendar bind:visible={visible15} {initMonth} />

	<Cell title="Show some fast selection items" onclick={() => (visible16 = true)} />
	<Calendar bind:visible={visible16} mode="range" quickSelects={['week', 'month', 'quarter', -3, -7, -30, 3, 7, 30]} />

	<Cell title="Quickly choose to include that day" onclick={() => (visible23 = true)} />
	<Calendar bind:visible={visible23} mode="range" quickSelects={quickSelectsDay} includeToday />

	<Cell title="Select this week from Sunday" onclick={() => (visible17 = true)} />
	<Calendar bind:visible={visible17} mode="range" startSunday quickSelects={['week']} />

	<div class="px-4">
		{#if selectedDates.length}
			The following is the following total {selectedDates.length} day:
		{:else}
			<div>Please select the date</div>
		{/if}
	</div>
	<div class="grid grid-cols-4 gap-2 p-2 text-primary dark:text-dark">
		{#each selectedDates as item}
			<div class="text-center">{item}</div>
		{/each}
	</div>
	<Cell title="Get the selection date of returning" onclick={() => (visible20 = true)} />
	<Calendar bind:visible={visible20} mode="range" onconfirm={getSelectedDatesFunc} />

	<div class="px-4">
		{#if selectedFormatDates.length}
			The following is the following total {selectedFormatDates.length} day:
		{:else}
			<div>Please select the date</div>
		{/if}
	</div>
	<div class="grid grid-cols-3 gap-2 p-2 text-sm text-primary dark:text-dark">
		{#each selectedFormatDates as item}
			<div class="text-center">{item}</div>
		{/each}
	</div>
	<Cell title="Customized date format" onclick={() => (visible21 = true)} />
	<Calendar bind:visible={visible21} mode="range" outFormat="M/D/Y" onconfirm={getSelectedFormatDatesFunc} />

	<Cell title="Turn off today's highlight display" onclick={() => (visible22 = true)} />
	<Calendar bind:visible={visible22} highlightToday={false} />

	<Cell title="Do not clear the selected date when closing" onclick={() => (visible24 = true)} />
	<Calendar bind:visible={visible24} mode="range" clear={false} />
</div>



================================================
FILE: packages/stdf/src/routes/calendar/zh_CN/+page.svelte
================================================
<!-- Calendar Demo -->
<script lang="ts">
	import { Cell, Calendar } from '$lib/index.js';
	import type { InfoDateProps } from '$lib/types/index.js';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);
	let visible15 = $state(false);
	let visible16 = $state(false);
	let visible17 = $state(false);
	let visible18 = $state(false);
	let visible19 = $state(false);
	let visible20 = $state(false);
	let visible21 = $state(false);
	let visible22 = $state(false);
	let visible23 = $state(false);
	let visible24 = $state(false);

	// 随机取出当前日期后的 6 天，组成 infoDates 数组，其中 date 格式为 YYYYMMDD，月和日补足 2 位
	const now = new Date();
	const infoDates: InfoDateProps[] = $state([]);
	for (let i = 0; i < 6; i++) {
		const date = new Date(now.getTime() + i * 24 * 60 * 60 * 1000);
		infoDates.push({
			text: `${date.getFullYear()}${(date.getMonth() + 1).toString().padStart(2, '0')}${date.getDate().toString().padStart(2, '0')}`,
			info: ''
		});
	}

	// 循环 infoDates ，按照顺序，将每一项转为对象，date 为日期，info分别为出发、入住、购物、 拍照、离店、回程
	infoDates.forEach((date, index) => {
		infoDates[index] = {
			text: date.text,
			info: ['出发', '入住', '购物', '拍照', '离店', '回程'][index]
		};
	});

	// 获取当前日期的前 7 天和后 7 天共 14 天，组成数组 disabledDates，其中 date 格式为 YYYYMMDD，月和日补足 2 位
	const disabledDates: string[] = [];
	const before7 = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
	for (let i = 0; i < 14; i++) {
		const date = new Date(before7.getTime() + i * 24 * 60 * 60 * 1000);
		disabledDates.push(
			`${date.getFullYear()}${(date.getMonth() + 1).toString().padStart(2, '0')}${date.getDate().toString().padStart(2, '0')}`
		);
	}
	// 传入数字 n，返回当前月份往前推第 n 个月的月份，格式为 YYYYMM，月份补足2位
	const getInitMonth = (n: number) => {
		const now = new Date();
		const year = now.getFullYear();
		const month = now.getMonth() + 1;
		const newMonth = month - n;
		if (newMonth > 0) {
			return `${year}${newMonth.toString().padStart(2, '0')}`;
		} else {
			return `${year - 1}${(12 + newMonth).toString().padStart(2, '0')}`;
		}
	};
	const initMonth = getInitMonth(3);

	const quickSelectsDay = [-5, -2, 3, 7];

	let selectedDates: string[] = $state([]);
	const getSelectedDatesFunc = (dates: string[]) => {
		selectedDates = dates;
	};

	let selectedFormatDates: string[] = $state([]);
	const getSelectedFormatDatesFunc = (dates: string[]) => {
		selectedFormatDates = dates;
	};
</script>

<div class="py-4">
	<Cell title="基础用法" onclick={() => (visible1 = true)} />
	<Calendar bind:visible={visible1} />

	<Cell title="多选" onclick={() => (visible7 = true)} />
	<Calendar bind:visible={visible7} mode="multiple" />

	<Cell title="范围选择" onclick={() => (visible8 = true)} />
	<Calendar bind:visible={visible8} mode="range" />

	<Cell title="从周日开始" onclick={() => (visible2 = true)} />
	<Calendar bind:visible={visible2} startSunday />

	<Cell title="周末文字标红" onclick={() => (visible3 = true)} />
	<Calendar bind:visible={visible3} weekendRed />

	<Cell title="不使用卡片样式且加水印" onclick={() => (visible4 = true)} />
	<Calendar bind:visible={visible4} monthCard={false} monthMark />

	<Cell title="高一点" onclick={() => (visible5 = true)} />
	<Calendar bind:visible={visible5} height={60} />

	<Cell title="自定义显示信息的日期" onclick={() => (visible6 = true)} />
	<Calendar bind:visible={visible6} {infoDates} />

	<Cell title="不要圆角" onclick={() => (visible9 = true)} />
	<Calendar bind:visible={visible9} mode="range" radius="none" />

	<Cell title="加大圆角" onclick={() => (visible10 = true)} />
	<Calendar bind:visible={visible10} mode="range" radius="2xl" />

	<Cell title="滚动时关闭动画" onclick={() => (visible18 = true)} />
	<Calendar bind:visible={visible18} useAnimation={false} />

	<Cell title="配置确认按钮样式" onclick={() => (visible11 = true)} />
	<Calendar bind:visible={visible11} button={{ radius: 'full' }} />

	<Cell title="顶部来点圆角" onclick={() => (visible19 = true)} />
	<Calendar bind:visible={visible19} popup={{ radius: 'xl' }} />

	<Cell title="定义开始与结束月" onclick={() => (visible12 = true)} />
	<Calendar bind:visible={visible12} startMonth="202101" endMonth="202106" />

	<Cell title="自定义不可选日期" onclick={() => (visible13 = true)} />
	<Calendar bind:visible={visible13} {disabledDates} mode="range" />

	<Cell title="多选或范围选择时不显示已选天数" onclick={() => (visible14 = true)} />
	<Calendar bind:visible={visible14} mode="range" showSelectedDay={false} />

	<Cell title="自定义初始显示月份" subTitle="开始月份为当前月份前第三个月" onclick={() => (visible15 = true)} />
	<Calendar bind:visible={visible15} {initMonth} />

	<Cell title="展示一些快速选择项" onclick={() => (visible16 = true)} />
	<Calendar bind:visible={visible16} mode="range" quickSelects={['week', 'month', 'quarter', -3, -7, -30, 3, 7, 30]} />

	<Cell title="快速选择天数时包含当天" onclick={() => (visible23 = true)} />
	<Calendar bind:visible={visible23} mode="range" quickSelects={quickSelectsDay} includeToday />

	<Cell title="从周日开始快速选择本周" onclick={() => (visible17 = true)} />
	<Calendar bind:visible={visible17} mode="range" startSunday quickSelects={['week']} />

	<div class="px-4">
		{#if selectedDates.length}
			当前选定了以下共 {selectedDates.length} 天：
		{:else}
			<div>请选定日期</div>
		{/if}
	</div>
	<div class="grid grid-cols-4 gap-2 p-2 text-primary dark:text-dark">
		{#each selectedDates as item}
			<div class="text-center">{item}</div>
		{/each}
	</div>
	<Cell title="获取返回的选定日期" onclick={() => (visible20 = true)} />
	<Calendar bind:visible={visible20} mode="range" onconfirm={getSelectedDatesFunc} />

	<div class="px-4">
		{#if selectedFormatDates.length}
			当前选定了以下共 {selectedFormatDates.length} 天：
		{:else}
			<div>请选定日期</div>
		{/if}
	</div>
	<div class="grid grid-cols-3 gap-2 p-2 text-sm text-primary dark:text-dark">
		{#each selectedFormatDates as item}
			<div class="text-center">{item}</div>
		{/each}
	</div>
	<Cell title="自定义返回的日期格式" onclick={() => (visible21 = true)} />
	<Calendar bind:visible={visible21} mode="range" outFormat="YYYY年MM月DD日" onconfirm={getSelectedFormatDatesFunc} />

	<Cell title="今日日期关闭高亮显示" onclick={() => (visible22 = true)} />
	<Calendar bind:visible={visible22} highlightToday={false} />

	<Cell title="关闭时不清空已选日期" onclick={() => (visible24 = true)} />
	<Calendar bind:visible={visible24} mode="range" clear={false} />
</div>



================================================
FILE: packages/stdf/src/routes/cell/en_US/+page.svelte
================================================
<!-- Cell Demo -->
<script lang="ts">
	import { Cell, CellGroup, Toast } from '$lib/index.js';

	let visible = $state(false);
</script>

<div class="flex flex-col space-y-8 py-8">
	<div>
		<Cell title="Basic Usage" />
		<Cell title="With Detail" detail="Zeroing" />
		<Cell title="Detail with Snippet">
			{#snippet detailChild()}
				<span class="text-primary dark:text-dark text-xs">I'm Snippet</span>
			{/snippet}
		</Cell>
		<Cell title="No Arrow" right={null} />
		<Cell title="Display Only" right={null} clickAll={false} />
		<Cell title="Click Event" detail="Click Me" onclick={() => (visible = true)} />
		<Toast bind:visible message="You clicked me!" />
		<Cell title="Detail without Arrow" detail="Zeroing" right={null} />
		<Cell title="Switch (Click Row)" right={{ type: 'switch' }} />
		<Cell title="Switch with Detail" detail="Description" right={{ type: 'switch' }} />
		<Cell title="Switch with Text" right={{ type: 'switch', switch: { inside: ['😭', '😄'] } }} />
		<Cell title="Rounded Switch" right={{ type: 'switch', switch: { radius: 'full' } }} />
		<Cell title="Switch Only" clickAll={false} right={{ type: 'switch' }} />
		<Cell title="Left Icon" left={{ name: 'ri-bank-line', size: 20, theme: true, top: -2 }} />
		<Cell title="Right Icon" right={{ type: 'icon', icon: { name: 'ri-battery-charge-line', size: 20, theme: true } }} />
		<Cell title="Left Image">
			{#snippet leftChild()}
				<div class="mr-1 shrink-0">
					<img class="h-6 w-6" src="/assets/images/icon_颁奖.png" alt="" />
				</div>
			{/snippet}
		</Cell>
		<Cell title="Both Side Images">
			{#snippet leftChild()}
				<div class="mr-1 shrink-0">
					<img class="h-6 w-6" src="/assets/images/icon_评价.png" alt="" />
				</div>
			{/snippet}
			{#snippet rightChild()}
				<div class="mr-1 shrink-0">
					<img class="h-6 w-6" src="/assets/images/icon_美食.png" alt="" />
				</div>
			{/snippet}
		</Cell>
		<Cell title="Larger Image">
			{#snippet leftChild()}
				<div class="mr-1 shrink-0">
					<img class="h-10 w-10" src="/assets/images/icon_会员.png" alt="" />
				</div>
			{/snippet}
		</Cell>
		<Cell title="With Subtitle" subTitle="I'm subtitle" />
		<Cell title="Subtitle and Detail" subTitle="I'm subtitle" detail="Zeroing" />
		<Cell title="Secondary Info" detail="Zeroing" info="Reboot" />
		<Cell title="Both Secondary" subTitle="I'm subtitle" detail="Zeroing" info="Reboot" />
		<Cell title="Both Secondary" subTitle="I'm subtitle" detail="With Arrow" info="Reboot" />
		<Cell
			title="Both Secondary"
			subTitle="With Left Icon"
			detail="With Arrow"
			info="Reboot"
			left={{ name: 'ri-shopping-basket-line', theme: true }}
		/>
		<Cell title="All Features" subTitle="Left Custom Image" detail="Right Arrow" info="No Border">
			{#snippet leftChild()}
				<div class="mr-1 shrink-0">
					<img class="h-10 w-10" src="/assets/images/icon_火车票.png" alt="" />
				</div>
			{/snippet}
		</Cell>
		<Cell
			title="Long title that wraps automatically when it exceeds the width of the container."
			subTitle="Long subtitle that also wraps automatically when it exceeds the width."
		/>
		<Cell
			title="Large image with long title that wraps automatically. Try other combinations yourself."
			subTitle="Short subtitle"
			line={false}
		>
			{#snippet leftChild()}
				<div class="mr-1 shrink-0">
					<img class="h-20 w-20" src="/assets/images/icon_外卖.png" alt="" />
				</div>
			{/snippet}
		</Cell>
	</div>

	<CellGroup>
		<Cell title="Group Usage" mx="0" my="0" shadow="none" line radius="none" />
		<Cell title="Group Usage" mx="0" my="0" shadow="none" radius="none" />
	</CellGroup>
	<CellGroup mx="0" radius="none">
		<Cell title="Group Usage" detail="No Margin" mx="0" my="0" shadow="none" line radius="none" />
		<Cell title="Group Usage" detail="No Radius" mx="0" my="0" shadow="none" radius="none" />
	</CellGroup>
	<CellGroup shadow="xl" radius="2xl">
		<Cell title="Group Usage" detail="Large Shadow" mx="0" my="0" shadow="none" line radius="none" />
		<Cell title="Group Usage" detail="Large Radius" mx="0" my="0" shadow="none" radius="none" />
	</CellGroup>

	<div>
		<Cell title="No Margin" mx="0" radius="none" />
		<Cell title="No Radius" radius="none" />
		<Cell title="Base Radius" radius="sm" />
		<Cell title="Medium Radius" radius="md" />
		<Cell title="Large Radius" radius="lg" />
		<Cell title="XL Radius" radius="xl" />
		<Cell title="2XL Radius" radius="2xl" />
		<Cell title="Full Radius" radius="full" />
		<Cell title="Large Shadow" shadow="lg" />
	</div>
	<div>
		<Cell title="Custom Text Color" injClass="text-primary dark:text-dark" />
		<Cell title="Custom Background" injClass="!bg-extend0/20 active:!bg-extend0/10" line={false} />
	</div>
	<div>
		<Cell love title="Care Version" />
		<Cell love title="Care Version" detail="Care" />
		<Cell love title="Care Version" left={{ name: 'ri-hand-heart-line', theme: true }} />
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/cell/zh_CN/+page.svelte
================================================
<!-- Cell Demo -->
<script lang="ts">
	import { Cell, CellGroup, Toast } from '$lib/index.js';

	let visible = $state(false);
</script>

<div class="flex flex-col space-y-8 py-8">
	<div>
		<Cell title="基础用法" />
		<Cell title="右侧有详情" detail="归零者" />
		<Cell title="详情使用 Snippet">
			{#snippet detailChild()}
				<span class="text-primary dark:text-dark text-xs">我是 Snippet</span>
			{/snippet}
		</Cell>
		<Cell title="右侧无箭头" right={null} />
		<Cell title="纯展示，无点击效果" right={null} clickAll={false} />
		<Cell title="点击事件" detail="请点击我" onclick={() => (visible = true)} />
		<Toast bind:visible message="你戳到我了！" />
		<Cell title="右侧有详情无箭头" detail="归零者" right={null} />
		<Cell title="右侧开关（点击整行皆可触发开关）" right={{ type: 'switch' }} />
		<Cell title="开关带详情" detail="解释一下" right={{ type: 'switch' }} />
		<Cell title="开关带文字" right={{ type: 'switch', switch: { inside: ['😭', '😄'] } }} />
		<Cell title="开关全圆角" right={{ type: 'switch', switch: { radius: 'full' } }} />
		<Cell title="仅点击开关触发" clickAll={false} right={{ type: 'switch' }} />
		<Cell title="左侧使用 Icon 组件" left={{ name: 'ri-bank-line', size: 20, theme: true, top: -2 }} />
		<Cell title="右侧使用 Icon 组件" right={{ type: 'icon', icon: { name: 'ri-battery-charge-line', size: 20, theme: true } }} />
		<Cell title="左侧自定义图片">
			{#snippet leftChild()}
				<div class="mr-1 shrink-0">
					<img class="h-6 w-6" src="/assets/images/icon_颁奖.png" alt="" />
				</div>
			{/snippet}
		</Cell>
		<Cell title="左右都自定义图片">
			{#snippet leftChild()}
				<div class="mr-1 shrink-0">
					<img class="h-6 w-6" src="/assets/images/icon_评价.png" alt="" />
				</div>
			{/snippet}
			{#snippet rightChild()}
				<div class="mr-1 shrink-0">
					<img class="h-6 w-6" src="/assets/images/icon_美食.png" alt="" />
				</div>
			{/snippet}
		</Cell>
		<Cell title="来张大点的图">
			{#snippet leftChild()}
				<div class="mr-1 shrink-0">
					<img class="h-10 w-10" src="/assets/images/icon_会员.png" alt="" />
				</div>
			{/snippet}
		</Cell>
		<Cell title="左侧有次级标题" subTitle="我是次，但我不次" />
		<Cell title="有次级标题和右侧详情" subTitle="我是次，但我不次" detail="归零者" />
		<Cell title="右侧有次级信息" detail="归零者" info="重启者" />
		<Cell title="左右侧都有次级内容" subTitle="我是次，但我不次" detail="归零者" info="重启者" />
		<Cell title="左右侧都有次级内容" subTitle="我是次，但我不次" detail="再来个箭头" info="重启者" />
		<Cell
			title="右右侧都有次级内容"
			subTitle="左侧再来个 Icon"
			detail="再来个箭头"
			info="重启者"
			left={{ name: 'ri-shopping-basket-line', theme: true }}
		/>
		<Cell title="图片什么也来吧" subTitle="左侧自定义图片" detail="右侧箭头" info="底部无分割线">
			{#snippet leftChild()}
				<div class="mr-1 shrink-0">
					<img class="h-10 w-10" src="/assets/images/icon_火车票.png" alt="" />
				</div>
			{/snippet}
		</Cell>
		<Cell
			title="标题超长长长长长长长长长长长长长长长长长长长，自动换行。"
			subTitle="我这个次级标题也很长长长长长长长长长长长长长长长长长长长长长长长长长长。"
		/>
		<Cell title="左侧自定义大图片，标题超长，自动换行。其余的搭配自己去尝试吧。" subTitle="我这个次级标题也很...哦不长了。" line={false}>
			{#snippet leftChild()}
				<div class="mr-1 shrink-0">
					<img class="h-20 w-20" src="/assets/images/icon_外卖.png" alt="" />
				</div>
			{/snippet}
		</Cell>
	</div>

	<CellGroup>
		<Cell title="组合使用" mx="0" my="0" shadow="none" line radius="none" />
		<Cell title="组合使用" mx="0" my="0" shadow="none" radius="none" />
	</CellGroup>
	<CellGroup mx="0" radius="none">
		<Cell title="组合使用" detail="无横向间距" mx="0" my="0" shadow="none" line radius="none" />
		<Cell title="组合使用" detail="无圆角" mx="0" my="0" shadow="none" radius="none" />
	</CellGroup>
	<CellGroup shadow="xl" radius="2xl">
		<Cell title="组合使用" detail="加大投影" mx="0" my="0" shadow="none" line radius="none" />
		<Cell title="组合使用" detail="加大圆角" mx="0" my="0" shadow="none" radius="none" />
	</CellGroup>

	<div>
		<Cell title="左右无间距" mx="0" radius="none" />
		<Cell title="无圆角" radius="none" />
		<Cell title="基础圆角" radius="sm" />
		<Cell title="中等圆角" radius="md" />
		<Cell title="大圆角" radius="lg" />
		<Cell title="加大圆角" radius="xl" />
		<Cell title="更大圆角" radius="2xl" />
		<Cell title="全圆角" radius="full" />
		<Cell title="加大投影" shadow="lg" />
	</div>
	<div>
		<Cell title="自定义文字颜色" injClass="text-primary dark:text-dark" />
		<Cell title="自定义背景颜色" injClass="!bg-extend0/20 active:!bg-extend0/10" line={false} />
	</div>
	<div>
		<Cell love title="关爱版" />
		<Cell love title="关爱版" detail="关爱版" />
		<Cell love title="关爱版" left={{ name: 'ri-hand-heart-line', theme: true }} />
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/checkbox/en_US/+page.svelte
================================================
<!-- Checkbox Demo -->
<script lang="ts">
	import { quintOut } from 'svelte/easing';
	import { crossfade } from 'svelte/transition';
	import { flip } from 'svelte/animate';
	import { Checkbox, CheckboxItem, Divider, Button, Icon } from '$lib/index.js';
	import type { CheckboxItemProps } from '$lib/types/index.js';

	const dota: CheckboxItemProps[] = [
		{ label: 'Jugg', name: 'Juggernaut' },
		{ label: 'SB', name: 'Spirit Breaker' },
		{ label: 'KOTL', name: 'Keeper of the Light' },
		{ label: 'Mag', name: 'Magnus' }
	];
	let checkeds: string[] = $state([]);
	const clickItemFn = (name: string) => {
		checkeds = checkeds.includes(name) ? checkeds.filter((v) => v !== name) : [name, ...checkeds];
	};
	let checkedsCustom: string[] = $state([]);
	const clickCustomFn = (name: string) => {
		checkedsCustom = checkedsCustom.includes(name) ? checkedsCustom.filter((v) => v !== name) : [name, ...checkedsCustom];
	};

	const dotaInlines: CheckboxItemProps[] = [
		{ label: 'Lina', name: 'Lina' },
		{ label: 'SB', name: 'Spirit Breaker' },
		{ label: 'Morph', name: 'Morphling' },
		{ label: 'Sniper', name: 'Sniper' },
		{ label: 'Sven', name: 'Sven' },
		{ label: 'Invoker', name: 'Invoker' },
		{ label: 'Tide', name: 'Tidehunter' },
		{ label: 'Bat', name: 'Batrider' },
		{ label: 'Mag', name: 'Magnus' }
	];
	let checkInlines: string[] = $state(['Spirit Breaker', 'Morphling']);
	const dotaInlineFun = (name: string) => {
		checkInlines = checkInlines.includes(name) ? checkInlines.filter((v) => v !== name) : [name, ...checkInlines];
	};

	const dotaImgs: (CheckboxItemProps & { imgName: string })[] = [
		{ label: 'Lina', name: 'Lina', imgName: '火女' },
		{ label: 'SB', name: 'Spirit Breaker', imgName: '小牛' },
		{ label: 'Morph', name: 'Morphling', imgName: '水人' },
		{ label: 'Sniper', name: 'Sniper', imgName: '火枪' },
		{ label: 'Sven', name: 'Sven', imgName: '斯温' }
	];
	let imgCheckeds: string[] = $state(['Lina']);
	const dotaImgsFun = (name: string) => {
		imgCheckeds = imgCheckeds.includes(name) ? imgCheckeds.filter((v) => v !== name) : [name, ...imgCheckeds];
	};

	const dotaLong: CheckboxItemProps[] = [
		{ name: 'Jugg', label: 'Juggernaut is a melee agility hero who can quickly engage in combat.' },
		{ name: 'SB', label: 'Barathrum, Spirit Breaker is a powerful ganking strength melee hero.' },
		{ name: 'KOTL', label: 'Ezalor, Keeper of the Light, is a famous support intelligence hero.' },
		{ name: 'Mag', label: 'Magnus? Why not ban Magnus? Why not ban Magnus?' }
	];

	const dotaVoices: (CheckboxItemProps & { voices: string[] })[] = [
		{ name: 'Invoker', label: 'Invoker', voices: ['"From the first point was begat a line."'] },
		{ name: 'Storm', label: 'Storm', voices: ['"Hey, wake up! Get some coffee, our tower is under attack."'] },
		{
			name: 'Batrider',
			label: 'Batrider',
			voices: [
				'"Oh Lina, wanna be my queen?"',
				'"Oh Windrunner, no need to run from me."',
				'"Crystal Maiden, you\'re like a tall glass of water."'
			]
		},
		{ name: 'Tidehunter', label: 'Tidehunter', voices: ['"I could eat a sea cucumber."'] }
	];
	let voiceCheckeds: string[] = $state([]);
	const dotaVoicesFun = (name: string) => {
		voiceCheckeds = voiceCheckeds.includes(name) ? voiceCheckeds.filter((v) => v !== name) : [name, ...voiceCheckeds];
	};

	const dotaAll = [
		{ name: 'Lina', label: 'Lina' },
		{ name: 'SB', label: 'Spirit Breaker' },
		{ name: 'Morph', label: 'Morphling' },
		{ name: 'Sniper', label: 'Sniper' },
		{ name: 'Sven', label: 'Sven' },
		{ name: 'Invoker', label: 'Invoker' },
		{ name: 'Tide', label: 'Tidehunter' },
		{ name: 'Bat', label: 'Batrider' },
		{ name: 'Mag', label: 'Magnus' }
	];
	let checkDotas = $state(['Sniper', 'Sven']);
	let noCheckDotas = $derived(dotaAll.filter((a) => !checkDotas.some((b) => b === a.name)).map((a) => a.name));
	// Select All
	const checkAllFun = () => {
		checkDotas = dotaAll.map((a) => a.name);
	};
	// Select None
	const checkNoneFun = () => {
		checkDotas = [];
	};
	// Reverse Selection
	const checkReverseFun = () => {
		checkDotas = dotaAll.filter((a) => !checkDotas.some((b) => b === a.name)).map((a) => a.name);
	};

	const animates = ['Lina', 'SB', 'Morph', 'Sniper', 'Sven', 'Invoker', 'Tide', 'Bat', 'Mag'];
	let animateNos = $state(['Lina', 'SB', 'Morph', 'Sniper', 'Sven', 'Invoker']);
	let animateYess: string[] = $derived(animates.filter((a) => !animateNos.some((b) => b === a)));
	const checkAnimateNoFun = (name: string) => {
		animateNos = animateNos.filter((a) => a !== name);
	};
	const checkAnimaYesFun = (name: string) => {
		animateNos = [name, ...animateNos];
	};
	const [send, receive] = crossfade({
		duration: (d) => Math.sqrt(d * 150),
		fallback(node) {
			const style = getComputedStyle(node);
			const transform = style.transform === 'none' ? '' : style.transform;
			return {
				duration: 600,
				easing: quintOut,
				css: (t) => `
					transform: ${transform} scale(${t});
					opacity: ${t}
				`
			};
		}
	});

	// Set height to avoid page height changes affecting click experience
	let heights = $state(0);
	let animateHeight = $derived(heights * animates.length + 50);
</script>

<div class="px-4">
	<div class="mb-4 mt-8 text-2xl font-bold">Horizontal Layout</div>
	<div class="mb-4 mt-6 text-lg font-bold">Basic Usage</div>
	<Checkbox layout="h" data={dota} />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Text Position</div>
	<Checkbox layout="h" data={dota} textPosition="l" />
	<Divider />
	<Checkbox layout="h" data={dota} textPosition="b" />
	<Divider />
	<Checkbox layout="h" data={dota} textPosition="t" />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Custom Icons</div>
	<Checkbox layout="h" data={dota} icon={{ name: 'ri-checkbox-blank-circle-line' }} iconChecked={{ name: 'ri-radio-button-fill' }} />
	<Divider />
	<Checkbox layout="h" data={dota} icon={{ name: 'ri-checkbox-circle-line' }} iconChecked={{ name: 'ri-checkbox-circle-fill' }} />
	<Divider />
	<Checkbox layout="h" data={dota} icon={{ name: 'ri-checkbox-multiple-line' }} iconChecked={{ name: 'ri-checkbox-multiple-fill' }} />
	<Divider />
	<Checkbox layout="h" data={dota} icon={{ name: 'ri-check-line' }} iconChecked={{ name: 'ri-check-fill' }} />
	<Divider />
	<Checkbox layout="h" data={dota} icon={{ name: 'ri-check-double-line' }} iconChecked={{ name: 'ri-check-double-line' }} />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Snippet as Button Component</div>
	<Checkbox layout="h" data={dota}>
		{#snippet checkboxChild({ item })}
			<Button
				fill={checkeds.includes(item.name) ? 'base' : 'lineLight'}
				injClass="px-2 !py-1"
				onclick={() => {
					clickItemFn(item.name);
				}}
			>
				{item.label}
			</Button>
		{/snippet}
	</Checkbox>
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Snippet as Custom Element</div>
	<Checkbox layout="h" data={dota}>
		{#snippet checkboxChild({ item })}
			<button
				class="rounded-sm border px-5 py-0.5 text-sm {checkedsCustom.includes(item.name)
					? 'bg-primary/10 text-primary dark:bg-dark/10 dark:text-dark'
					: 'border-gray-200 bg-gray-100 dark:border-gray-500 dark:bg-gray-600'}"
				onclick={() => {
					clickCustomFn(item.name);
				}}
			>
				{item.label}
			</button>
		{/snippet}
	</Checkbox>
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Image Options</div>
	<Checkbox layout="h" data={dotaImgs}>
		{#snippet checkboxChild({ item })}
			<div class="flex flex-col items-center">
				<!-- svelte-ignore a11y_click_events_have_key_events -->
				<!-- svelte-ignore a11y_no_static_element_interactions -->
				<div
					class="mb-1 h-12 w-12 overflow-hidden rounded-sm {imgCheckeds.includes(item.name) ? 'ring-primary dark:ring-dark ring-2' : ''}"
					onclick={() => {
						dotaImgsFun(item.name);
					}}
				>
					<img class="h-full w-full object-cover" src={`/assets/images/dota_${item.imgName}.png`} alt="" />
				</div>
				<div>
					<Icon
						name={imgCheckeds.includes(item.name) ? 'ri-arrow-up-s-fill' : 'ri-arrow-up-s-line'}
						theme={imgCheckeds.includes(item.name)}
						alpha={imgCheckeds.includes(item.name) ? 1 : 0.2}
					/>
				</div>
			</div>
		{/snippet}
	</Checkbox>
	<div class="text-sm">
		{imgCheckeds.length > 0 ? 'Selected' : 'No heroes selected'}
		<span class="text-[red]">{imgCheckeds.join(' + ')}</span>
	</div>
	<Divider />
</div>

<div class="px-4">
	<div class="mb-4 text-2xl font-bold">Inline Layout</div>
	<div class="mb-4 mt-8 text-lg font-bold">Snippet Inline Layout</div>
	<Checkbox layout="inline" data={dotaInlines}>
		{#snippet checkboxChild({ item })}
			<!-- svelte-ignore a11y_click_events_have_key_events -->
			<!-- svelte-ignore a11y_no_static_element_interactions -->
			<div
				class="m-1 rounded-sm border px-2 py-0.5 text-sm {checkInlines.includes(item.name)
					? 'bg-primary/10 text-primary dark:bg-dark/10 dark:text-dark'
					: 'border-gray-200 bg-gray-100 dark:border-gray-500 dark:bg-gray-600'}"
				onclick={() => {
					dotaInlineFun(item.name);
				}}
			>
				{item.label}
			</div>
		{/snippet}
	</Checkbox>
	<div class="mt-2 text-xs">Selected: {checkInlines.join('-')}</div>
</div>
<Divider />

<div class="px-4 pb-8">
	<div class="mb-4 text-2xl font-bold">Vertical Layout</div>
	<div class="mb-4 mt-8 text-lg font-bold">Basic Usage</div>
	<Checkbox data={dota} />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Long Text Options</div>
	<Checkbox data={dotaLong} />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Left Aligned Text</div>
	<Checkbox data={dota} textPosition="l" />

	<div class="mb-4 mt-8 text-lg font-bold">Complex Options && Custom Selection Effect</div>
	<Checkbox data={dotaVoices}>
		{#snippet checkboxChild({ item })}
			<!-- svelte-ignore a11y_click_events_have_key_events -->
			<!-- svelte-ignore a11y_no_static_element_interactions -->
			<div class="flex cursor-pointer items-center" onclick={() => dotaVoicesFun(item.name)}>
				<div>
					<Icon
						name={voiceCheckeds.includes(item.name) ? 'ri-checkbox-fill' : 'ri-checkbox-line'}
						theme={voiceCheckeds.includes(item.name)}
						alpha={voiceCheckeds.includes(item.name) ? 1 : 0.2}
					/>
				</div>
				<div class="ml-2 grow {voiceCheckeds.includes(item.name) ? 'text-primary dark:text-dark' : ''}">
					{item.label}
					{#each item.voices as string[] as voice}
						<div class="text-xs">{voice}</div>
					{/each}
					<div class="mt-1 h-px bg-black/10 dark:bg-white/10"></div>
				</div>
			</div>
		{/snippet}
	</Checkbox>

	<div class="mb-4 mt-8 text-lg font-bold">Batch Operations</div>
	<Checkbox data={dotaAll} bind:checkeds={checkDotas} />
	<div class="mt-2 text-xs">Selected: {checkDotas.map((a) => dotaAll.find((b) => b.name === a)?.label).join('-')}</div>
	<div class="mt-2 text-xs">Unselected: {noCheckDotas.map((a) => dotaAll.find((b) => b.name === a)?.label).join('-')}</div>
	<div class="mt-2 flex">
		<div class="flex-1">
			<Button fill="lineTheme" heightIn="1" onclick={checkAllFun}>All</Button>
		</div>
		<div class="flex-1">
			<Button fill="lineTheme" heightIn="1" onclick={checkNoneFun}>None</Button>
		</div>
		<div class="flex-1">
			<Button fill="lineTheme" heightIn="1" onclick={checkReverseFun}>Reverse</Button>
		</div>
	</div>
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">With Animation</div>
	<div class="flex justify-center" style="height: {animateHeight}px;">
		<div class="flex-1">
			<div class="pb-2">Unselected</div>
			{#each animateNos as item (item)}
				<div in:receive={{ key: item }} out:send={{ key: item }} animate:flip={{ duration: 600 }} bind:clientHeight={heights}>
					<CheckboxItem name={item} checked={!animateNos.includes(item)} onclick={checkAnimateNoFun}>{item}</CheckboxItem>
				</div>
			{/each}
		</div>
		<div class="flex-1">
			<div class="pb-2">Selected</div>
			{#each animateYess as item (item)}
				<div in:receive={{ key: item }} out:send={{ key: item }} animate:flip={{ duration: 600 }}>
					<CheckboxItem name={item} checked={animateYess.includes(item)} onclick={checkAnimaYesFun}>{item}</CheckboxItem>
				</div>
			{/each}
		</div>
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/checkbox/zh_CN/+page.svelte
================================================
<!-- Checkbox Demo -->
<script lang="ts">
	import { quintOut } from 'svelte/easing';
	import { crossfade } from 'svelte/transition';
	import { flip } from 'svelte/animate';
	import { Checkbox, CheckboxItem, Divider, Button, Icon } from '$lib/index.js';
	import type { CheckboxItemProps } from '$lib/types/index.js';

	const dota: CheckboxItemProps[] = [
		{ label: '主宰', name: '奶棒人' },
		{ label: '白牛', name: '令狐冲' },
		{ label: '光法', name: '光之守卫' },
		{ label: '猛犸', name: '马格纳斯' }
	];
	let checkeds: string[] = $state([]);
	const clickItemFn = (name: string) => {
		checkeds = checkeds.includes(name) ? checkeds.filter((v) => v !== name) : [name, ...checkeds];
	};
	let checkedsCustom: string[] = $state([]);
	const clickCustomFn = (name: string) => {
		checkedsCustom = checkedsCustom.includes(name) ? checkedsCustom.filter((v) => v !== name) : [name, ...checkedsCustom];
	};

	const dotaInlines: CheckboxItemProps[] = [
		{ label: '火女', name: '火女' },
		{ label: '小牛', name: '小牛' },
		{ label: '水人', name: '水人' },
		{ label: '火枪', name: '火枪' },
		{ label: '斯温', name: '斯温' },
		{ label: '祈求者', name: '祈求者' },
		{ label: '潮汐', name: '潮汐' },
		{ label: '蝙蝠', name: '蝙蝠' },
		{ label: '猛犸', name: '猛犸' }
	];
	let checkInlines: string[] = $state(['小牛', '水人']);
	const dotaInlineFun = (name: string) => {
		checkInlines = checkInlines.includes(name) ? checkInlines.filter((v) => v !== name) : [name, ...checkInlines];
	};

	const dotaImgs: CheckboxItemProps[] = [
		{ label: '火女', name: '火女' },
		{ label: '小牛', name: '小牛' },
		{ label: '水人', name: '水人' },
		{ label: '火枪', name: '火枪' },
		{ label: '斯温', name: '斯温' }
	];
	let imgCheckeds: string[] = $state(['火女']);
	const dotaImgsFun = (name: string) => {
		imgCheckeds = imgCheckeds.includes(name) ? imgCheckeds.filter((v) => v !== name) : [name, ...imgCheckeds];
	};

	const dotaLong: CheckboxItemProps[] = [
		{ name: '主宰', label: '主宰是一个近战敏捷英雄，他能够迅速切入战斗。' },
		{ name: '白牛', label: '巴拉森，裂魂人是一个强大的 Gank 型的力量型近战英雄。' },
		{ name: '光法', label: '伊扎洛，光之守卫，他是一个著名的辅助性智力英雄。' },
		{ name: '猛犸', label: '猛犸？为什么不 BAN 猛犸？为什么不 BAN 猛犸？' }
	];

	const dotaVoices: (CheckboxItemProps & { voices: string[] })[] = [
		{ name: '祈求者', label: '祈求者', voices: ['“来自于伟大的奥秘。”'] },
		{ name: '风暴之灵', label: '风暴之灵', voices: ['“喂~快醒醒，快喝点咖啡，我方上塔正遭受攻击。”'] },
		{
			name: '蝙蝠骑士',
			label: '蝙蝠骑士',
			voices: ['“哦，莉娜，当我的压寨夫人怎么样？”', '“哦，风行者，见着我你不用跑。”', '“水晶室女，你就像一个装满冰水的高脚杯。”']
		},
		{ name: '潮汐猎人', label: '潮汐猎人', voices: ['“我还能吃下一根海藻。”'] }
	];
	let voiceCheckeds: string[] = $state([]);
	const dotaVoicesFun = (name: string) => {
		voiceCheckeds = voiceCheckeds.includes(name) ? voiceCheckeds.filter((v) => v !== name) : [name, ...voiceCheckeds];
	};

	const dotaAll: CheckboxItemProps[] = [
		{ name: '火女', label: '火女' },
		{ name: '小牛', label: '小牛' },
		{ name: '水人', label: '水人' },
		{ name: '火枪', label: '火枪' },
		{ name: '斯温', label: '斯温' },
		{ name: '祈求者', label: '祈求者' },
		{ name: '潮汐', label: '潮汐' },
		{ name: '蝙蝠', label: '蝙蝠' },
		{ name: '猛犸', label: '猛犸' }
	];
	let checkDotas = $state(['火枪', '斯温']);
	let noCheckDotas = $derived(dotaAll.filter((a) => !checkDotas.some((b) => b === a.name)).map((a) => a.name));
	// 全选
	const checkAllFun = () => {
		checkDotas = dotaAll.map((a) => a.name);
	};
	// 全不选
	const checkNoneFun = () => {
		checkDotas = [];
	};
	// 反选
	const checkReverseFun = () => {
		checkDotas = dotaAll.filter((a) => !checkDotas.some((b) => b === a.name)).map((a) => a.name);
	};

	const animates = ['火女', '小牛', '水人', '火枪', '斯温', '祈求者', '潮汐', '蝙蝠', '猛犸'];
	let animateNos = $state(['火女', '小牛', '水人', '火枪', '斯温', '祈求者']);
	let animateYess = $derived(animates.filter((a) => !animateNos.some((b) => b === a)));
	const checkAnimateNoFun = (name: string) => {
		animateNos = animateNos.filter((a) => a !== name);
	};
	const checkAnimaYesFun = (name: string) => {
		animateNos = [name, ...animateNos];
	};
	const [send, receive] = crossfade({
		duration: (d) => Math.sqrt(d * 150),
		fallback(node) {
			const style = getComputedStyle(node);
			const transform = style.transform === 'none' ? '' : style.transform;
			return {
				duration: 600,
				easing: quintOut,
				css: (t) => `
					transform: ${transform} scale(${t});
					opacity: ${t}
				`
			};
		}
	});

	// 设定高度，避免页面高度变化影响点击体验。
	let heights = $state(0);
	let animateHeight = $derived(heights * animates.length + 50);
</script>

<div class="px-4">
	<div class="mb-4 mt-8 text-2xl font-bold">横向排列</div>
	<div class="mb-4 mt-6 text-lg font-bold">简单用法</div>
	<Checkbox layout="h" data={dota} />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">文字在不同位置</div>
	<Checkbox layout="h" data={dota} textPosition="l" />
	<Divider />
	<Checkbox layout="h" data={dota} textPosition="b" />
	<Divider />
	<Checkbox layout="h" data={dota} textPosition="t" />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">自定义图标</div>
	<Checkbox layout="h" data={dota} icon={{ name: 'ri-checkbox-blank-circle-line' }} iconChecked={{ name: 'ri-radio-button-fill' }} />
	<Divider />
	<Checkbox layout="h" data={dota} icon={{ name: 'ri-checkbox-circle-line' }} iconChecked={{ name: 'ri-checkbox-circle-fill' }} />
	<Divider />
	<Checkbox layout="h" data={dota} icon={{ name: 'ri-checkbox-multiple-line' }} iconChecked={{ name: 'ri-checkbox-multiple-fill' }} />
	<Divider />
	<Checkbox layout="h" data={dota} icon={{ name: 'ri-check-line' }} iconChecked={{ name: 'ri-check-fill' }} />
	<Divider />
	<Checkbox layout="h" data={dota} icon={{ name: 'ri-check-double-line' }} iconChecked={{ name: 'ri-check-double-line' }} />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Snippet 为 Button 组件</div>
	<Checkbox layout="h" data={dota}>
		{#snippet checkboxChild({ item })}
			<Button
				fill={checkeds.includes(item.name) ? 'base' : 'lineLight'}
				injClass="px-2 !py-1"
				onclick={() => {
					clickItemFn(item.name);
				}}
			>
				{item.label}
			</Button>
		{/snippet}
	</Checkbox>
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Snippet 为自定义元素</div>
	<Checkbox layout="h" data={dota}>
		{#snippet checkboxChild({ item })}
			<button
				class="rounded-sm border px-5 py-0.5 text-sm {checkedsCustom.includes(item.name)
					? 'bg-primary/10 text-primary dark:bg-dark/10 dark:text-dark'
					: 'border-gray-200 bg-gray-100 dark:border-gray-500 dark:bg-gray-600'}"
				onclick={() => {
					clickCustomFn(item.name);
				}}
			>
				{item.label}
			</button>
		{/snippet}
	</Checkbox>
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">图片选项</div>
	<Checkbox layout="h" data={dotaImgs}>
		{#snippet checkboxChild({ item })}
			<div class="flex flex-col items-center">
				<!-- svelte-ignore a11y_click_events_have_key_events -->
				<!-- svelte-ignore a11y_no_static_element_interactions -->
				<div
					class="mb-1 h-12 w-12 overflow-hidden rounded-sm {imgCheckeds.includes(item.name) ? 'ring-primary dark:ring-dark ring-2' : ''}"
					onclick={() => {
						dotaImgsFun(item.name);
					}}
				>
					<img class="h-full w-full object-cover" src={`/assets/images/dota_${item.name}.png`} alt="" />
				</div>
				<div>
					<Icon
						name={imgCheckeds.includes(item.name) ? 'ri-arrow-up-s-fill' : 'ri-arrow-up-s-line'}
						theme={imgCheckeds.includes(item.name)}
						alpha={imgCheckeds.includes(item.name) ? 1 : 0.2}
					/>
				</div>
			</div>
		{/snippet}
	</Checkbox>
	<div class="text-sm">
		{imgCheckeds.length > 0 ? '已选' : '未选择任何英雄'}
		<span class="text-[red]">{imgCheckeds.join(' + ')}</span>
	</div>
	<Divider />
</div>

<div class="px-4">
	<div class="mb-4 text-2xl font-bold">行内元素排列</div>
	<div class="mb-4 mt-8 text-lg font-bold">Snippet 行内元素排列</div>
	<Checkbox layout="inline" data={dotaInlines}>
		{#snippet checkboxChild({ item })}
			<!-- svelte-ignore a11y_click_events_have_key_events -->
			<!-- svelte-ignore a11y_no_static_element_interactions -->
			<div
				class="m-1 rounded-sm border px-2 py-0.5 text-sm {checkInlines.includes(item.name)
					? 'bg-primary/10 text-primary dark:bg-dark/10 dark:text-dark'
					: 'border-gray-200 bg-gray-100 dark:border-gray-500 dark:bg-gray-600'}"
				onclick={() => {
					dotaInlineFun(item.name);
				}}
			>
				{item.label}
			</div>
		{/snippet}
	</Checkbox>
	<div class="mt-2 text-xs">已选：{checkInlines.join('-')}</div>
</div>
<Divider />

<div class="px-4 pb-8">
	<div class="mb-4 text-2xl font-bold">纵向排列</div>
	<div class="mb-4 mt-8 text-lg font-bold">基础用法</div>
	<Checkbox data={dota} />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">长文字选项</div>
	<Checkbox data={dotaLong} />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">文字靠左</div>
	<Checkbox data={dota} textPosition="l" />

	<div class="mb-4 mt-8 text-lg font-bold">复杂选项 && 自定义选中效果</div>
	<Checkbox data={dotaVoices}>
		{#snippet checkboxChild({ item })}
			<!-- svelte-ignore a11y_click_events_have_key_events -->
			<!-- svelte-ignore a11y_no_static_element_interactions -->
			<div class="flex cursor-pointer items-center" onclick={() => dotaVoicesFun(item.name)}>
				<div>
					<Icon
						name={voiceCheckeds.includes(item.name) ? 'ri-checkbox-fill' : 'ri-checkbox-line'}
						theme={voiceCheckeds.includes(item.name)}
						alpha={voiceCheckeds.includes(item.name) ? 1 : 0.2}
					/>
				</div>
				<div class="ml-2 grow {voiceCheckeds.includes(item.name) ? 'text-primary dark:text-dark' : ''}">
					{item.label}
					{#each item.voices as string[] as voice}
						<div class="text-xs">{voice}</div>
					{/each}
					<div class="mt-1 h-px bg-black/10 dark:bg-white/10"></div>
				</div>
			</div>
		{/snippet}
	</Checkbox>

	<div class="mb-4 mt-8 text-lg font-bold">批量操作</div>
	<Checkbox data={dotaAll} bind:checkeds={checkDotas} />
	<div class="mt-2 text-xs">已选：{checkDotas.map((a) => dotaAll.find((b) => b.name === a)?.label).join('-')}</div>
	<div class="mt-2 text-xs">未选：{noCheckDotas.map((a) => dotaAll.find((b) => b.name === a)?.label).join('-')}</div>
	<div class="mt-2 flex">
		<div class="flex-1">
			<Button fill="lineTheme" heightIn="1" onclick={checkAllFun}>全选</Button>
		</div>
		<div class="flex-1">
			<Button fill="lineTheme" heightIn="1" onclick={checkNoneFun}>全不选</Button>
		</div>
		<div class="flex-1">
			<Button fill="lineTheme" heightIn="1" onclick={checkReverseFun}>反选</Button>
		</div>
	</div>
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">带动画</div>
	<div class="flex justify-center" style="height: {animateHeight}px;">
		<div class="flex-1">
			<div class="pb-2">未选</div>
			{#each animateNos as item (item)}
				<div in:receive={{ key: item }} out:send={{ key: item }} animate:flip={{ duration: 600 }} bind:clientHeight={heights}>
					<CheckboxItem name={item} checked={!animateNos.includes(item)} onclick={checkAnimateNoFun}>{item}</CheckboxItem>
				</div>
			{/each}
		</div>
		<div class="flex-1">
			<div class="pb-2">已选</div>
			{#each animateYess as item (item)}
				<div in:receive={{ key: item }} out:send={{ key: item }} animate:flip={{ duration: 600 }}>
					<CheckboxItem name={item} checked={animateYess.includes(item)} onclick={checkAnimaYesFun}>{item}</CheckboxItem>
				</div>
			{/each}
		</div>
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/components/Aphorism.svelte
================================================
<script lang="ts">
	// 引入数据
	// import data
	import aphorisms from '../../data/aphorisms.js';

	/**
	 * @typedef {Object} Props
	 * @property {number} [num] - number of items to display
	 * @property {boolean} [compact] - whether to use compact mode
	 */
	/** @type {Props} */
	let { num = 0, compact = false } = $props();

	// 从 aphorisms 随机取出 num 条数据
	// get num items from aphorisms randomly
	const aphorismsList = aphorisms.sort(() => Math.random() - 0.5).slice(0, num);
</script>

<div class="{compact ? '' : 'px-4 py-8 '}divide-y divide-black/5 dark:divide-white/5">
	{#each aphorismsList as item}
		<div class:py-6={num > 1}>
			<div class="text-justify text-sm">{item.text}</div>
			<div class="mt-1 text-right" class:italic={item.fromItalic}>{item.from}</div>
		</div>
	{/each}
</div>



================================================
FILE: packages/stdf/src/routes/components/ThemeSwitch.svelte
================================================
<script lang="ts">
	import { switchTheme } from '$lib/theme/index.js';
	import themes from '../../data/themes/index.js';

	const isZh = sessionStorage.getItem('lang') === 'zh_CN';

	let currentColor = $state('STDF');

	const selectColorFunc = (e: MouseEvent, item: (typeof themes)[number]) => {
		// 阻止冒泡
		// Prevent bubbling
		e.stopPropagation();
		currentColor = item.name;
		switchTheme(item.theme);
	};
</script>

<div class="my-2 flex flex-col flex-wrap gap-1">
	{#each themes as item (item.name)}
		<button
			class="flex items-center justify-between gap-0.5 border px-0.5 py-1 {currentColor === item.name
				? 'border-primary dark:border-dark'
				: 'border-gray-100 dark:border-gray-700'} cursor-pointer rounded-sm"
			onclick={(e) => selectColorFunc(e, item)}
		>
			<div class="size-3 {currentColor === item.name ? 'fill-primary dark:fill-dark' : 'fill-gray-300 dark:fill-gray-700'}">
				<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
					<path
						d="M12 2C17.5222 2 22 5.97778 22 10.8889C22 13.9556 19.5111 16.4444 16.4444 16.4444H14.4778C13.5556 16.4444 12.8111 17.1889 12.8111 18.1111C12.8111 18.5333 12.9778 18.9222 13.2333 19.2111C13.5 19.5111 13.6667 19.9 13.6667 20.3333C13.6667 21.2556 12.9 22 12 22C6.47778 22 2 17.5222 2 12C2 6.47778 6.47778 2 12 2ZM7.5 12C8.32843 12 9 11.3284 9 10.5C9 9.67157 8.32843 9 7.5 9C6.67157 9 6 9.67157 6 10.5C6 11.3284 6.67157 12 7.5 12ZM16.5 12C17.3284 12 18 11.3284 18 10.5C18 9.67157 17.3284 9 16.5 9C15.6716 9 15 9.67157 15 10.5C15 11.3284 15.6716 12 16.5 12ZM12 9C12.8284 9 13.5 8.32843 13.5 7.5C13.5 6.67157 12.8284 6 12 6C11.1716 6 10.5 6.67157 10.5 7.5C10.5 8.32843 11.1716 9 12 9Z"
					>
					</path>
				</svg>
			</div>
			<div class="flex-1 whitespace-nowrap text-left text-xs font-normal">{isZh ? item.name_CN : item.name}</div>
			<div class="flex justify-between gap-1">
				<!-- theme  -->
				<div class="rounded-xs flex overflow-hidden">
					<div class="bg-primary w-3" style="background-color: {item.theme.color.primary.default};"></div>
					<div class="bg-dark w-3" style="background-color: {item.theme.color.dark.default};"></div>
				</div>
				<div class="flex flex-col justify-between gap-px">
					<!-- Functional -->
					<div class="flex gap-px">
						<div class="size-1.5 rounded" style="background-color: {item.theme.color.functional.success};"></div>
						<div class="size-1.5 rounded" style="background-color: {item.theme.color.functional.warning};"></div>
						<div class="size-1.5 rounded" style="background-color: {item.theme.color.functional.error};"></div>
						<div class="size-1.5 rounded" style="background-color: {item.theme.color.functional.info};"></div>
					</div>
					<!-- Extended -->
					<div class="flex justify-between gap-px">
						{#each item.theme.color?.extend ?? [] as child (child.alias)}
							<div class="size-1.5 rounded" style="background-color: {child.color};"></div>
						{/each}
					</div>
				</div>
			</div>
		</button>
	{/each}
</div>



================================================
FILE: packages/stdf/src/routes/dialog/en_US/+page.svelte
================================================
<!-- Dialog Demo -->
<script lang="ts">
	import { Dialog, Cell, Toast, Loading } from '$lib/index.js';
	import Aphorism from '../../components/Aphorism.svelte';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);
	let visible15 = $state(false);
	let visible16 = $state(false);
	let visible17 = $state(false);
	let visible18 = $state(false);
	let visible19 = $state(false);

	let toastVisible = $state(false);
	let toastVisible2 = $state(false);
	let toastVisible3 = $state(false);
	let toastVisible4 = $state(false);

	$effect(() => {
		if (visible8) {
			setTimeout(() => {
				visible8 = false;
			}, 3000);
		}
	});

	let loading = $state(false);
	const somethingFnc = () => {
		loading = true;
		setTimeout(() => {
			loading = false;
			visible18 = false;
			toastVisible4 = true;
		}, 3000);
	};
</script>

<div class="py-4">
	<Cell title="Basic Usage" onclick={() => (visible1 = true)} />
	<Dialog bind:visible={visible1} title="Li Xiaoyao" content="Go to Fairy Island?" />

	<Cell title="Content with Snippet" onclick={() => (visible2 = true)} />
	<Dialog bind:visible={visible2}>
		{#snippet contentChild()}
			<Aphorism num={1} compact />
		{/snippet}
	</Dialog>

	<Cell title="No Title" onclick={() => (visible3 = true)} />
	<Dialog bind:visible={visible3} title="" />

	<Cell title="Close on Mask Click" onclick={() => (visible5 = true)} />
	<Dialog bind:visible={visible5} popup={{ maskClosable: true }} />

	<Cell title="Custom Icon" onclick={() => (visible6 = true)} />
	<Dialog
		bind:visible={visible6}
		content="Please wear a mask!"
		showIcon
		icon={{ name: 'ri-surgical-mask-fill', size: 40, injClass: 'text-[#48a1b4]' }}
		secondaryText="No mask"
		primaryText="OK"
	/>

	<Cell title="Scrollable Content" onclick={() => (visible4 = true)} />
	<Dialog bind:visible={visible4}>
		{#snippet contentChild()}
			<div class="max-h-56 overflow-auto">
				<Aphorism num={6} compact />
			</div>
		{/snippet}
	</Dialog>

	<Cell title="Bounce Animation" onclick={() => (visible11 = true)} />
	<Dialog bind:visible={visible11} content="Bounce transition" popup={{ easeType: 'backOut' }} />

	<Cell title="Left Title" onclick={() => (visible7 = true)} />
	<Dialog bind:visible={visible7} title="Left Title" titleAlign="left" />

	<Cell title="Auto Close" onclick={() => (visible8 = true)} />
	<Dialog bind:visible={visible8} content="Don't move! Closing in 3s!" />

	<Cell title="Primary Button Ratio" onclick={() => (visible9 = true)} />
	<Dialog bind:visible={visible9} btnRatio={[3, 2]} />

	<Cell title="Reverse Button Order" onclick={() => (visible10 = true)} />
	<Dialog bind:visible={visible10} btnReverse />

	<Cell title="Larger Button Gap" onclick={() => (visible19 = true)} />
	<Dialog bind:visible={visible19} btnGap="16" />

	<Cell title="Text Buttons" onclick={() => (visible12 = true)} />
	<Dialog bind:visible={visible12} btnStyle="text" />

	<Cell title="Text Buttons with Line" onclick={() => (visible13 = true)} />
	<Dialog bind:visible={visible13} btnStyle="textLine" />

	<Cell title="Rounded Buttons" onclick={() => (visible15 = true)} />
	<Dialog bind:visible={visible15} primaryButton={{ radius: 'full' }} secondaryButton={{ radius: 'full' }} />

	<Cell title="Secondary Event" onclick={() => (visible14 = true)} />
	<Dialog bind:visible={visible14} onsecondary={() => (toastVisible = true)} />
	<Toast bind:visible={toastVisible} message="Cancelled!" />

	<Cell title="Close Event" onclick={() => (visible16 = true)} />
	<Dialog bind:visible={visible16} onclose={() => (toastVisible2 = true)} />
	<Toast bind:visible={toastVisible2} message="Dialog closed!" />

	<Cell title="Primary Event" onclick={() => (visible17 = true)} />
	<Dialog bind:visible={visible17} onprimary={() => (toastVisible3 = true)} />
	<Toast bind:visible={toastVisible3} message="Confirmed!" />

	<Cell title="Async Primary Event" onclick={() => (visible18 = true)} />
	<Dialog bind:visible={visible18} onprimary={somethingFnc} title="Ghost" content="Enter the Demon Tower?">
		{#snippet primaryChild()}
			<span>
				{#if loading}
					<Loading inverse width="12" height="6" type="1_17" />
				{:else}
					Enter
				{/if}
			</span>
		{/snippet}
	</Dialog>
	<Toast bind:visible={toastVisible4} message="Entered the tower!" />
</div>

<!-- Aphorism.svelte -->
<!-- 
<script lang="ts">
	// 引入数据
	// import data
	import aphorisms from '../../data/aphorisms';

	/**
	 * @typedef {Object} Props
	 * @property {number} [num] - number of items to display
	 * @property {boolean} [compact] - whether to use compact mode
	 */
	/** @type {Props} */
	let { num = 0, compact = false } = $props();

	// 从 aphorisms 随机取出 num 条数据
	// get num items from aphorisms randomly
	const aphorismsList = aphorisms.sort(() => Math.random() - 0.5).slice(0, num);
</script>

<div class="{compact ? '' : 'px-4 py-8 '}divide-y divide-black/5 dark:divide-white/5">
	{#each aphorismsList as item}
		<div class:py-6={num > 1}>
			<div class="text-sm text-justify">{item.text}</div>
			<div class="text-right mt-1" class:italic={item.fromItalic}>{item.from}</div>
		</div>
	{/each}
</div>
-->



================================================
FILE: packages/stdf/src/routes/dialog/zh_CN/+page.svelte
================================================
<!-- Dialog Demo -->
<script lang="ts">
	import { Dialog, Cell, Toast, Loading } from '$lib/index.js';
	import Aphorism from '../../components/Aphorism.svelte';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);
	let visible15 = $state(false);
	let visible16 = $state(false);
	let visible17 = $state(false);
	let visible18 = $state(false);
	let visible19 = $state(false);

	let toastVisible = $state(false);
	let toastVisible2 = $state(false);
	let toastVisible3 = $state(false);
	let toastVisible4 = $state(false);

	$effect(() => {
		if (visible8) {
			setTimeout(() => {
				visible8 = false;
			}, 3000);
		}
	});

	let loading = $state(false);
	const somethingFnc = () => {
		loading = true;
		setTimeout(() => {
			loading = false;
			visible18 = false;
			toastVisible4 = true;
		}, 3000);
	};
</script>

<div class="py-4">
	<Cell title="基础用法" onclick={() => (visible1 = true)} />
	<Dialog bind:visible={visible1} title="李逍遥" content="你确认前往仙灵岛吗？" />

	<Cell title="内容使用 Snippet" onclick={() => (visible2 = true)} />
	<Dialog bind:visible={visible2}>
		{#snippet contentChild()}
			<Aphorism num={1} compact />
		{/snippet}
	</Dialog>

	<Cell title="不显示标题" onclick={() => (visible3 = true)} />
	<Dialog bind:visible={visible3} title="" />

	<Cell title="点击遮罩关闭" onclick={() => (visible5 = true)} />
	<Dialog bind:visible={visible5} popup={{ maskClosable: true }} />

	<Cell title="自定义图标" onclick={() => (visible6 = true)} />
	<Dialog
		bind:visible={visible6}
		content="请佩戴口罩！"
		showIcon
		icon={{ name: 'ri-surgical-mask-fill', size: 40, injClass: 'text-[#48a1b4]' }}
		secondaryText="没携带"
		primaryText="好的"
	/>

	<Cell title="内容使用 Snippet 且滚动" onclick={() => (visible4 = true)} />
	<Dialog bind:visible={visible4}>
		{#snippet contentChild()}
			<div class="max-h-56 overflow-auto">
				<Aphorism num={6} compact />
			</div>
		{/snippet}
	</Dialog>

	<Cell title="另一种动画效果" onclick={() => (visible11 = true)} />
	<Dialog bind:visible={visible11} content="回弹过渡" popup={{ easeType: 'backOut' }} />

	<Cell title="标题居左" onclick={() => (visible7 = true)} />
	<Dialog bind:visible={visible7} title="标题居左" titleAlign="left" />

	<Cell title="自动关闭" onclick={() => (visible8 = true)} />
	<Dialog bind:visible={visible8} content="别动！3 秒后我立即消失！" />

	<Cell title="主按钮占比多一点" onclick={() => (visible9 = true)} />
	<Dialog bind:visible={visible9} btnRatio={[3, 2]} />

	<Cell title="主次按钮位置反转" onclick={() => (visible10 = true)} />
	<Dialog bind:visible={visible10} btnReverse />

	<Cell title="按钮间距大一点" onclick={() => (visible19 = true)} />
	<Dialog bind:visible={visible19} btnGap="16" />

	<Cell title="按钮为纯文字" onclick={() => (visible12 = true)} />
	<Dialog bind:visible={visible12} btnStyle="text" />

	<Cell title="按钮为纯文字有分割线" onclick={() => (visible13 = true)} />
	<Dialog bind:visible={visible13} btnStyle="textLine" />

	<Cell title="全圆角按钮" onclick={() => (visible15 = true)} />
	<Dialog bind:visible={visible15} primaryButton={{ radius: 'full' }} secondaryButton={{ radius: 'full' }} />

	<Cell title="监听次要事件" onclick={() => (visible14 = true)} />
	<Dialog bind:visible={visible14} onsecondary={() => (toastVisible = true)} />
	<Toast bind:visible={toastVisible} message="点击了取消！" />

	<Cell title="监听关闭事件" onclick={() => (visible16 = true)} />
	<Dialog bind:visible={visible16} onclose={() => (toastVisible2 = true)} />
	<Toast bind:visible={toastVisible2} message="关闭了 Dialog！" />

	<Cell title="监听主要事件" onclick={() => (visible17 = true)} />
	<Dialog bind:visible={visible17} onprimary={() => (toastVisible3 = true)} />
	<Toast bind:visible={toastVisible3} message="点击了确认！" />

	<Cell title="异步执行主要事件" onclick={() => (visible18 = true)} />
	<Dialog bind:visible={visible18} onprimary={somethingFnc} title="小鬼" content="你一定要进入锁妖塔吗？">
		{#snippet primaryChild()}
			<span>
				{#if loading}
					<Loading inverse width="12" height="6" type="1_17" />
				{:else}
					进入
				{/if}
			</span>
		{/snippet}
	</Dialog>
	<Toast bind:visible={toastVisible4} message="已进入锁妖塔！" />
</div>

<!-- Aphorism.svelte -->
<!-- 
<script lang=""ts>
	// 引入数据
	// import data
	import aphorisms from '../../data/aphorisms';

	/**
	 * @typedef {Object} Props
	 * @property {number} [num] - number of items to display
	 * @property {boolean} [compact] - whether to use compact mode
	 */
	/** @type {Props} */
	let { num = 0, compact = false } = $props();

	// 从 aphorisms 随机取出 num 条数据
	// get num items from aphorisms randomly
	const aphorismsList = aphorisms.sort(() => Math.random() - 0.5).slice(0, num);
</script>

<div class="{compact ? '' : 'px-4 py-8 '}divide-y divide-black/5 dark:divide-white/5">
	{#each aphorismsList as item}
		<div class:py-6={num > 1}>
			<div class="text-sm text-justify">{item.text}</div>
			<div class="text-right mt-1" class:italic={item.fromItalic}>{item.from}</div>
		</div>
	{/each}
</div>
-->



================================================
FILE: packages/stdf/src/routes/divider/en_US/+page.svelte
================================================
<!-- Divider Demo -->
<script lang="ts">
	import { Divider } from '$lib/index.js';
</script>

<div class="flex flex-col space-y-8 py-8">
	<div>
		<div class="p-4 font-bold">Different lengths</div>
		<Divider />
		<Divider px="4" />
		<Divider px="8" />
		<Divider px="16" />
		<Divider px="36" />
	</div>
	<div>
		<div class="p-4 font-bold">Text</div>
		<Divider text="The Guzheng Project" />
		<Divider px="4" text="Red Cliff Base" />
	</div>
	<div>
		<div class="p-4 font-bold">Different heights</div>
		<div class="px-4 text-sm">Start</div>
		<Divider py="0" />
		<div class="px-4 text-sm">Height is 0</div>
		<Divider />
		<div class="px-4 text-sm">Height is 4</div>
		<Divider py="8" />
		<div class="px-4 text-sm">Height is 8</div>
	</div>

	<div>
		<div class="p-4 font-bold">Text position</div>
		<Divider text="Left" align="left" />
		<Divider text="Center" />
		<Divider text="Right" align="right" />
	</div>
	<div>
		<div class="p-4 font-bold">Line style</div>
		<Divider text="Solid" />
		<Divider line="dashed" text="Dashed" />
		<Divider line="dotted" text="Dotted" />
	</div>
	<div>
		<div class="p-4 font-bold">Custom color</div>
		<Divider injClass="!border-[blue] dark:!border-[yellow]" />
		<Divider text="Custom line" injClass="!border-[red] dark:!border-[purple]" />
		<Divider text="Custom text" injClass="!text-[red]" />
		<Divider text="Custom line and text" injClass="!border-[red] !text-[blue] dark:!text-[purple]" />
		<Divider line="dashed" text="Custom dashed line" injClass="!border-[#FF5722]" />
	</div>
	<div class="px-4">
		<div class="py-4 font-bold">Vertical divider</div>
		<div class="text-sm">
			Three days in the sky<Divider layout="v" />Three days in a row<Divider layout="v" />Human computer
		</div>
	</div>
	<div>
		<div class="p-4 font-bold">Different weights</div>
		<Divider />
		<Divider weight="2" />
		<Divider weight="4" />
		<div class="px-4 text-sm">
			Guardian<Divider layout="v" />Three days in the sky<Divider layout="v" weight="2" />Three days in a row<Divider
				layout="v"
				weight="4"
			/>Human computer
		</div>
	</div>
	<div class="px-4">
		<div class="py-4 font-bold">Custom vertical divider</div>
		<div class="text-sm">
			Increase spacing
			<Divider layout="v" mx="4" />
			Custom
			<Divider layout="v" mx="4" injClass="!border-[red] dark:!border-[purple]" />
			Color
			<Divider line="dashed" layout="v" mx="4" injClass="!border-[red] dark:!border-[purple]" />
			Line style
		</div>
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/divider/zh_CN/+page.svelte
================================================
<!-- Divider Demo -->
<script lang="ts">
	import { Divider } from '$lib/index.js';
</script>

<div class="flex flex-col space-y-8 py-8">
	<div>
		<div class="p-4 font-bold">不同长度</div>
		<Divider />
		<Divider px="4" />
		<Divider px="8" />
		<Divider px="16" />
		<Divider px="36" />
	</div>
	<div>
		<div class="p-4 font-bold">包含文字</div>
		<Divider text="古筝计划" />
		<Divider px="4" text="红岸基地" />
	</div>
	<div>
		<div class="p-4 font-bold">不同高度</div>
		<div class="px-4 text-sm">开始</div>
		<Divider py="0" />
		<div class="px-4 text-sm">高度为 0</div>
		<Divider />
		<div class="px-4 text-sm">高度为 4</div>
		<Divider py="8" />
		<div class="px-4 text-sm">高度为 8</div>
	</div>

	<div>
		<div class="p-4 font-bold">文字位置</div>
		<Divider text="左侧" align="left" />
		<Divider text="居中" />
		<Divider text="右侧" align="right" />
	</div>
	<div>
		<div class="p-4 font-bold">线条风格</div>
		<Divider text="实线" />
		<Divider line="dashed" text="虚线" />
		<Divider line="dotted" text="点线" />
	</div>
	<div>
		<div class="p-4 font-bold">自定义颜色</div>
		<Divider injClass="!border-[blue] dark:!border-[yellow]" />
		<Divider text="自定义线条" injClass="!border-[red] dark:!border-[purple]" />
		<Divider text="自定义文字" injClass="!text-[red]" />
		<Divider text="自定义线条与文字" injClass="!border-[red] !text-[blue] dark:!text-[purple]" />
		<Divider line="dashed" text="自定义虚线" injClass="!border-[#FF5722]" />
	</div>
	<div class="px-4">
		<div class="py-4 font-bold">垂直分割线</div>
		<div class="text-sm">
			三日凌空<Divider layout="v" />三日连珠<Divider layout="v" />人列计算机
		</div>
	</div>
	<div>
		<div class="p-4 font-bold">不同粗细</div>
		<Divider />
		<Divider weight="2" />
		<Divider weight="4" />
		<div class="px-4 text-sm">
			执剑人<Divider layout="v" />三日凌空<Divider layout="v" weight="2" />三日连珠<Divider layout="v" weight="4" />人列计算机
		</div>
	</div>
	<div class="px-4">
		<div class="py-4 font-bold">自定义垂直分割线</div>
		<div class="text-sm">
			加大间距
			<Divider layout="v" mx="4" />
			自定义
			<Divider layout="v" mx="4" injClass="!border-[red] dark:!border-[purple]" />
			颜色
			<Divider line="dashed" layout="v" mx="4" injClass="!border-[red] dark:!border-[purple]" />
			与线条风格
		</div>
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/grids/en_US/+page.svelte
================================================
<!-- Grids Demo -->
<script lang="ts">
	import { Grids, Grid, Placeholder, Switch, Icon, Button } from '$lib/index.js';

	const devices = ['iOS', 'Android', 'Windows', 'macOS', 'Ubuntu'];
	let curentIndex = $state(0);
	let currentDevice = $derived(devices[curentIndex]);
	const changeDeviceFun = () => {
		if (curentIndex === devices.length - 1) {
			curentIndex = 0;
		} else {
			curentIndex++;
		}
	};
	let color = $state(false);
	let colorCss = $derived(`${color ? ' bg-gradient-to-tr from-extend0/70 to-extend2/70' : ' bg-gray-100 dark:bg-gray-700'}`);
	const changeColorFun = (active: boolean) => {
		color = active;
	};
	// Get current date
	const date = new Date();
	// Get current month in Chinese
	const monthArr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
	const monthIndex = date.getMonth();
	let month = $derived(monthArr[monthIndex]);
	const day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
	const hour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
	const minute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
	let time = $derived(`${hour}:${minute}`);
	// Get Chinese week
	const week = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
	let weekDay = $derived(week[date.getDay()]);
</script>

<div class="mt-8 px-4 font-bold">Using Placeholder Example 3﹡4</div>
<Grids cols="4">
	<Grid row="3">
		<Placeholder>3﹡1</Placeholder>
	</Grid>
	<Grid col="3">
		<Placeholder>1﹡3</Placeholder>
	</Grid>
	<Grid row="2">
		<Placeholder>2﹡1</Placeholder>
	</Grid>
	<Grid col="2">
		<Placeholder>1﹡2</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
</Grids>

<div class="mt-8 px-4 font-bold">Using Placeholder Example 4﹡6</div>
<Grids>
	<Grid row="3" col="2">
		<Placeholder>3﹡2</Placeholder>
	</Grid>
	<Grid col="3">
		<Placeholder>1﹡3</Placeholder>
	</Grid>
	<Grid row="4">
		<Placeholder>4﹡1</Placeholder>
	</Grid>
	<Grid row="2">
		<Placeholder>2﹡1</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
	<Grid col="4">
		<Placeholder>1﹡4</Placeholder>
	</Grid>
</Grids>

<div class="mt-8 px-4 font-bold">Increase Margin and Cell Gap</div>
<Grids cols="4" gap="4" mx="8" my="8">
	<Grid row="3">
		<Placeholder>3﹡1</Placeholder>
	</Grid>
	<Grid col="3">
		<Placeholder>1﹡3</Placeholder>
	</Grid>
	<Grid row="2">
		<Placeholder>2﹡1</Placeholder>
	</Grid>
	<Grid col="2">
		<Placeholder>1﹡2</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
</Grids>

<div class="mt-8 px-4 font-bold">Scene Example 6﹡5</div>
<div class="pb-8 pt-2">
	<div class={`mx-2 rounded-xl p-2 shadow-sm transition duration-300${colorCss}`}>
		<Grids cols="5" mx="0" my="0">
			<Grid row="3">
				<div
					class="flex h-full flex-col justify-between rounded-lg bg-white p-1 text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<div>{weekDay}</div>
					<div class="text-4xl">{day}</div>
					<div class="text-gray-600">{month}</div>
				</div>
			</Grid>
			<Grid row="2">
				<div
					class="flex h-full flex-col justify-center rounded-lg bg-white p-1 text-center text-xl font-bold shadow-sm dark:bg-black dark:shadow-white/10"
				>
					{time}
				</div>
			</Grid>
			<Grid row="2">
				<div
					class="flex h-full flex-col justify-around rounded-lg bg-white p-1 text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<div class="flex justify-center">
						<Switch radius="full" onchange={changeColorFun}>
							{#snippet falseChild()}
								<div><Icon name="ri-paint-brush-line" size={12} /></div>
							{/snippet}
							{#snippet trueChild()}
								<div><Icon name="ri-paint-brush-fill" size={12} theme /></div>
							{/snippet}
						</Switch>
					</div>
					<div>Colorful</div>
				</div>
			</Grid>

			<Grid row="2" col="2">
				<div
					class="flex h-full flex-col justify-center rounded-lg bg-white text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<Button fill="lineTheme" radius="full" onclick={changeDeviceFun}>Device</Button>
				</div>
			</Grid>
			<Grid row="2" col="2">
				<div
					class="flex h-full justify-around rounded-lg bg-white p-1 py-1 text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<div class="flex flex-col justify-center">
						{#if currentDevice === 'iOS'}
							<Icon name="ri-apple-fill" size={30} />
						{:else if currentDevice === 'Android'}
							<Icon name="ri-android-fill" size={30} />
						{:else if currentDevice === 'Windows'}
							<Icon name="ri-windows-fill" size={30} />
						{:else if currentDevice === 'macOS'}
							<Icon name="ri-command-fill" size={30} />
						{:else}
							<Icon name="ri-ubuntu-fill" size={30} />
						{/if}
					</div>
					<div class="flex flex-col justify-around">
						<div class="text-sm">
							{#if currentDevice === 'iOS'}
								A15 Bionic
							{:else if currentDevice === 'Android'}
								Snapdragon
							{:else if currentDevice === 'Windows'}
								AMD YES
							{:else if currentDevice === 'macOS'}
								M1 Ultra
							{:else}
								Intel
							{/if}
						</div>
						<div>
							{#if currentDevice === 'iOS'}
								iPhone
							{:else if currentDevice === 'Android'}
								Android
							{:else if currentDevice === 'Windows'}
								Windows
							{:else if currentDevice === 'macOS'}
								MacBook Pro
							{:else}
								Ubuntu
							{/if}
						</div>
					</div>
				</div>
			</Grid>
			<Grid row="2">
				<div
					class="flex h-full flex-col justify-around rounded-lg bg-white p-1 text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<div class="flex justify-center">
						<Switch radius="full">
							{#snippet falseChild()}
								<div><Icon name="ri-bluetooth-line" size={12} top={-1} /></div>
							{/snippet}
							{#snippet trueChild()}
								<div><Icon name="ri-bluetooth-connect-line" size={12} theme top={-1} /></div>
							{/snippet}
						</Switch>
					</div>
					<div>Bluetooth</div>
				</div>
			</Grid>
			<Grid row="4">
				<div
					class="flex h-full flex-col items-center justify-around rounded-lg bg-white text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<div class="w-1/2 overflow-hidden">
						<img class="block dark:hidden" src="/assets/stdf_512px.png" alt="" />
						<img class="hidden dark:block" src="/assets/stdf_dark_512px.png" alt="" />
					</div>
					<div>STDF</div>
				</div>
			</Grid>
			<Grid row="3">
				<div
					class="flex h-full flex-col justify-around rounded-lg bg-white text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<div>92%</div>
					<div class="animate-pulse">
						<Icon name="ri-battery-2-charge-line" size={30} injClass="text-extend1" />
					</div>
					<div>充电中</div>
				</div>
			</Grid>
			<Grid row="2">
				<div
					class="flex h-full flex-col justify-center rounded-lg bg-white text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					{#if currentDevice === 'iOS'}
						<Icon name="ri-smartphone-line" size={30} />
					{:else if currentDevice === 'Android'}
						<Icon name="ri-tablet-line" size={30} />
					{:else if currentDevice === 'Windows'}
						<Icon name="ri-computer-line" size={30} />
					{:else if currentDevice === 'macOS'}
						<Icon name="ri-macbook-fill" size={30} />
					{:else}
						<Icon name="ri-ubuntu-line" size={30} />
					{/if}
				</div>
			</Grid>
			<Grid row="2">
				<div
					class="flex h-full flex-col items-center justify-around rounded-lg bg-white py-1 text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<div>
						<Icon name="ri-sun-line" size={20} />
					</div>
					<div>
						<div>68%</div>
					</div>
				</div>
			</Grid>
			<Grid row="2">
				<div
					class="flex h-full flex-col justify-around rounded-lg bg-white p-1 text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<div class="flex justify-center">
						<Switch radius="full">
							{#snippet falseChild()}
								<div><Icon name="ri-wifi-off-line" size={12} /></div>
							{/snippet}
							{#snippet trueChild()}
								<div><Icon name="ri-wifi-line" size={12} theme /></div>
							{/snippet}
						</Switch>
					</div>
					<div>Wi-Fi</div>
				</div>
			</Grid>
		</Grids>
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/grids/zh_CN/+page.svelte
================================================
<!-- Grids Demo -->
<script lang="ts">
	import { Grids, Grid, Placeholder, Switch, Icon, Button } from '$lib/index.js';

	const devices = ['iOS', 'Android', 'Windows', 'macOS', 'Ubuntu'];
	let curentIndex: number = $state(0);
	let currentDevice: string = $derived(devices[curentIndex]);
	const changeDeviceFun = () => {
		if (curentIndex === devices.length - 1) {
			curentIndex = 0;
		} else {
			curentIndex++;
		}
	};
	let color = $state(false);
	let colorCss = $derived(color ? ' bg-gradient-to-tr from-extend0/70 to-extend2/70' : ' bg-gray-100 dark:bg-gray-700');
	const changeColorFun = (active: boolean) => {
		color = active;
	};
	//获取当前时间
	const date = new Date();
	//获取当前月份转为汉字
	const monthArr = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
	const monthIndex = date.getMonth();
	let month = $derived(monthArr[monthIndex]);
	const day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
	const hour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
	const minute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
	let time = $derived(`${hour}:${minute}`);
	//获取中文周几
	const week = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
	let weekDay = $derived(week[date.getDay()]);
</script>

<div class="mt-8 px-4 font-bold">使用占位符示例 3﹡4</div>
<Grids cols="4">
	<Grid row="3">
		<Placeholder>3﹡1</Placeholder>
	</Grid>
	<Grid col="3">
		<Placeholder>1﹡3</Placeholder>
	</Grid>
	<Grid row="2">
		<Placeholder>2﹡1</Placeholder>
	</Grid>
	<Grid col="2">
		<Placeholder>1﹡2</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
</Grids>

<div class="mt-8 px-4 font-bold">使用占位符示例 4﹡6</div>
<Grids>
	<Grid row="3" col="2">
		<Placeholder>3﹡2</Placeholder>
	</Grid>
	<Grid col="3">
		<Placeholder>1﹡3</Placeholder>
	</Grid>
	<Grid row="4">
		<Placeholder>4﹡1</Placeholder>
	</Grid>
	<Grid row="2">
		<Placeholder>2﹡1</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
	<Grid col="4">
		<Placeholder>1﹡4</Placeholder>
	</Grid>
</Grids>

<div class="mt-8 px-4 font-bold">增加外边距与单元格间距</div>
<Grids cols="4" gap="4" mx="8" my="8">
	<Grid row="3">
		<Placeholder>3﹡1</Placeholder>
	</Grid>
	<Grid col="3">
		<Placeholder>1﹡3</Placeholder>
	</Grid>
	<Grid row="2">
		<Placeholder>2﹡1</Placeholder>
	</Grid>
	<Grid col="2">
		<Placeholder>1﹡2</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
	<Grid>
		<Placeholder>1﹡1</Placeholder>
	</Grid>
</Grids>

<div class="mt-8 px-4 font-bold">场景示例 6﹡5</div>
<div class="pb-8 pt-2">
	<div class="mx-2 rounded-xl p-2 shadow-sm transition duration-300{colorCss}">
		<Grids cols="5" mx="0" my="0">
			<Grid row="3">
				<div
					class="flex h-full flex-col justify-between rounded-lg bg-white p-1 text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<div>{weekDay}</div>
					<div class="text-4xl">{day}</div>
					<div class="text-gray-600">{month}</div>
				</div>
			</Grid>
			<Grid row="2">
				<div
					class="flex h-full flex-col justify-center rounded-lg bg-white p-1 text-center text-xl font-bold shadow-sm dark:bg-black dark:shadow-white/10"
				>
					{time}
				</div>
			</Grid>
			<Grid row="2">
				<div
					class="flex h-full flex-col justify-around rounded-lg bg-white p-1 text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<div class="flex justify-center">
						<Switch radius="full" onchange={changeColorFun}>
							{#snippet falseChild()}
								<div><Icon name="ri-paint-brush-line" size={12} /></div>
							{/snippet}
							{#snippet trueChild()}
								<div><Icon name="ri-paint-brush-fill" size={12} theme /></div>
							{/snippet}
						</Switch>
					</div>
					<div>彩色</div>
				</div>
			</Grid>

			<Grid row="2" col="2">
				<div
					class="flex h-full flex-col justify-center rounded-lg bg-white text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<Button fill="lineTheme" radius="full" onclick={changeDeviceFun}>切换设备</Button>
				</div>
			</Grid>
			<Grid row="2" col="2">
				<div
					class="flex h-full justify-around rounded-lg bg-white p-1 py-1 text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<div class="flex flex-col justify-center">
						{#if currentDevice === 'iOS'}
							<Icon name="ri-apple-fill" size={30} />
						{:else if currentDevice === 'Android'}
							<Icon name="ri-android-fill" size={30} />
						{:else if currentDevice === 'Windows'}
							<Icon name="ri-windows-fill" size={30} />
						{:else if currentDevice === 'macOS'}
							<Icon name="ri-command-fill" size={30} />
						{:else}
							<Icon name="ri-ubuntu-fill" size={30} />
						{/if}
					</div>
					<div class="flex flex-col justify-around">
						<div class="text-sm">
							{#if currentDevice === 'iOS'}
								A15 Bionic
							{:else if currentDevice === 'Android'}
								骁龙 8 Gen1
							{:else if currentDevice === 'Windows'}
								AMD YES
							{:else if currentDevice === 'macOS'}
								M1 Ultra
							{:else}
								Intel
							{/if}
						</div>
						<div>
							{#if currentDevice === 'iOS'}
								iPhone
							{:else if currentDevice === 'Android'}
								Android
							{:else if currentDevice === 'Windows'}
								Windows
							{:else if currentDevice === 'macOS'}
								MacBook Pro
							{:else}
								Ubuntu
							{/if}
						</div>
					</div>
				</div>
			</Grid>
			<Grid row="2">
				<div
					class="flex h-full flex-col justify-around rounded-lg bg-white p-1 text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<div class="flex justify-center">
						<Switch radius="full">
							{#snippet falseChild()}
								<div><Icon name="ri-bluetooth-line" size={12} top={-1} /></div>
							{/snippet}
							{#snippet trueChild()}
								<div><Icon name="ri-bluetooth-connect-line" size={12} theme top={-1} /></div>
							{/snippet}
						</Switch>
					</div>
					<div>蓝 牙</div>
				</div>
			</Grid>
			<Grid row="4">
				<div
					class="flex h-full flex-col items-center justify-around rounded-lg bg-white text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<div class="w-1/2 overflow-hidden">
						<img class="block dark:hidden" src="/assets/stdf_512px.png" alt="" />
						<img class="hidden dark:block" src="/assets/stdf_dark_512px.png" alt="" />
					</div>
					<div>STDF</div>
				</div>
			</Grid>
			<Grid row="3">
				<div
					class="flex h-full flex-col justify-around rounded-lg bg-white text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<div>92%</div>
					<div class="animate-pulse">
						<Icon name="ri-battery-2-charge-line" size={30} injClass="text-extend1" />
					</div>
					<div>充电中</div>
				</div>
			</Grid>
			<Grid row="2">
				<div
					class="flex h-full flex-col justify-center rounded-lg bg-white text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					{#if currentDevice === 'iOS'}
						<Icon name="ri-smartphone-line" size={30} />
					{:else if currentDevice === 'Android'}
						<Icon name="ri-tablet-line" size={30} />
					{:else if currentDevice === 'Windows'}
						<Icon name="ri-computer-line" size={30} />
					{:else if currentDevice === 'macOS'}
						<Icon name="ri-macbook-fill" size={30} />
					{:else}
						<Icon name="ri-ubuntu-line" size={30} />
					{/if}
				</div>
			</Grid>
			<Grid row="2">
				<div
					class="flex h-full flex-col items-center justify-around rounded-lg bg-white py-1 text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<div>
						<Icon name="ri-sun-line" size={20} />
					</div>
					<div>
						<div>68%</div>
					</div>
				</div>
			</Grid>
			<Grid row="2">
				<div
					class="flex h-full flex-col justify-around rounded-lg bg-white p-1 text-center text-xs shadow-sm dark:bg-black dark:shadow-white/10"
				>
					<div class="flex justify-center">
						<Switch radius="full">
							{#snippet falseChild()}
								<div><Icon name="ri-wifi-off-line" size={12} /></div>
							{/snippet}
							{#snippet trueChild()}
								<div><Icon name="ri-wifi-line" size={12} theme /></div>
							{/snippet}
						</Switch>
					</div>
					<div>Wi-Fi</div>
				</div>
			</Grid>
		</Grids>
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/icon/en_US/+page.svelte
================================================
<!-- Icon Demo, Please make sure you have been introduced symbol.svg file. -->
<script lang="ts">
	import { Icon } from '$lib/index.js';

	const icons = ['ri-spy-fill', 'ri-chrome-fill', 'ri-riding-line', 'ri-switch-fill'];
</script>

<div class="felx felx-col space-y-12 px-4 py-8">
	<div>
		<div class="mb-2 text-xl font-bold">Basic usage</div>
		<div class="flex flex-wrap justify-between">
			{#each icons as icon}
				<div class="flex-1 py-2 text-center">
					<Icon name={icon} />
					<div class="mt-2 text-xs">{icon}</div>
				</div>
			{/each}
		</div>
	</div>
	<div>
		<div class="mb-2 text-xl font-bold">Follow the theme color</div>
		<div class="flex flex-wrap justify-between">
			{#each icons as icon}
				<div class="flex-1 py-2 text-center">
					<Icon name={icon} theme />
				</div>
			{/each}
		</div>
	</div>
	<div>
		<div class="mb-2 text-xl font-bold">Different size</div>
		<div class="flex flex-wrap justify-between">
			{#each icons as icon, i}
				<div class="flex-1 py-2 text-center">
					<Icon name={icon} size={18 + i * 6} />
					<div class="mt-2 text-xs">{18 + i * 6}</div>
				</div>
			{/each}
		</div>
	</div>
	<div>
		<div class="mb-2 text-xl font-bold">Different transparency</div>
		<div class="flex flex-wrap justify-between">
			{#each icons as icon, i}
				<div class="flex-1 py-2 text-center">
					<Icon name={icon} alpha={Number((0.2 + i * 0.2).toFixed(1))} />
					<div class="mt-2 text-xs">{(0.2 + i * 0.2).toFixed(1)}</div>
				</div>
			{/each}
		</div>
	</div>
	<div>
		<div class="mb-2 text-xl font-bold">
			Custom color<span class="ml-2 text-xs font-normal">By injClass</span>
		</div>
		<div class="flex flex-wrap justify-between">
			{#each icons as icon}
				<div class="flex-1 py-2 text-center">
					<Icon name={icon} injClass="text-[red] dark:text-[green]" />
				</div>
			{/each}
		</div>
	</div>
	<div>
		<div class="mb-2 text-xl font-bold">
			Custom color<span class="ml-2 text-xs font-normal">by Snippet</span>
		</div>
		<div class="flex flex-wrap justify-between">
			{#each icons as icon}
				<div class="flex-1 py-2 text-center">
					<Icon><i class="text-[#266CF6] dark:text-[#C84031]"> <Icon name={icon} /></i></Icon>
				</div>
			{/each}
		</div>
	</div>
	<div>
		<div class="mb-2 text-xl font-bold">Snippet</div>
		<div class="flex flex-wrap justify-between">
			{#each icons as icon, index}
				<div class="flex-1 py-2 text-center">
					<Icon>
						<svg
							height="24"
							width="24"
							aria-hidden="true"
							viewBox="0 0 16 16"
							data-view-component="true"
							style="display: inline;"
							class={index % 2 ? 'fill-primary dark:fill-dark' : 'fill-black dark:fill-white'}
						>
							<path
								fill-rule="evenodd"
								d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"
							/>
						</svg>
					</Icon>
				</div>
			{/each}
		</div>
	</div>
	<div>
		<div class="mb-2 text-xl font-bold">Offset</div>
		<div class="flex flex-wrap justify-between">
			{#each icons as icon, i}
				<div class="flex-1 py-2 text-center">
					<Icon name={icons[1]} top={-4 + i * 2} />
					top:{-4 + i * 2}
				</div>
			{/each}
		</div>
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/icon/zh_CN/+page.svelte
================================================
<!-- Icon Demo，请确保已引入 symbol.svg 文件。 -->
<script lang="ts">
	import { Icon } from '$lib/index.js';

	const icons = ['ri-spy-fill', 'ri-chrome-fill', 'ri-riding-line', 'ri-switch-fill'];
</script>

<div class="felx felx-col space-y-12 px-4 py-8">
	<div>
		<div class="mb-2 text-xl font-bold">基础用法</div>
		<div class="flex flex-wrap justify-between">
			{#each icons as icon}
				<div class="flex-1 py-2 text-center">
					<Icon name={icon} />
					<div class="mt-2 text-xs">{icon}</div>
				</div>
			{/each}
		</div>
	</div>
	<div>
		<div class="mb-2 text-xl font-bold">跟随主题色</div>
		<div class="flex flex-wrap justify-between">
			{#each icons as icon}
				<div class="flex-1 py-2 text-center">
					<Icon name={icon} theme />
				</div>
			{/each}
		</div>
	</div>
	<div>
		<div class="mb-2 text-xl font-bold">不同大小</div>
		<div class="flex flex-wrap justify-between">
			{#each icons as icon, i}
				<div class="flex-1 py-2 text-center">
					<Icon name={icon} size={18 + i * 6} />
					<div class="mt-2 text-xs">{18 + i * 6}</div>
				</div>
			{/each}
		</div>
	</div>
	<div>
		<div class="mb-2 text-xl font-bold">不同透明度</div>
		<div class="flex flex-wrap justify-between">
			{#each icons as icon, i}
				<div class="flex-1 py-2 text-center">
					<Icon name={icon} alpha={Number((0.2 + i * 0.2).toFixed(1))} />
					<div class="mt-2 text-xs">{(0.2 + i * 0.2).toFixed(1)}</div>
				</div>
			{/each}
		</div>
	</div>
	<div>
		<div class="mb-2 text-xl font-bold">
			自定义颜色<span class="ml-2 text-xs font-normal">通过 injClass</span>
		</div>
		<div class="flex flex-wrap justify-between">
			{#each icons as icon}
				<div class="flex-1 py-2 text-center">
					<Icon name={icon} injClass="text-[red] dark:text-[green]" />
				</div>
			{/each}
		</div>
	</div>
	<div>
		<div class="mb-2 text-xl font-bold">
			自定义颜色<span class="ml-2 text-xs font-normal">通过 Snippet</span>
		</div>
		<div class="flex flex-wrap justify-between">
			{#each icons as icon}
				<div class="flex-1 py-2 text-center">
					<Icon><i class="text-[#266CF6] dark:text-[#C84031]"><Icon name={icon} /></i></Icon>
				</div>
			{/each}
		</div>
	</div>
	<div>
		<div class="mb-2 text-xl font-bold">Snippet</div>
		<div class="flex flex-wrap justify-between">
			<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
			{#each icons as _, index}
				<div class="flex-1 py-2 text-center">
					<Icon>
						<svg
							height="24"
							width="24"
							aria-hidden="true"
							viewBox="0 0 16 16"
							data-view-component="true"
							style="display: inline;"
							class={index % 2 ? 'fill-primary dark:fill-dark' : 'fill-black dark:fill-white'}
						>
							<path
								fill-rule="evenodd"
								d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"
							/>
						</svg>
					</Icon>
				</div>
			{/each}
		</div>
	</div>
	<div>
		<div class="mb-2 text-xl font-bold">偏移</div>
		<div class="flex flex-wrap justify-between">
			<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
			{#each icons as _, i}
				<div class="flex-1 py-2 text-center">
					<Icon name={icons[1]} top={-4 + i * 2} />
					top:{-4 + i * 2}
				</div>
			{/each}
		</div>
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/indexBar/en_US/+page.svelte
================================================
<!-- IndexBar Demo -->
<script lang="ts">
	import { IndexBar, Button, Toast } from '$lib/index.js';
	import type { IndexBarItemProps } from '$lib/types/index.js';

	const addressList: IndexBarItemProps[] = [
		{ index: 'A', title: 'A', child: ['Macau', 'Anning', 'Anqing', 'Anshan'] },
		{ index: 'B', title: 'B', child: ['Beijing', 'Baoding', 'Baotou', 'Baoji'] },
		{ index: 'C', title: 'C', child: ['Chengde', 'Cangzhou', 'Chifeng'] },
		{ index: 'D', title: 'D', child: ['Datong', 'Dalian', 'Dali'] },
		{ index: 'E', title: 'E', child: ['Enshi', 'Ordos', 'Emeishan'] },
		{ index: 'F', title: 'F', child: ['Fushun', 'Foshan', 'Fuquan'] },
		{ index: 'G', title: 'G', child: ['Gejiu', 'Guilin', 'Ganzhou'] },
		{ index: 'H', title: 'H', child: ['Handan', 'Hohhot', 'Hulunbuir'] },
		{ index: 'J', title: 'J', child: ['Jilin', 'Jiuquan', 'Jinjiang'] },
		{ index: 'K', title: 'K', child: ['Kunming', 'Kunshan', 'Kaifeng'] },
		{ index: 'L', title: 'L', child: ['Lhasa', 'Lanzhou', 'Luzhou'] },
		{ index: 'M', title: 'M', child: ['Mianyang', 'Maans', 'Mudanjiang'] },
		{ index: 'N', title: 'N', child: ['Nanchang', 'Nanjing', 'Ningbo'] },
		{ index: 'P', title: 'P', child: ['Putian', 'Panzhihua', 'Pingdingshan'] },
		{ index: 'Q', title: 'Q', child: ['Qujing', 'Qingdao', 'Qiqihar'] },
		{ index: 'R', title: 'R', child: ['Ruili', 'Ruian', 'Ruijin'] },
		{ index: 'S', title: 'S', child: ['Sanya', 'Shanghai', 'Shenzhen'] },
		{ index: 'T', title: 'T', child: ['Taizhou', 'Taiyuan', 'Tianjin'] },
		{ index: 'W', title: 'W', child: ['Wuhan', 'Wuxi', 'Wuhu'] },
		{ index: 'X', title: 'X', child: ['Xi an', 'Xiamen', 'Xuanwei'] },
		{ index: 'Y', title: 'Y', child: ['Yiwu', 'Yinchuan', 'Yuxi'] },
		{ index: 'Z', title: 'Z', child: ['Zhaotong', 'Zunyi', 'Zhangjiajie'] }
	];

	const emojiList: IndexBarItemProps[] = [
		{ index: '😀', title: 'Smileys & Emotion', child: ['😂', '🥰', '🥱', '🧐'] },
		{ index: '👋', title: 'People & Body', child: ['👌', '🤝', '👨‍💻', '💪'] },
		{ index: '🐵', title: 'Animals & Nature', child: ['🦄', '🌱', '🦁', '🐶'] },
		{ index: '🍎', title: 'Food & Drink', child: ['🍑', '🍞', '🍽️', '🍩'] },
		{ index: '🌍', title: 'Travel & Places', child: ['🏔️', '🚆', '✈️', '🛵'] },
		{ index: '🏆', title: 'Activities', child: ['⚽', '🎨', '🏀', '🧨'] },
		{ index: '📱', title: 'Objects', child: ['🎩', '💻', '🎒', '📖'] },
		{ index: '⚠️', title: 'Symbols', child: ['🚫', '⚛️', '🛄', '🔱'] },
		{ index: '🏁', title: 'Flags', child: ['🇨🇳', '🇺🇸', '🇧🇻', '🇦🇹'] }
	];
	const movieTVList: IndexBarItemProps[] = [
		{
			index: '三',
			title: '三体',
			child: [
				'地球往事',
				'黑暗森林',
				'死神永生',
				'科学边界',
				'射手和农场主',
				'寂静的春天',
				'宇宙闪烁',
				'地球叛军',
				'古筝行动',
				'智子',
				'面壁者',
				'咒语',
				'黑暗森林',
				'危机纪元',
				'威慑纪元',
				'广播纪元',
				'掩体纪元',
				'银河纪元',
				'时间开始',
				'时间之外，我们的宇宙'
			]
		},
		{
			index: '流',
			title: '流浪地球',
			child: [
				'人类的勇气和坚毅必将被镌刻在星空之下。',
				'希望是像钻石一样珍贵的东西！',
				'希望，希望是我们唯一回家的方向。',
				'让人类永远保持理智，是一种奢求。',
				'道路千万条，安全第一条；行车不规范，亲人两行泪！',
				'那时候人们还没注意到太阳，人们更喜欢叫做钱的东西。',
				'为了我们的孩子，没有什么不能失去的了',
				'moss 没有叛逃！',
				'火石没了，我老婆孩子全他妈白死了！'
			]
		},
		{
			index: '仙',
			title: '仙剑奇侠传',
			child: [
				'既不回头，何必不忘。既然无缘，何必誓言。',
				'没有值得不值得，只有愿意不愿意。',
				'不曾得到，谈何放下。既已得到，又如何放下。',
				'轮回的是故人，不变的是初心！',
				'明夕何夕，君已陌路。',
				'我曾经也拥有过爱，只是，我放弃了。',
				'你以为每天看到的东西，就会抓得住吗？',
				'世有无情人，却有痴情妖。',
				'君子，小人，皆在一念思量。',
				'到家了，一定要叫醒我，我怕我醒不过来。',
				'如果得道就是牺牲所有人来成全自己，我宁愿执迷不悟。',
				'我们今日一别，让我们十年后再相见，不见不散！',
				'一杯愁绪，几段情缘，莫过，与君对酒当歌。'
			]
		}
	];
	const navHeight = 48;
	const bottomHeight = 50;
	const height = window.innerHeight - navHeight - bottomHeight;
	/**
	 * @type {'base' | 'full' | 'none'}
	 */
	let radius: 'middle' | 'full' | 'none' = $state('middle');
	let dataFlag = $state(0);
	let scrollAlign = $state(true);
	let injClassList: string[] = $state([]);
	const changeRadiusFun = () => {
		radius = radius === 'middle' ? 'full' : radius === 'full' ? 'none' : 'middle';
	};
	const changeListFun = () => {
		dataFlag = dataFlag === 0 ? 1 : dataFlag === 1 ? 2 : 0;
	};
	const changeScrollAlignFun = () => {
		scrollAlign = !scrollAlign;
	};
	const changeClassFun = () => {
		injClassList = !injClassList.length ? ['!text-3xl text-center', 'text-xs text-center !py-1'] : [];
	};
	let visible = $state(false);
	let toastObj = $state({ index: 0, group: { title: '' }, childIndex: 0, child: '' });
</script>

{#if dataFlag === 0}
	<IndexBar
		data={addressList}
		{radius}
		{height}
		{scrollAlign}
		titleInjClass={injClassList[0]}
		textInjClass={injClassList[1]}
		top={navHeight}
		onclickChild={(index, group, childIndex, child) => {
			toastObj = { index, group, childIndex, child };
			visible = true;
		}}
	/>
{:else if dataFlag === 1}
	<IndexBar
		data={emojiList}
		{radius}
		{height}
		{scrollAlign}
		titleInjClass={injClassList[0]}
		textInjClass={injClassList[1]}
		top={navHeight}
		onclickChild={(index, group, childIndex, child) => {
			toastObj = { index, group, childIndex, child };
			visible = true;
		}}
	/>
{:else}
	<IndexBar
		data={movieTVList}
		{radius}
		{height}
		{scrollAlign}
		titleInjClass={injClassList[0]}
		textInjClass={injClassList[1]}
		top={navHeight}
		onclickChild={(index, group, childIndex, child) => {
			toastObj = { index, group, childIndex, child };
			visible = true;
		}}
	/>
{/if}
<Toast
	bind:visible
	message={`Clicked ${toastObj.index + 1} group(${toastObj.group.title}) ${toastObj.childIndex + 1} item(${toastObj.child})`}
/>

<div class="sticky bottom-0 z-10 flex justify-between bg-white/90 px-2 dark:bg-black/90">
	<Button fill="lineTheme" size="auto" injClass="text-xs px-2" onclick={changeListFun}>Switch data</Button>
	<Button fill="lineTheme" size="auto" injClass="text-xs px-2" onclick={changeScrollAlignFun}>
		{scrollAlign ? 'open' : 'close'} Align
	</Button>
	<Button fill="lineTheme" size="auto" injClass="text-xs px-2" onclick={changeRadiusFun}>Switch rounded</Button>
	<Button fill="lineTheme" size="auto" injClass="text-xs px-2" onclick={changeClassFun}>Switch style</Button>
</div>



================================================
FILE: packages/stdf/src/routes/indexBar/zh_CN/+page.svelte
================================================
<!-- IndexBar Demo -->
<script lang="ts">
	import { IndexBar, Button, Toast } from '$lib/index.js';
	import type { IndexBarItemProps } from '$lib/types/index.js';

	const addressList: IndexBarItemProps[] = [
		{ index: 'A', title: 'A', child: ['澳门', '安宁', '安庆', '鞍山'] },
		{ index: 'B', title: 'B', child: ['北京', '保定', '包头', '宝鸡'] },
		{ index: 'C', title: 'C', child: ['承德', '沧州', '赤峰'] },
		{ index: 'D', title: 'D', child: ['大同', '大连', '大理'] },
		{ index: 'E', title: 'E', child: ['恩施', '鄂尔多斯', '峨眉山'] },
		{ index: 'F', title: 'F', child: ['抚顺', '佛山', '福泉'] },
		{ index: 'G', title: 'G', child: ['个旧', '桂林', '赣州'] },
		{ index: 'H', title: 'H', child: ['邯郸', '呼和浩特', '呼伦贝尔'] },
		{ index: 'J', title: 'J', child: ['吉林', '酒泉', '晋江'] },
		{ index: 'K', title: 'K', child: ['昆明', '昆山', '开封'] },
		{ index: 'L', title: 'L', child: ['拉萨', '兰州', '泸州'] },
		{ index: 'M', title: 'M', child: ['绵阳', '马鞍山', '牡丹江'] },
		{ index: 'N', title: 'N', child: ['南昌', '南京', '宁波'] },
		{ index: 'P', title: 'P', child: ['莆田', '攀枝花', '平顶山'] },
		{ index: 'Q', title: 'Q', child: ['曲靖', '青岛', '齐齐哈尔'] },
		{ index: 'R', title: 'R', child: ['瑞丽', '瑞安', '瑞金'] },
		{ index: 'S', title: 'S', child: ['三亚', '上海', '深圳'] },
		{ index: 'T', title: 'T', child: ['台州', '太原', '天津'] },
		{ index: 'W', title: 'W', child: ['武汉', '无锡', '芜湖'] },
		{ index: 'X', title: 'X', child: ['西安', '厦门', '宣威'] },
		{ index: 'Y', title: 'Y', child: ['义乌', '银川', '玉溪'] },
		{ index: 'Z', title: 'Z', child: ['昭通', '遵义', '张家界'] }
	];
	const emojiList: IndexBarItemProps[] = [
		{ index: '😀', title: '表情与情感', child: ['😂', '🥰', '🥱', '🧐'] },
		{ index: '👋', title: '人物与身体', child: ['👌', '🤝', '👨‍💻', '💪'] },
		{ index: '🐵', title: '动物与自然', child: ['🦄', '🌱', '🦁', '🐶'] },
		{ index: '🍎', title: '食物与饮料', child: ['🍑', '🍞', '🍽️', '🍩'] },
		{ index: '🌍', title: '旅行与地理', child: ['🏔️', '🚆', '✈️', '🛵'] },
		{ index: '🏆', title: '活动', child: ['⚽', '🎨', '🏀', '🧨'] },
		{ index: '📱', title: '物品', child: ['🎩', '💻', '🎒', '📖'] },
		{ index: '⚠️', title: '符号标志', child: ['🚫', '⚛️', '🛄', '🔱'] },
		{ index: '🏁', title: '旗帜', child: ['🇨🇳', '🇺🇸', '🇧🇻', '🇦🇹'] }
	];
	const movieTVList: IndexBarItemProps[] = [
		{
			index: '三',
			title: '三体',
			child: [
				'地球往事',
				'黑暗森林',
				'死神永生',
				'科学边界',
				'射手和农场主',
				'寂静的春天',
				'宇宙闪烁',
				'地球叛军',
				'古筝行动',
				'智子',
				'面壁者',
				'咒语',
				'黑暗森林',
				'危机纪元',
				'威慑纪元',
				'广播纪元',
				'掩体纪元',
				'银河纪元',
				'时间开始',
				'时间之外，我们的宇宙'
			]
		},
		{
			index: '流',
			title: '流浪地球',
			child: [
				'人类的勇气和坚毅必将被镌刻在星空之下。',
				'希望是像钻石一样珍贵的东西！',
				'希望，希望是我们唯一回家的方向。',
				'让人类永远保持理智，是一种奢求。',
				'道路千万条，安全第一条；行车不规范，亲人两行泪！',
				'那时候人们还没注意到太阳，人们更喜欢叫做钱的东西。',
				'为了我们的孩子，没有什么不能失去的了',
				'moss 没有叛逃！',
				'火石没了，我老婆孩子全他妈白死了！'
			]
		},
		{
			index: '仙',
			title: '仙剑奇侠传',
			child: [
				'既不回头，何必不忘。既然无缘，何必誓言。',
				'没有值得不值得，只有愿意不愿意。',
				'不曾得到，谈何放下。既已得到，又如何放下。',
				'轮回的是故人，不变的是初心！',
				'明夕何夕，君已陌路。',
				'我曾经也拥有过爱，只是，我放弃了。',
				'你以为每天看到的东西，就会抓得住吗？',
				'世有无情人，却有痴情妖。',
				'君子，小人，皆在一念思量。',
				'到家了，一定要叫醒我，我怕我醒不过来。',
				'如果得道就是牺牲所有人来成全自己，我宁愿执迷不悟。',
				'我们今日一别，让我们十年后再相见，不见不散！',
				'一杯愁绪，几段情缘，莫过，与君对酒当歌。'
			]
		}
	];
	const navHeight = 48;
	const bottomHeight = 50;
	const height = window.innerHeight - navHeight - bottomHeight;
	/**
	 * @type {'base' | 'full' | 'none'}
	 */
	let radius: 'middle' | 'full' | 'none' = $state('middle');
	let dataFlag = $state(0);
	let scrollAlign = $state(true);
	let injClassList: string[] = $state([]);
	const changeRadiusFun = () => {
		radius = radius === 'middle' ? 'full' : radius === 'full' ? 'none' : 'middle';
	};
	const changeListFun = () => {
		dataFlag = dataFlag === 0 ? 1 : dataFlag === 1 ? 2 : 0;
	};
	const changeScrollAlignFun = () => {
		scrollAlign = !scrollAlign;
	};
	const changeClassFun = () => {
		injClassList = !injClassList.length ? ['!text-3xl text-center', 'text-xs text-center !py-1'] : [];
	};
	let visible = $state(false);
	let toastObj = $state({ index: 0, group: { title: '' }, childIndex: 0, child: '' });
</script>

{#if dataFlag === 0}
	<IndexBar
		data={addressList}
		{radius}
		{height}
		{scrollAlign}
		titleInjClass={injClassList[0]}
		textInjClass={injClassList[1]}
		top={navHeight}
		onclickChild={(index, group, childIndex, child) => {
			toastObj = { index, group, childIndex, child };
			visible = true;
		}}
	/>
{:else if dataFlag === 1}
	<IndexBar
		data={emojiList}
		{radius}
		{height}
		{scrollAlign}
		titleInjClass={injClassList[0]}
		textInjClass={injClassList[1]}
		top={navHeight}
		onclickChild={(index, group, childIndex, child) => {
			toastObj = { index, group, childIndex, child };
			visible = true;
		}}
	/>
{:else}
	<IndexBar
		data={movieTVList}
		{radius}
		{height}
		{scrollAlign}
		titleInjClass={injClassList[0]}
		textInjClass={injClassList[1]}
		top={navHeight}
		onclickChild={(index, group, childIndex, child) => {
			toastObj = { index, group, childIndex, child };
			visible = true;
		}}
	/>
{/if}
<Toast
	bind:visible
	message={`点击了第 ${toastObj.index + 1} 组（${toastObj.group.title}）中的第 ${toastObj.childIndex + 1} 项（${toastObj.child}）`}
/>

<div class="sticky bottom-0 z-10 flex justify-between bg-white/90 px-2 dark:bg-black/90">
	<Button fill="lineTheme" size="auto" injClass="text-xs px-2" onclick={changeListFun}>切换数据</Button>
	<Button fill="lineTheme" size="auto" injClass="text-xs px-2" onclick={changeScrollAlignFun}>
		{scrollAlign ? '关闭' : '开启'}滚动对齐
	</Button>
	<Button fill="lineTheme" size="auto" injClass="text-xs px-2" onclick={changeRadiusFun}>切换圆角</Button>
	<Button fill="lineTheme" size="auto" injClass="text-xs px-2" onclick={changeClassFun}>切换样式</Button>
</div>



================================================
FILE: packages/stdf/src/routes/input/en_US/+page.svelte
================================================
<!-- Input Demo -->
<script lang="ts">
	import { Input, Button, Icon, Toast } from '$lib/index.js';

	let value = $state('Initial text');
	let visible = $state(false);

	let IdCard = $state('');

	// Get browser information to determine if it is a mobile device
	const isMobile = /Mobi|Android|iPhone/i.test(navigator.userAgent);

	let placeholderIdCard = $state('');
	$effect(() => {
		placeholderIdCard = IdCard === '' ? 'Please enter ID card number' : '';
	});
	const clickLabel4Fun = () => {
		placeholderIdCard = 'Recognition completed in 2 seconds......';
		setTimeout(() => {
			IdCard = '1234567890XXX-XX';
		}, 2000);
	};
	let mobileLength = $state(0);
	const changeStateFun = (v: string) => {
		mobileLength = v.length;
	};

	let mobileState: 'success' | 'theme' | 'error' = $derived(mobileLength === 11 ? 'success' : mobileLength === 0 ? 'theme' : 'error');

	// Key pressed
	let key = $state('');
</script>

<div class="px-4 pt-8 text-xl font-bold">Basic Usage</div>
<Input title="Text" />

<div class="px-4 pt-8 text-xl font-bold">Without Title</div>
<Input placeholder="Please enter text" />

<div class="px-4 pt-8 text-xl font-bold">Custom Placeholder</div>
<Input title="Text" placeholder="I am a custom placeholder" />

<div class="px-4 pt-8 text-xl font-bold">
	Different Input Types
	{#if !isMobile}
		<span class="ml-2 text-xs opacity-50">Please check keyboard types on mobile devices</span>
	{/if}
</div>
<Input title="Any Text (Regular Keyboard)" />
<Input title="Password" type="password" />
<Input title="Number (Any)" type="number" />
<Input title="Number (Integer)" type="numeric" />
<Input title="Number (Decimal Allowed)" type="decimal" />
<Input title="Number (Allow Negative)" type="number" negative />
<Input title="Email" type="email" />
<Input title="Phone Number" type="tel" />
<Input title="URL" type="url" />
<Input title="Search Content" type="search" />
<Input title="Text (No Virtual Keyboard)" type="none" />

<div class="px-4 pt-8 text-xl font-bold">Line Style</div>
<Input title="Text" inputStyle="line" />
<Input title="Text (Center Line Transition)" inputStyle="line" lineTransition="center" />
<Input title="Text (Left Line Transition)" inputStyle="line" lineTransition="left" />

<div class="px-4 pt-8 text-xl font-bold">Different Transition Times</div>
<Input title="Fast Transition" duration="fast" />
<Input title="Normal Transition" />
<Input title="Slower Transition" duration="slower" />
<Input title="Normal Line Transition" inputStyle="line" lineTransition="center" />
<Input title="Slower Line Transition" inputStyle="line" lineTransition="center" duration="slower" />

<div class="px-4 pt-8 text-xl font-bold">Different Title Positions</div>
<Input title="Title (External)" />
<Input title="Title (Internal)" titlePosition="in" />
<Input title="Title (None)" titlePosition={null} />

<div class="px-4 pt-8 text-xl font-bold">Different Input Text Positions</div>
<Input title="Text" />
<Input title="Text" inputPosition="right" />

<div class="px-4 pt-8 text-xl font-bold">Different Border Radius Styles</div>
<Input title="Text" />
<Input title="Text" radius="xl" />
<Input title="Text" radius="full" />
<Input title="Text" radius="none" />
<Input title="Line Style (Radius Invalid)" radius="full" inputStyle="line" />

<div class="px-4 pt-8 text-xl font-bold">Different Vertical Spacing</div>
<Input placeholder="Please enter text (Spacing 0)" py="0" inputStyle="line" />
<Input placeholder="Please enter text (Spacing 0)" py="0" inputStyle="line" />
<Input placeholder="Please enter text (Spacing 0)" py="0" inputStyle="line" />
<Input placeholder="Please enter text (Spacing 4)" py="4" inputStyle="line" />
<Input placeholder="Please enter text (Spacing 4)" py="4" inputStyle="line" />
<Input placeholder="Please enter text (Spacing 4)" py="4" inputStyle="line" />

<div class="px-4 pt-8 text-xl font-bold">With Clear Button</div>
<Input title="Text" clear />

<div class="px-4 pt-8 text-xl font-bold">Disabled</div>
<Input title="Text" disabled value="Disabled" />

<div class="px-4 pt-8 text-xl font-bold">Different States</div>
<Input title="Success" state="success" />
<Input title="Warning" state="warning" />
<Input title="Error" state="error" />
<Input title="Info" state="info" />
<Input title="Warning & Line" inputStyle="line" state="error" />
<Input title="Warning & Line & Animation" inputStyle="line" state="error" lineTransition="center" />
<Input
	title="Dynamic State Change"
	type="tel"
	placeholder="Please enter 11-digit phone number"
	maxlength={11}
	state={mobileState}
	onchange={changeStateFun}
/>

<div class="px-4 pt-8 text-xl font-bold">Left Icon</div>
<Input title="Password" type="password" label1={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} />
<Input
	title="Username"
	label1={{ name: 'ri-arrow-down-s-line', size: 16, alpha: 0.5 }}
	label3={{ name: 'ri-shield-user-line', size: 16, alpha: 0.5 }}
/>

<div class="px-4 pt-8 text-xl font-bold">Left Text</div>
<Input title="Account" label2="Account" />

<div class="px-4 pt-8 text-xl font-bold">Left Icon and Text</div>
<Input title="Password" type="password" label1={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} label2="Password" />

<div class="px-4 pt-8 text-xl font-bold">Left Text and Icon</div>
<Input title="Password" type="password" label2="Password" label3={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} />

<div class="px-4 pt-8 text-xl font-bold">Left Icon, Text, Icon</div>
<Input
	title="Password"
	type="password"
	label1={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
	label2="Password"
	label3={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
/>

<div class="px-4 pt-8 text-xl font-bold">Right Icon</div>
<Input title="ID Card" label4={{ name: 'ri-qr-scan-line', size: 16, alpha: 0.5 }} />
<Input
	title="Username"
	label4={{ name: 'ri-arrow-down-s-line', size: 16, alpha: 0.5 }}
	label6={{ name: 'ri-shield-user-line', size: 16, alpha: 0.5 }}
/>

<div class="px-4 pt-8 text-xl font-bold">Right Text</div>
<Input title="Amount" type="number" label5="Yuan" />

<div class="px-4 pt-8 text-xl font-bold">Right Icon and Text</div>
<Input title="Password" type="password" label4={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} label5="Password" />

<div class="px-4 pt-8 text-xl font-bold">Right Text and Icon</div>
<Input title="Password" type="password" label5="Password" label6={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} />

<div class="px-4 pt-8 text-xl font-bold">Right Icon, Text, Icon</div>
<Input
	title="Password"
	type="password"
	label4={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
	label5="Password"
	label6={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
/>

<div class="px-4 pt-8 text-xl font-bold">Left Text and Right Icon</div>
<Input label2="ID Card" label6={{ name: 'ri-qr-scan-line', size: 16, alpha: 0.5 }} placeholder="Please enter ID card number" />

<div class="px-4 pt-8 text-xl font-bold">All Six Items</div>
<Input
	title="Password"
	type="password"
	label1={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
	label2="Password"
	label3={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
	label4={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
	label5="Password"
	label6={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
/>

<div class="px-4 pt-8 text-xl font-bold">Tips and Data Items</div>
<Input title="Text" tip="Tip message" />
<Input title="Text" data1="Data item 1" />
<Input title="Text" data1="Data item 1" data2="Data item 2" />
<Input title="Text" data3="Data item 3" />
<Input title="Text" data1="Data item 1" tip="Tip message" />
<Input title="Text" data3="Data item 3" tip="Tip message" />

<div class="px-4 pt-8 text-xl font-bold">All Configurable Items</div>
<Input
	title="Title"
	placeholder="Please enter text"
	label1={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
	label2="Label 2"
	label3={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
	label4={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
	label5="Label 5"
	label6={{ name: 'ri-qr-scan-line', size: 16, alpha: 0.5 }}
	data1="Data item 1"
	data2="Data item 2"
	data3="Data item 3"
	tip="Tip message"
	clear
/>

<div class="px-4 pt-8 text-xl font-bold">label1 and label4 Using Snippet</div>
<Input title="Verification Code">
	{#snippet label1Child()}
		<div>
			<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16">
				<path
					d="M511.198384 637.07798c-17.170101 0-31.08202 13.911919-31.08202 31.08202v124.302222c0 17.157172 13.924848 31.08202 31.08202 31.08202s31.069091-13.924848 31.069091-31.08202v-124.302222c0-17.170101-13.911919-31.08202-31.069091-31.08202z m0 0"
					fill="#515151"
				/>
				<path
					d="M759.815758 513.331717V264.145455C759.815758 126.823434 648.520404 15.515152 511.198384 15.515152c-137.309091 0-248.630303 111.308283-248.630303 248.630303v249.186262C223.702626 565.20404 200.40404 629.423838 200.40404 699.229091c0 171.649293 139.145051 310.794343 310.794344 310.794343s310.794343-139.145051 310.794343-310.794343c0-69.805253-23.311515-134.025051-62.176969-185.897374zM324.719192 264.145455c0-102.994747 83.497374-186.479192 186.479192-186.479192 102.981818 0 186.466263 83.484444 186.466262 186.479192v186.88c-51.975758-39.111111-116.402424-62.577778-186.466262-62.577778s-134.490505 23.453737-186.479192 62.577778V264.145455z m186.479192 683.726868c-137.309091 0-248.630303-111.321212-248.630303-248.643232 0-137.309091 111.308283-248.617374 248.630303-248.617374 132.628687 0 248.617374 115.988687 248.617374 248.617374 0 137.32202-111.295354 248.643232-248.617374 248.643232z m0 0"
					fill="#515151"
				/>
			</svg>
		</div>
	{/snippet}
	{#snippet label4Child()}
		<div>
			<Button size="auto" heightOut="0" heightIn="1" fill="lineTheme">
				<div class="px-2">Get Code</div>
			</Button>
		</div>
	{/snippet}
</Input>

<div class="px-4 pt-8 text-xl font-bold">Dynamic Display</div>
<Input
	title="Dynamic label5"
	type="tel"
	placeholder="Please enter 11-digit phone number"
	maxlength={11}
	state={mobileState}
	onchange={changeStateFun}
>
	{#snippet label5Child()}
		<div>
			{#if mobileLength === 11}
				<Icon name="ri-check-fill" injClass="text-success" size={14} />
			{:else if mobileLength === 0}{:else}
				<Icon name="ri-close-fill" injClass="text-error" size={14} />
			{/if}
		</div>
	{/snippet}
</Input>

<div class="px-4 pt-8 text-xl font-bold">Bind Value</div>
<Input title="Text" bind:value />
<Button onclick={() => (visible = true)}>Show Current Value</Button>
<Toast bind:visible message={`Current input text: ${value}`} />

<div class="px-4 pt-8 text-xl font-bold">Click label4 Trigger Event</div>
<Input
	title="ID Card"
	placeholder={placeholderIdCard}
	bind:value={IdCard}
	label4={{ name: 'ri-qr-scan-line', size: 16, alpha: 0.5 }}
	onclickLabel4={clickLabel4Fun}
	clear
/>

<div class="px-4 pt-8 text-xl font-bold">Textarea</div>
<Input placeholder="Please enter content" type="textarea" />

<div class="px-4 pt-8 text-xl font-bold">Textarea Auto Height</div>
<Input placeholder="Please enter content" type="textarea" autosize />

<div class="px-4 pt-4 text-xl font-bold">Listen to Keydown Event</div>
<div class="px-4 pt-4">You pressed {key}</div>
<Input placeholder="Please enter content" onkeydown={(v) => (key = v)} />



================================================
FILE: packages/stdf/src/routes/input/zh_CN/+page.svelte
================================================
<!-- Input Demo -->
<script lang="ts">
	import { Input, Button, Icon, Toast } from '$lib/index.js';

	let value = $state('初始文本');
	let visible = $state(false);

	let IdCard = $state('');

	// 通过获取浏览器信息判断是否是移动设备
	const isMobile = /Mobi|Android|iPhone/i.test(navigator.userAgent);

	let placeholderIdCard = $state('');
	$effect(() => {
		placeholderIdCard = IdCard === '' ? '请输入身份证号' : '';
	});
	const clickLabel4Fun = () => {
		placeholderIdCard = '两秒后识别完毕......';
		setTimeout(() => {
			IdCard = '1234567890XXX-XX';
		}, 2000);
	};
	let mobileLength = $state(0);
	const changeStateFun = (v: string) => {
		mobileLength = v.length;
	};

	let mobileState: 'success' | 'theme' | 'error' = $derived(mobileLength === 11 ? 'success' : mobileLength === 0 ? 'theme' : 'error');

	// 按键 key
	let key = $state('');
</script>

<div class="px-4 pt-8 text-xl font-bold">基础用法</div>
<Input title="文本" />

<div class="px-4 pt-8 text-xl font-bold">不带标题</div>
<Input placeholder="请输入文本" />

<div class="px-4 pt-8 text-xl font-bold">自定义 placeholder</div>
<Input title="文本" placeholder="我是自定义的 placeholder" />

<div class="px-4 pt-8 text-xl font-bold">
	不同输入类型
	{#if !isMobile}
		<span class="ml-2 text-xs opacity-50">请在移动设备查看键盘类型</span>
	{/if}
</div>
<Input title="任意文本（常规键盘）" />
<Input title="密码" type="password" />
<Input title="数字（任意）" type="number" />
<Input title="数字（整数）" type="numeric" />
<Input title="数字（允许小数点）" type="decimal" />
<Input title="数字（允许负数）" type="number" negative />
<Input title="邮箱" type="email" />
<Input title="电话号码" type="tel" />
<Input title="链接地址" type="url" />
<Input title="搜索内容" type="search" />
<Input title="文本（不使用虚拟键盘）" type="none" />

<div class="px-4 pt-8 text-xl font-bold">线性风格</div>
<Input title="文本" inputStyle="line" />
<Input title="文本（线条居中过渡）" inputStyle="line" lineTransition="center" />
<Input title="文本（线条左侧过渡）" inputStyle="line" lineTransition="left" />

<div class="px-4 pt-8 text-xl font-bold">不同过渡时间</div>
<Input title="过渡快" duration="fast" />
<Input title="过渡正常" />
<Input title="过渡较慢" duration="slower" />
<Input title="线性过渡正常" inputStyle="line" lineTransition="center" />
<Input title="线性过渡较慢" inputStyle="line" lineTransition="center" duration="slower" />

<div class="px-4 pt-8 text-xl font-bold">不同标题位置</div>
<Input title="标题（外部）" />
<Input title="标题（内部）" titlePosition="in" />
<Input title="标题（无）" titlePosition={null} />

<div class="px-4 pt-8 text-xl font-bold">不同输入文字位置</div>
<Input title="文本" />
<Input title="文本" inputPosition="right" />

<div class="px-4 pt-8 text-xl font-bold">不同圆角风格</div>
<Input title="文本" />
<Input title="文本" radius="xl" />
<Input title="文本" radius="full" />
<Input title="文本" radius="none" />
<Input title="线性风格圆角无效" radius="full" inputStyle="line" />

<div class="px-4 pt-8 text-xl font-bold">不同垂直间距</div>
<Input placeholder="请输入文本（间距为 0）" py="0" inputStyle="line" />
<Input placeholder="请输入文本（间距为 0）" py="0" inputStyle="line" />
<Input placeholder="请输入文本（间距为 0）" py="0" inputStyle="line" />
<Input placeholder="请输入文本（间距为 4）" py="4" inputStyle="line" />
<Input placeholder="请输入文本（间距为 4）" py="4" inputStyle="line" />
<Input placeholder="请输入文本（间距为 4）" py="4" inputStyle="line" />

<div class="px-4 pt-8 text-xl font-bold">带清除</div>
<Input title="文本" clear />

<div class="px-4 pt-8 text-xl font-bold">禁用</div>
<Input title="文本" disabled value="已禁用" />

<div class="px-4 pt-8 text-xl font-bold">不同状态色</div>
<Input title="成功" state="success" />
<Input title="警告" state="warning" />
<Input title="错误" state="error" />
<Input title="信息" state="info" />
<Input title="警告&线性" inputStyle="line" state="error" />
<Input title="警告&线性&动画" inputStyle="line" state="error" lineTransition="center" />
<Input title="动态改变状态色" type="tel" placeholder="请输入11位手机号" maxlength={11} state={mobileState} onchange={changeStateFun} />

<div class="px-4 pt-8 text-xl font-bold">左侧带图标</div>
<Input title="密码" type="password" label1={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} />
<Input
	title="用户名"
	label1={{ name: 'ri-arrow-down-s-line', size: 16, alpha: 0.5 }}
	label3={{ name: 'ri-shield-user-line', size: 16, alpha: 0.5 }}
/>

<div class="px-4 pt-8 text-xl font-bold">左侧带文字</div>
<Input title="账号" label2="账号" />

<div class="px-4 pt-8 text-xl font-bold">左侧带图标与文字</div>
<Input title="密码" type="password" label1={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} label2="密码" />

<div class="px-4 pt-8 text-xl font-bold">左侧带文字与图标</div>
<Input title="密码" type="password" label2="密码" label3={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} />

<div class="px-4 pt-8 text-xl font-bold">左侧带图标、文字、图标</div>
<Input
	title="密码"
	type="password"
	label1={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
	label2="密码"
	label3={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
/>

<div class="px-4 pt-8 text-xl font-bold">右侧带图标</div>
<Input title="身份证号" label4={{ name: 'ri-qr-scan-line', size: 16, alpha: 0.5 }} />
<Input
	title="用户名"
	label4={{ name: 'ri-arrow-down-s-line', size: 16, alpha: 0.5 }}
	label6={{ name: 'ri-shield-user-line', size: 16, alpha: 0.5 }}
/>

<div class="px-4 pt-8 text-xl font-bold">右侧带文字</div>
<Input title="金额" type="number" label5="元" />

<div class="px-4 pt-8 text-xl font-bold">右侧带图标与文字</div>
<Input title="密码" type="password" label4={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} label5="密码" />

<div class="px-4 pt-8 text-xl font-bold">右侧带文字与图标</div>
<Input title="密码" type="password" label5="密码" label6={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} />

<div class="px-4 pt-8 text-xl font-bold">右侧带图标、文字、图标</div>
<Input
	title="密码"
	type="password"
	label4={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
	label5="密码"
	label6={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
/>

<div class="px-4 pt-8 text-xl font-bold">左侧带文字右侧带图标</div>
<Input label2="身份证号" label6={{ name: 'ri-qr-scan-line', size: 16, alpha: 0.5 }} placeholder="请输入身份证号" />

<div class="px-4 pt-8 text-xl font-bold">左右六项全带</div>
<Input
	title="密码"
	type="password"
	label1={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
	label2="密码"
	label3={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
	label4={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
	label5="密码"
	label6={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
/>

<div class="px-4 pt-8 text-xl font-bold">提示信息与数据项组合</div>
<Input title="文本" tip="提示信息" />
<Input title="文本" data1="数据项1" />
<Input title="文本" data1="数据项1" data2="数据项2" />
<Input title="文本" data3="数据项3" />
<Input title="文本" data1="数据项1" tip="提示信息" />
<Input title="文本" data3="数据项3" tip="提示信息" />

<div class="px-4 pt-8 text-xl font-bold">展示所有可配置项</div>
<Input
	title="标题"
	placeholder="请输入文本"
	label1={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
	label2="标签 2"
	label3={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
	label4={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
	label5="标签 5"
	label6={{ name: 'ri-qr-scan-line', size: 16, alpha: 0.5 }}
	data1="数据项 1"
	data2="数据项 2"
	data3="数据项 3"
	tip="提示信息"
	clear
/>

<div class="px-4 pt-8 text-xl font-bold">label1 和 label4 使用 Snippet</div>
<Input title="验证码">
	{#snippet label1Child()}
		<div>
			<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16">
				<path
					d="M511.198384 637.07798c-17.170101 0-31.08202 13.911919-31.08202 31.08202v124.302222c0 17.157172 13.924848 31.08202 31.08202 31.08202s31.069091-13.924848 31.069091-31.08202v-124.302222c0-17.170101-13.911919-31.08202-31.069091-31.08202z m0 0"
					fill="#515151"
				/>
				<path
					d="M759.815758 513.331717V264.145455C759.815758 126.823434 648.520404 15.515152 511.198384 15.515152c-137.309091 0-248.630303 111.308283-248.630303 248.630303v249.186262C223.702626 565.20404 200.40404 629.423838 200.40404 699.229091c0 171.649293 139.145051 310.794343 310.794344 310.794343s310.794343-139.145051 310.794343-310.794343c0-69.805253-23.311515-134.025051-62.176969-185.897374zM324.719192 264.145455c0-102.994747 83.497374-186.479192 186.479192-186.479192 102.981818 0 186.466263 83.484444 186.466262 186.479192v186.88c-51.975758-39.111111-116.402424-62.577778-186.466262-62.577778s-134.490505 23.453737-186.479192 62.577778V264.145455z m186.479192 683.726868c-137.309091 0-248.630303-111.321212-248.630303-248.643232 0-137.309091 111.308283-248.617374 248.630303-248.617374 132.628687 0 248.617374 115.988687 248.617374 248.617374 0 137.32202-111.295354 248.643232-248.617374 248.643232z m0 0"
					fill="#515151"
				/>
			</svg>
		</div>
	{/snippet}
	{#snippet label4Child()}
		<div>
			<Button size="auto" heightOut="0" heightIn="1" fill="lineTheme">
				<div class="px-2">获取验证码</div>
			</Button>
		</div>
	{/snippet}
</Input>

<div class="px-4 pt-8 text-xl font-bold">动态显示</div>
<Input title="动态显示 label5" type="tel" placeholder="请输入11位手机号" maxlength={11} state={mobileState} onchange={changeStateFun}>
	{#snippet label5Child()}
		<div>
			{#if mobileLength === 11}
				<Icon name="ri-check-fill" injClass="text-success" size={14} />
			{:else if mobileLength === 0}{:else}
				<Icon name="ri-close-fill" injClass="text-error" size={14} />
			{/if}
		</div>
	{/snippet}
</Input>

<div class="px-4 pt-8 text-xl font-bold">绑定 value</div>
<Input title="文本" bind:value />
<Button onclick={() => (visible = true)}>显示当前值</Button>
<Toast bind:visible message={`当前输入文本：${value}`} />

<div class="px-4 pt-8 text-xl font-bold">点击 label4 触发事件</div>
<Input
	title="身份证号"
	placeholder={placeholderIdCard}
	bind:value={IdCard}
	label4={{ name: 'ri-qr-scan-line', size: 16, alpha: 0.5 }}
	onclickLabel4={clickLabel4Fun}
	clear
/>

<div class="px-4 pt-8 text-xl font-bold">textarea</div>
<Input placeholder="请输入内容" type="textarea" />

<div class="px-4 pt-8 text-xl font-bold">textarea 自动高度</div>
<Input placeholder="请输入内容" type="textarea" autosize />

<div class="px-4 pt-4 text-xl font-bold">监听 keydown 事件</div>
<div class="px-4 pt-4">你按下了 {key}</div>
<Input placeholder="请输入内容" onkeydown={(v) => (key = v)} />



================================================
FILE: packages/stdf/src/routes/loading/en_US/+page.svelte
================================================
<!--Loading Demo-->
<script lang="ts">
	import { Loading, Tabs, TabContent, Button } from '$lib/index.js';

	//Input the number and return an array of randomly generated colors
	const randomColorArr = (num: number) => {
		// Generate a random hexadecimal color
		const randomColor = () => '#' + ('00000' + ((Math.random() * 0x1000000) << 0).toString(16)).slice(-6);
		let arr = [];
		for (let i = 0; i < num; i++) {
			arr.push(randomColor());
		}
		return arr;
	};

	const arr1 = new Array(54);
	const arr2 = new Array(6);
	const arr4 = new Array(4);
	const labels = [{ text: 'One color' }, { text: 'Two color' }, { text: 'Four color' }, { text: 'Other' }];

	const speedBtns = [0.5, 1, 2];
	let speed = $state(1);
</script>

<div class="py-4">
	<Tabs tab={{ labels }}>
		<TabContent>
			<div class="py-4">
				<div class="flex text-center text-sm font-bold">
					{#each ['Default', 'Theme', 'Custom', 'Inverse', 'Inv theme'] as item}
						<div class="flex-1 border border-black/5 py-2 dark:border-white/5">{item}</div>
					{/each}
				</div>
				<div class="grid grid-cols-5">
					<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
					{#each arr1 as _, i}
						<div class="flex w-full flex-col items-center border border-black/5 py-6 dark:border-white/5">
							<div class="h-8 w-8">
								<Loading type={'1_' + i} bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'1_' + i}</div>
						</div>
						<div class="flex w-full flex-col items-center border border-black/5 py-6 dark:border-white/5">
							<div class="h-8 w-8">
								<Loading type={'1_' + i} theme bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'1_' + i}</div>
						</div>
						<div class="flex w-full flex-col items-center border border-black/5 py-6 dark:border-white/5">
							<div class="h-8 w-8">
								<Loading type={'1_' + i} theme customColor={randomColorArr(1)} bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'1_' + i}</div>
						</div>
						<div
							class="bg-darkBlack dark:bg-darkWhite flex w-full flex-col items-center border border-white/5 py-6 text-white dark:border-black/5 dark:text-black"
						>
							<div class="h-8 w-8">
								<Loading type={'1_' + i} inverse bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'1_' + i}</div>
						</div>
						<div
							class="bg-darkBlack dark:bg-darkWhite flex w-full flex-col items-center border border-white/5 py-6 text-white dark:border-black/5 dark:text-black"
						>
							<div class="h-8 w-8">
								<Loading type={'1_' + i} theme inverse bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'1_' + i}</div>
						</div>
					{/each}
				</div>
			</div>
			<div class="p-4 text-xs">Continually updated...</div>
		</TabContent>
		<TabContent>
			<div class="py-4">
				<div class="flex text-center text-sm font-bold">
					{#each ['Default', 'Custom', 'Inverse'] as item}
						<div class="flex-1 border border-black/5 py-2 dark:border-white/5">{item}</div>
					{/each}
				</div>
				<div class="grid grid-cols-3">
					<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
					{#each arr2 as _, i}
						<div class="flex w-full flex-col items-center border border-black/5 py-6 dark:border-white/5">
							<div class="h-8 w-8">
								<Loading type={'2_' + i} bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'2_' + i}</div>
						</div>
						<div class="flex w-full flex-col items-center border border-black/5 py-6 dark:border-white/5">
							<div class="h-8 w-8">
								<Loading type={'2_' + i} customColor={randomColorArr(2)} bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'2_' + i}</div>
						</div>
						<div
							class="bg-darkBlack dark:bg-darkWhite flex w-full flex-col items-center border border-white/5 py-6 text-white dark:border-black/5 dark:text-black"
						>
							<div class="h-8 w-8">
								<Loading type={'2_' + i} inverse bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'2_' + i}</div>
						</div>
					{/each}
				</div>
			</div>
			<div class="p-4 text-xs">Continually updated...</div>
		</TabContent>
		<TabContent>
			<div class="py-4">
				<div class="flex text-center text-sm font-bold">
					{#each ['Default', 'Custom', 'Default', 'Custom'] as item}
						<div class="flex-1 border border-black/5 py-2 dark:border-white/5">{item}</div>
					{/each}
				</div>
				<div class="grid grid-cols-4">
					<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
					{#each arr4 as _, i}
						<div class="flex w-full flex-col items-center border border-black/5 py-6 dark:border-white/5">
							<div class="h-8 w-8">
								<Loading type={'4_' + i} bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'4_' + i}</div>
						</div>
						<div class="flex w-full flex-col items-center border border-black/5 py-6 dark:border-white/5">
							<div class="h-8 w-8">
								<Loading type={'4_' + i} customColor={randomColorArr(4)} bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'4_' + i}</div>
						</div>
					{/each}
				</div>
			</div>
			<div class="p-4 text-xs">Continually updated...</div>
		</TabContent>
		<TabContent>
			<div class="py-4"></div>
			<div class="p-4 text-xs">Continually updated...</div>
		</TabContent>
	</Tabs>
</div>
<!-- The button group fixed at the bottom, control speed -->
<div class="sticky bottom-0 left-0 z-10 flex w-full justify-between gap-3 bg-white/60 px-2 backdrop-blur-sm dark:bg-black/60">
	{#each speedBtns as item}
		<div class="flex-1">
			<Button fill={speed === item ? 'base' : 'lineTheme'} size="full" injClass="text-xs px-2" onclick={() => (speed = item)}>
				{item}x speed
			</Button>
		</div>
	{/each}
</div>



================================================
FILE: packages/stdf/src/routes/loading/zh_CN/+page.svelte
================================================
<!--Loading Demo-->
<script lang="ts">
	import { Loading, Tabs, TabContent, Button } from '$lib/index.js';

	//传入个数，返回随机生成的颜色数组
	const randomColorArr = (num: number) => {
		//随机生成 16 进制颜色
		const randomColor = () => '#' + ('00000' + ((Math.random() * 0x1000000) << 0).toString(16)).slice(-6);
		let arr = [];
		for (let i = 0; i < num; i++) {
			arr.push(randomColor());
		}
		return arr;
	};

	const arr1 = new Array(54);
	const arr2 = new Array(6);
	const arr4 = new Array(4);
	const labels = [{ text: '单色' }, { text: '双色' }, { text: '四色' }, { text: '其他' }];

	const speedBtns = [0.5, 1, 2];
	let speed = $state(1);
</script>

<div class="py-4">
	<Tabs tab={{ labels }}>
		<TabContent>
			<div class="py-4">
				<div class="flex text-center text-sm font-bold">
					{#each ['默认色', '主题色', '自选色', '反差色', '反主色'] as item}
						<div class="flex-1 border border-black/5 py-2 dark:border-white/5">{item}</div>
					{/each}
				</div>
				<div class="grid grid-cols-5">
					<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
					{#each arr1 as _, i}
						<div class="flex w-full flex-col items-center border border-black/5 py-6 dark:border-white/5">
							<div class="h-8 w-8">
								<Loading type={'1_' + i} bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'1_' + i}</div>
						</div>
						<div class="flex w-full flex-col items-center border border-black/5 py-6 dark:border-white/5">
							<div class="h-8 w-8">
								<Loading type={'1_' + i} theme bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'1_' + i}</div>
						</div>
						<div class="flex w-full flex-col items-center border border-black/5 py-6 dark:border-white/5">
							<div class="h-8 w-8">
								<Loading type={'1_' + i} theme customColor={randomColorArr(1)} bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'1_' + i}</div>
						</div>
						<div
							class="bg-darkBlack dark:bg-darkWhite flex w-full flex-col items-center border border-white/5 py-6 text-white dark:border-black/5 dark:text-black"
						>
							<div class="h-8 w-8">
								<Loading type={'1_' + i} inverse bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'1_' + i}</div>
						</div>
						<div
							class="bg-darkBlack dark:bg-darkWhite flex w-full flex-col items-center border border-white/5 py-6 text-white dark:border-black/5 dark:text-black"
						>
							<div class="h-8 w-8">
								<Loading type={'1_' + i} theme inverse bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'1_' + i}</div>
						</div>
					{/each}
				</div>
			</div>
			<div class="p-4 text-xs">持续更新...</div>
		</TabContent>
		<TabContent>
			<div class="py-4">
				<div class="flex text-center text-sm font-bold">
					{#each ['默认色', '自选色', '反差色'] as item}
						<div class="flex-1 border border-black/5 py-2 dark:border-white/5">{item}</div>
					{/each}
				</div>
				<div class="grid grid-cols-3">
					<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
					{#each arr2 as _, i}
						<div class="flex w-full flex-col items-center border border-black/5 py-6 dark:border-white/5">
							<div class="h-8 w-8">
								<Loading type={'2_' + i} bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'2_' + i}</div>
						</div>
						<div class="flex w-full flex-col items-center border border-black/5 py-6 dark:border-white/5">
							<div class="h-8 w-8">
								<Loading type={'2_' + i} customColor={randomColorArr(2)} bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'2_' + i}</div>
						</div>
						<div
							class="bg-darkBlack dark:bg-darkWhite flex w-full flex-col items-center border border-white/5 py-6 text-white dark:border-black/5 dark:text-black"
						>
							<div class="h-8 w-8">
								<Loading type={'2_' + i} inverse bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'2_' + i}</div>
						</div>
					{/each}
				</div>
			</div>
			<div class="p-4 text-xs">持续更新...</div>
		</TabContent>
		<TabContent>
			<div class="py-4">
				<div class="flex text-center text-sm font-bold">
					{#each ['默认色', '自选色', '默认色', '自选色'] as item}
						<div class="flex-1 border border-black/5 py-2 dark:border-white/5">{item}</div>
					{/each}
				</div>
				<div class="grid grid-cols-4">
					<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
					{#each arr4 as _, i}
						<div class="flex w-full flex-col items-center border border-black/5 py-6 dark:border-white/5">
							<div class="h-8 w-8">
								<Loading type={'4_' + i} bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'4_' + i}</div>
						</div>
						<div class="flex w-full flex-col items-center border border-black/5 py-6 dark:border-white/5">
							<div class="h-8 w-8">
								<Loading type={'4_' + i} customColor={randomColorArr(4)} bind:speed />
							</div>
							<div class="mt-8 text-center text-xs">{'4_' + i}</div>
						</div>
					{/each}
				</div>
			</div>
			<div class="p-4 text-xs">持续更新...</div>
		</TabContent>
		<TabContent>
			<div class="py-4"></div>
			<div class="p-4 text-xs">持续更新...</div>
		</TabContent>
	</Tabs>
</div>
<!-- 固定在底部的按钮组，控制速度 -->
<div class="sticky bottom-0 left-0 z-10 flex w-full justify-between gap-3 bg-white/60 px-2 backdrop-blur-sm dark:bg-black/60">
	{#each speedBtns as item}
		<div class="flex-1">
			<Button fill={speed === item ? 'base' : 'lineTheme'} size="full" injClass="text-xs px-2" onclick={() => (speed = item)}>
				{item} 倍速
			</Button>
		</div>
	{/each}
</div>



================================================
FILE: packages/stdf/src/routes/mask/en_US/+page.svelte
================================================
<!-- Mask Demo -->
<script lang="ts">
	import { Mask, Toast, Cell, Button, Popup } from '$lib/index.js';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);

	let isClick = $state(false);
</script>

<div class="py-4">
	<Cell title="Basic usage" onclick={() => (visible1 = true)} />
	<Mask visible={visible1} onclickMask={() => (visible1 = false)} />

	<Cell title="Transparency is 0.1" onclick={() => (visible2 = true)} />
	<Mask visible={visible2} opacity="0.1" onclickMask={() => (visible2 = false)} />

	<Cell title="Transparency is 0.8" onclick={() => (visible3 = true)} />
	<Mask visible={visible3} opacity="0.8" onclickMask={() => (visible3 = false)} />

	<Cell title="Click through" detail="Please close manually" onclick={() => (visible4 = true)} />
	<Mask visible={visible4} clickable />
	<div class="flex">
		<div class="flex-1"><Button onclick={() => (isClick = !isClick)}>{isClick ? 'Click on me' : 'Click through'}</Button></div>
		<div class="flex-1"><Button onclick={() => (visible4 = false)}>Manual shutdown</Button></div>
	</div>

	<Cell title="Reverse color mask" onclick={() => (visible5 = true)} />
	<Mask visible={visible5} inverse onclickMask={() => (visible5 = false)} />

	<Cell title="Blur mask" onclick={() => (visible6 = true)} />
	<Mask visible={visible6} backdropBlur="xs" opacity="0" onclickMask={() => (visible6 = false)} />

	<Cell title="Increase ambiguity" onclick={() => (visible7 = true)} />
	<Mask visible={visible7} backdropBlur="xl" opacity="0" onclickMask={() => (visible7 = false)} />

	<Cell title="Increased the animation time" onclick={() => (visible8 = true)} />
	<Mask visible={visible8} duration={1000} onclickMask={() => (visible8 = false)} />

	<Cell title="Increased the duration of vanishing animation" onclick={() => (visible9 = true)} />
	<Mask visible={visible9} outDuration={1000} onclickMask={() => (visible9 = false)} />

	<Cell title="Toast Use in" onclick={() => (visible10 = true)} />
	<Toast bind:visible={visible10} message="Transparency is 0" />

	<Cell title="Popup Use in" onclick={() => (visible11 = true)} />
	<Popup bind:visible={visible11} />
</div>



================================================
FILE: packages/stdf/src/routes/mask/zh_CN/+page.svelte
================================================
<!-- Mask Demo -->
<script lang="ts">
	import { Mask, Toast, Cell, Button, Popup } from '$lib/index.js';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);

	let isClick = $state(false);
</script>

<div class="py-4">
	<Cell title="基础用法" onclick={() => (visible1 = true)} />
	<Mask visible={visible1} onclickMask={() => (visible1 = false)} />

	<Cell title="透明度为 0.1" onclick={() => (visible2 = true)} />
	<Mask visible={visible2} opacity="0.1" onclickMask={() => (visible2 = false)} />

	<Cell title="透明度为 0.8" onclick={() => (visible3 = true)} />
	<Mask visible={visible3} opacity="0.8" onclickMask={() => (visible3 = false)} />

	<Cell title="点击穿透" detail="请手动关闭" onclick={() => (visible4 = true)} />
	<Mask visible={visible4} clickable />
	<div class="flex">
		<div class="flex-1"><Button onclick={() => (isClick = !isClick)}>{isClick ? '已经点到我了' : '测试点击穿透'}</Button></div>
		<div class="flex-1"><Button onclick={() => (visible4 = false)}>手动关闭</Button></div>
	</div>

	<Cell title="反色遮罩" onclick={() => (visible5 = true)} />
	<Mask visible={visible5} inverse onclickMask={() => (visible5 = false)} />

	<Cell title="模糊遮罩" onclick={() => (visible6 = true)} />
	<Mask visible={visible6} backdropBlur="xs" opacity="0" onclickMask={() => (visible6 = false)} />

	<Cell title="加大模糊度" onclick={() => (visible7 = true)} />
	<Mask visible={visible7} backdropBlur="xl" opacity="0" onclickMask={() => (visible7 = false)} />

	<Cell title="增加出现动画时长" onclick={() => (visible8 = true)} />
	<Mask visible={visible8} duration={1000} onclickMask={() => (visible8 = false)} />

	<Cell title="增加消失动画时长" onclick={() => (visible9 = true)} />
	<Mask visible={visible9} outDuration={1000} onclickMask={() => (visible9 = false)} />

	<Cell title="Toast 中使用" onclick={() => (visible10 = true)} />
	<Toast bind:visible={visible10} message="透明度为 0" />

	<Cell title="Popup 中使用" onclick={() => (visible11 = true)} />
	<Popup bind:visible={visible11} />
</div>



================================================
FILE: packages/stdf/src/routes/modal/en_US/+page.svelte
================================================
<!-- Modal Demo -->
<script lang="ts">
	import { Modal, Cell, Toast } from '$lib/index.js';
	import Aphorism from '../../components/Aphorism.svelte';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);
	let visible15 = $state(false);

	let toastVisible = $state(false);

	$effect(() => {
		if (visible15) {
			setTimeout(() => {
				visible15 = false;
			}, 3000);
		}
	});
</script>

<div class="py-4">
	<Cell title="Basic usage" onclick={() => (visible1 = true)} />
	<Modal bind:visible={visible1} title="Do you understand?" content="Those who stay will suffer the most" btnText="I see" />

	<Cell title="Content usage Snippet" onclick={() => (visible2 = true)} />
	<Modal bind:visible={visible2}>
		{#snippet contentChild()}
			<Aphorism num={1} compact />
		{/snippet}
	</Modal>

	<Cell title="Do not show the title" onclick={() => (visible3 = true)} />
	<Modal bind:visible={visible3} title="" />

	<Cell title="Do not show button" onclick={() => (visible4 = true)} />
	<Modal bind:visible={visible4} showBtn={false}>
		{#snippet contentChild()}
			<Aphorism num={1} compact />
		{/snippet}
	</Modal>

	<Cell title="Click the mask to close" onclick={() => (visible5 = true)} />
	<Modal bind:visible={visible5} popup={{ maskClosable: true }} />

	<Cell title="Custom icon" onclick={() => (visible6 = true)} />
	<Modal
		bind:visible={visible6}
		content="Please wear a mask!"
		showIcon
		icon={{ name: 'ri-surgical-mask-fill', size: 40, injClass: 'text-[#48a1b4]' }}
	/>

	<Cell title="Error status button" onclick={() => (visible8 = true)} />
	<Modal bind:visible={visible8} btnText="I was wrong." button={{ state: 'error' }} />

	<Cell title="Full rounded corner button" onclick={() => (visible9 = true)} />
	<Modal bind:visible={visible9} button={{ radius: 'full' }} />

	<Cell title="Theme color plain text button" onclick={() => (visible12 = true)} />
	<Modal bind:visible={visible12} button={{ fill: 'textTheme' }} />

	<Cell title="Content uses Snippet and scrolls" onclick={() => (visible10 = true)} />
	<Modal bind:visible={visible10}>
		{#snippet contentChild()}
			<div class="h-56 overflow-auto">
				<Aphorism num={6} compact />
			</div>
		{/snippet}
	</Modal>

	<Cell title="Show narrow" onclick={() => (visible7 = true)} />
	<Modal bind:visible={visible7} popup={{ px: '20' }} />

	<Cell title="Another animation effect" onclick={() => (visible11 = true)} />
	<Modal bind:visible={visible11} content="Rebound transition" popup={{ easeType: 'backOut' }} />

	<Cell title="Listening shutdown event" onclick={() => (visible13 = true)} />
	<Modal bind:visible={visible13} onclose={() => (toastVisible = true)} />
	<Toast bind:visible={toastVisible} message="Shut down Modal！" />

	<Cell title="Heading left" onclick={() => (visible14 = true)} />
	<Modal bind:visible={visible14} title="Heading left" titleAlign="left" />

	<Cell title="Automatic shutdown" onclick={() => (visible15 = true)} />
	<Modal bind:visible={visible15} content="Don't move! I'll be gone in three seconds!" />
</div>

<!-- Aphorism.svelte -->
<!-- 
<script lang="ts">
	// 引入数据
	// import data
	import aphorisms from '../../data/aphorisms';

	/**
	 * @typedef {Object} Props
	 * @property {number} [num] - number of items to display
	 * @property {boolean} [compact] - whether to use compact mode
	 */
	/** @type {Props} */
	let { num = 0, compact = false } = $props();

	// 从 aphorisms 随机取出 num 条数据
	// get num items from aphorisms randomly
	const aphorismsList = aphorisms.sort(() => Math.random() - 0.5).slice(0, num);
</script>

<div class="{compact ? '' : 'px-4 py-8 '}divide-y divide-black/5 dark:divide-white/5">
	{#each aphorismsList as item}
		<div class:py-6={num > 1}>
			<div class="text-sm text-justify">{item.text}</div>
			<div class="text-right mt-1" class:italic={item.fromItalic}>{item.from}</div>
		</div>
	{/each}
</div>
-->



================================================
FILE: packages/stdf/src/routes/modal/zh_CN/+page.svelte
================================================
<!-- Modal Demo -->
<script lang="ts">
	import { Modal, Cell, Toast } from '$lib/index.js';
	import Aphorism from '../../components/Aphorism.svelte';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);
	let visible15 = $state(false);

	let toastVisible = $state(false);

	$effect(() => {
		if (visible15) {
			setTimeout(() => {
				visible15 = false;
			}, 3000);
		}
	});
</script>

<div class="py-4">
	<Cell title="基础用法" onclick={() => (visible1 = true)} />
	<Modal bind:visible={visible1} title="您明白吗？" content="留下来的人才是最痛苦的" btnText="我明白了" />

	<Cell title="内容使用 Snippet" onclick={() => (visible2 = true)} />
	<Modal bind:visible={visible2}>
		{#snippet contentChild()}
			<Aphorism num={1} compact />
		{/snippet}
	</Modal>

	<Cell title="不显示标题" onclick={() => (visible3 = true)} />
	<Modal bind:visible={visible3} title="" />

	<Cell title="不显示按钮" onclick={() => (visible4 = true)} />
	<Modal bind:visible={visible4} showBtn={false}>
		{#snippet contentChild()}
			<Aphorism num={1} compact />
		{/snippet}
	</Modal>

	<Cell title="点击遮罩关闭" onclick={() => (visible5 = true)} />
	<Modal bind:visible={visible5} popup={{ maskClosable: true }} />

	<Cell title="自定义图标" onclick={() => (visible6 = true)} />
	<Modal
		bind:visible={visible6}
		content="请佩戴口罩！"
		showIcon
		icon={{ name: 'ri-surgical-mask-fill', size: 40, injClass: 'text-[#48a1b4]' }}
	/>

	<Cell title="错误状态按钮" onclick={() => (visible8 = true)} />
	<Modal bind:visible={visible8} btnText="我错了" button={{ state: 'error' }} />

	<Cell title="全圆角按钮" onclick={() => (visible9 = true)} />
	<Modal bind:visible={visible9} button={{ radius: 'full' }} />

	<Cell title="主题色纯文本按钮" onclick={() => (visible12 = true)} />
	<Modal bind:visible={visible12} button={{ fill: 'textTheme' }} />

	<Cell title="内容使用 Snippet 且滚动" onclick={() => (visible10 = true)} />
	<Modal bind:visible={visible10}>
		{#snippet contentChild()}
			<div class="h-56 overflow-auto">
				<Aphorism num={6} compact />
			</div>
		{/snippet}
	</Modal>

	<Cell title="显示窄一点" onclick={() => (visible7 = true)} />
	<Modal bind:visible={visible7} popup={{ px: '20' }} />

	<Cell title="另一种动画效果" onclick={() => (visible11 = true)} />
	<Modal bind:visible={visible11} content="回弹过渡" popup={{ easeType: 'backOut' }} />

	<Cell title="监听关闭事件" onclick={() => (visible13 = true)} />
	<Modal bind:visible={visible13} onclose={() => (toastVisible = true)} />
	<Toast bind:visible={toastVisible} message="关闭了 Modal！" />

	<Cell title="标题居左" onclick={() => (visible14 = true)} />
	<Modal bind:visible={visible14} title="标题居左" titleAlign="left" />

	<Cell title="自动关闭" onclick={() => (visible15 = true)} />
	<Modal bind:visible={visible15} content="别动！3 秒后我立即消失！" />
</div>

<!-- Aphorism.svelte -->
<!-- 
<script lang=""ts>
	// 引入数据
	// import data
	import aphorisms from '../../data/aphorisms';

	/**
	 * @typedef {Object} Props
	 * @property {number} [num] - number of items to display
	 * @property {boolean} [compact] - whether to use compact mode
	 */
	/** @type {Props} */
	let { num = 0, compact = false } = $props();

	// 从 aphorisms 随机取出 num 条数据
	// get num items from aphorisms randomly
	const aphorismsList = aphorisms.sort(() => Math.random() - 0.5).slice(0, num);
</script>

<div class="{compact ? '' : 'px-4 py-8 '}divide-y divide-black/5 dark:divide-white/5">
	{#each aphorismsList as item}
		<div class:py-6={num > 1}>
			<div class="text-sm text-justify">{item.text}</div>
			<div class="text-right mt-1" class:italic={item.fromItalic}>{item.from}</div>
		</div>
	{/each}
</div>
-->



================================================
FILE: packages/stdf/src/routes/navBar/en_US/+page.svelte
================================================
<!-- NavBar Demo -->
<script lang="ts">
	import { NavBar, Icon, Toast } from '$lib/index.js';

	const icons1 = [{ name: 'ri-paint-brush-line', theme: true }, { name: 'ri-share-line' }];
	const icons2 = [{ name: 'ri-command-line' }, { name: 'ri-drag-move-line' }];
	const icons3 = [{ name: 'ri-indent-decrease' }, { name: 'ri-service-line' }];
	const icons4 = [{ name: 'ri-hand-heart-line', theme: true }, { name: 'ri-parent-line' }];

	let visible1 = $state(false);
	let visible2 = $state(false);
	let rightIndex = $state(0);
	let visible3 = $state(false);
</script>

<div class="flex flex-col space-y-8 py-8">
	<NavBar title="Basic usage" />
	<NavBar title="Use Icon on the right side" rights={icons1} />
	<NavBar title="Title centered" titleAlign="center" rights={[{ name: 'ri-command-line' }]} />
	<NavBar title="Click on the left" onclickLeft={() => (visible1 = true)} />
	<Toast bind:visible={visible1} message="Clicked on the left!" />
	<NavBar
		title="Click on the right"
		rights={icons2}
		onclickRight={(index) => {
			visible2 = true;
			rightIndex = index;
		}}
	/>
	<Toast bind:visible={visible2} message={`The index of the clicked right icon is ${rightIndex}.`} />
	<NavBar title="No left and bottom dividers, long text" left={null} line={false} rights={icons3} />
	<NavBar title="Custom background color by injClass" injClass="!bg-[#e0e0e0] dark:!bg-[green]" />
	<NavBar>
		{#snippet titleChild()}
			<div class="text-[red] dark:text-[green]">Custom text color by Snippet</div>
		{/snippet}
	</NavBar>
	<NavBar>
		{#snippet titleChild()}
			<div class="flex h-12 flex-col justify-around text-xs">
				<div class="text-sm">title Snippet renders</div>
				<div>right Snippet renders</div>
			</div>
		{/snippet}
		{#snippet rightChild()}
			<div>
				<button class="text-primary dark:text-dark h-12 w-12 cursor-pointer text-center" onclick={() => (visible3 = true)}>Hello</button>
			</div>
		{/snippet}
	</NavBar>
	<Toast bind:visible={visible3} message="Clicked on the right Snippet content!" />
	<NavBar title="Love version" love rights={icons4} />
	<NavBar injClass="!bg-transparent" line={false}>
		{#snippet leftChild()}
			<div class="m-2 h-8 w-8 rounded-full bg-white text-center leading-8 dark:bg-black/50">
				<Icon name="ri-home-7-line" size={18} top={-2} />
			</div>
		{/snippet}
		{#snippet titleChild()}
			<div class="my-2 h-8 rounded-full bg-white px-3 text-sm leading-8 dark:bg-black/50">custom styles by injClass and Snippet</div>
		{/snippet}
		{#snippet rightChild()}
			<div class="m-2 h-8 w-8 rounded-full bg-white text-center leading-8 dark:bg-black/50">
				<Icon name="ri-customer-service-2-line" size={18} top={-2} />
			</div>
		{/snippet}
	</NavBar>
</div>



================================================
FILE: packages/stdf/src/routes/navBar/zh_CN/+page.svelte
================================================
<!-- NavBar Demo -->
<script lang="ts">
	import { NavBar, Icon, Toast } from '$lib/index.js';

	const icons1 = [{ name: 'ri-paint-brush-line', theme: true }, { name: 'ri-share-line' }];
	const icons2 = [{ name: 'ri-command-line' }, { name: 'ri-drag-move-line' }];
	const icons3 = [{ name: 'ri-indent-decrease' }, { name: 'ri-service-line' }];
	const icons4 = [{ name: 'ri-hand-heart-line', theme: true }, { name: 'ri-parent-line' }];

	let visible1 = $state(false);
	let visible2 = $state(false);
	let rightIndex = $state(0);
	let visible3 = $state(false);
</script>

<div class="flex flex-col space-y-8 py-8">
	<NavBar title="基础用法" />
	<NavBar title="右侧使用 Icon" rights={icons1} />
	<NavBar title="标题居中" titleAlign="center" rights={[{ name: 'ri-command-line' }]} />
	<NavBar title="点击左侧" onclickLeft={() => (visible1 = true)} />
	<Toast bind:visible={visible1} message="点击了左侧！" />
	<NavBar
		title="点击右侧"
		rights={icons2}
		onclickRight={(index) => {
			visible2 = true;
			rightIndex = index;
		}}
	/>
	<Toast bind:visible={visible2} message={`点击的右侧图标索引值是 ${rightIndex}。`} />
	<NavBar title="无左侧与底分割线，文字过长长长长长长长" left={null} line={false} rights={icons3} />
	<NavBar title="自定义背景颜色 by injClass" injClass="!bg-[#e0e0e0] dark:!bg-[green]" />
	<NavBar>
		{#snippet titleChild()}
			<div class="text-[red] dark:text-[green]">自定义文字颜色 by Snippet</div>
		{/snippet}
	</NavBar>
	<NavBar>
		{#snippet titleChild()}
			<div class="flex h-12 flex-col justify-around text-xs">
				<div class="text-sm">title 插槽渲染标题区域</div>
				<div>right 插槽渲染右侧且可点击</div>
			</div>
		{/snippet}
		{#snippet rightChild()}
			<div>
				<button class="text-primary dark:text-dark h-12 w-12 cursor-pointer text-center" onclick={() => (visible3 = true)}>Hello</button>
			</div>
		{/snippet}
	</NavBar>
	<Toast bind:visible={visible3} message="点击了右侧插槽内容！" />
	<NavBar title="关爱版导航栏" love rights={icons4} />
	<NavBar injClass="!bg-transparent" line={false}>
		{#snippet leftChild()}
			<div class="m-2 h-8 w-8 rounded-full bg-white text-center leading-8 dark:bg-black/50">
				<Icon name="ri-home-7-line" size={18} top={-2} />
			</div>
		{/snippet}
		{#snippet titleChild()}
			<div class="my-2 h-8 rounded-full bg-white px-3 text-sm leading-8 dark:bg-black/50">injClass 与 Snippet 结合自定义样式</div>
		{/snippet}
		{#snippet rightChild()}
			<div class="m-2 h-8 w-8 rounded-full bg-white text-center leading-8 dark:bg-black/50">
				<Icon name="ri-customer-service-2-line" size={18} top={-2} />
			</div>
		{/snippet}
	</NavBar>
</div>



================================================
FILE: packages/stdf/src/routes/noticeBar/en_US/+page.svelte
================================================
<!-- NoticeBar Demo -->
<script lang="ts">
	import { NoticeBar, Toast } from '$lib/index.js';

	let textList = ['1. This is the first announcement!', '2. This is the second notice!'];
	let textLongList = [
		'1. This message long, long, long, long, long, long, long, long, long, long, long, long, long!',
		'2. This is the second notice!'
	];

	let visible = $state(false);
</script>

<div class="m-4 mt-8 text-lg font-bold">Basic usage</div>
<NoticeBar {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">The announcements are short and do not scroll</div>
<NoticeBar textList={['1. Short notice!', '2. Short notice!']}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">Set notification spacing</div>
<NoticeBar space={200} {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">Set rolling speed</div>
<NoticeBar speed={100} {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">Right arrow (listen for click events)</div>
<NoticeBar rightIcon="arrow" {textList} onclickRight={() => (visible = true)}></NoticeBar>
<Toast bind:visible message="Click the right arrow!"></Toast>

<div class="m-4 mt-8 text-lg font-bold">No content on the right</div>
<NoticeBar rightIcon={null} {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">Nothing on the left</div>
<NoticeBar leftIcon={null} {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">Set text size</div>
<NoticeBar fontSize="lg" {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">Custom left</div>
<NoticeBar leftIcon={{ name: 'ri-notification-2-line', size: 16, top: -1 }} {textList}></NoticeBar>
<div class="my-4"></div>
<NoticeBar leftIcon={{ name: 'ri-wireless-charging-line', size: 16, top: -1 }} {textList}></NoticeBar>
<div class="my-4"></div>
<NoticeBar {textList}>
	{#snippet leftChild()}🥳{/snippet}
</NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">Custom right</div>
<NoticeBar {textList}>
	{#snippet rightChild()}🥳{/snippet}
</NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">Vertical rolling</div>
<NoticeBar vertical {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">Scroll transition to 1 second</div>
<NoticeBar vertical duration={1000} {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">The scrolling interval is 8 seconds</div>
<NoticeBar vertical interval={8} {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">Excessively long text</div>
<NoticeBar vertical textList={textLongList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">Single bar does not roll</div>
<NoticeBar vertical textList={[textLongList[0]]}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">Custom style</div>
<NoticeBar injClass="!text-error !bg-error/10" {textList}></NoticeBar>
<div class="my-4"></div>
<NoticeBar leftIcon={{ name: 'ri-check-line', size: 16, top: -1 }} injClass="!text-success !bg-success/10" {textList}></NoticeBar>
<div class="my-4"></div>
<NoticeBar injClass="!text-extend0 !bg-extend0/10" {textList}></NoticeBar>
<div class="pb-8"></div>



================================================
FILE: packages/stdf/src/routes/noticeBar/zh_CN/+page.svelte
================================================
<!-- NoticeBar Demo -->
<script lang="ts">
	import { NoticeBar, Toast } from '$lib/index.js';

	let textList = ['1. 这是第一条通告内容！', '2. 这是第二条通告内容！'];
	let textLongList = ['1. 这条通告超长长长长长长长长长长长长长长长长长长长长长！', '2. 这是第二条通告内容！'];

	let visible = $state(false);
</script>

<div class="m-4 mt-8 text-lg font-bold">基础用法</div>
<NoticeBar {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">通告内容较短不滚动</div>
<NoticeBar textList={['1. 短通告！', '2. 短通告！']}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">设定通告间距</div>
<NoticeBar space={200} {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">设定滚动速度</div>
<NoticeBar speed={100} {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">右侧箭头（监听点击事件）</div>
<NoticeBar rightIcon="arrow" {textList} onclickRight={() => (visible = true)}></NoticeBar>
<Toast bind:visible message="点击了右侧箭头！"></Toast>

<div class="m-4 mt-8 text-lg font-bold">右侧无内容</div>
<NoticeBar rightIcon={null} {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">左侧无内容</div>
<NoticeBar leftIcon={null} {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">设定文字大小</div>
<NoticeBar fontSize="lg" {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">自定义左侧</div>
<NoticeBar leftIcon={{ name: 'ri-notification-2-line', size: 16, top: -1 }} {textList}></NoticeBar>
<div class="my-4"></div>
<NoticeBar leftIcon={{ name: 'ri-wireless-charging-line', size: 16, top: -1 }} {textList}></NoticeBar>
<div class="my-4"></div>
<NoticeBar {textList}>
	{#snippet leftChild()}🥳{/snippet}
</NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">自定义右侧</div>
<NoticeBar {textList}>
	{#snippet rightChild()}🥳{/snippet}
</NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">垂直滚动</div>
<NoticeBar vertical {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">滚动过渡为 1 秒</div>
<NoticeBar vertical duration={1000} {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">滚动间隔为 8 秒</div>
<NoticeBar vertical interval={8} {textList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">文字过长</div>
<NoticeBar vertical textList={textLongList}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">单条不滚动</div>
<NoticeBar vertical textList={[textLongList[0]]}></NoticeBar>

<div class="m-4 mt-8 text-lg font-bold">自定义样式</div>
<NoticeBar injClass="!text-error !bg-error/10" {textList}></NoticeBar>
<div class="my-4"></div>
<NoticeBar leftIcon={{ name: 'ri-check-line', size: 16, top: -1 }} injClass="!text-success !bg-success/10" {textList}></NoticeBar>
<div class="my-4"></div>
<NoticeBar injClass="!text-extend0 !bg-extend0/10" {textList}></NoticeBar>
<div class="pb-8"></div>



================================================
FILE: packages/stdf/src/routes/numKeyboard/en_US/+page.svelte
================================================
<!-- NumKeyboard Demo -->
<script lang="ts">
	import { NumKeyboard, Cell, Toast } from '$lib/index.js';
	import { Confetti } from 'svelte-confetti';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);
	let visible15 = $state(false);
	let visible16 = $state(false);
	let visible17 = $state(false);
	let visible18 = $state(false);
	let visible19 = $state(false);
	let visible20 = $state(false);
	let visible21 = $state(false);

	// Demo for click event listening
	let visibleToast = $state(false);
	let key = $state('');
	const clickFunc = (k: string) => {
		key = k;
		visibleToast = true;
	};

	// Demo for open and close event listening
	let loveDom: HTMLElement | null = $state(null);
	// Distance from loveDom to window bottom
	let loveDomBottom = 0;
	let value = $state('');
	let top = $state(0);
	const openFunc = (height: number) => {
		// If loveDom is less than keyboard height from window bottom, move loveDom up by keyboard height
		loveDomBottom = window.innerHeight - (loveDom?.getBoundingClientRect().bottom || 0);
		top = loveDomBottom < height ? -(height - loveDomBottom) - 50 : 0;
	};

	let value21 = $state('');
	// Demo for getting content
	let valueClear = $state('');
</script>

<Cell title="Basic Usage" onclick={() => (visible1 = true)} />
<NumKeyboard bind:visible={visible1} />

<div class="px-4">Content: {value21}</div>
<Cell title="Get Content" onclick={() => (visible21 = true)} />
<NumKeyboard bind:visible={visible21} bind:value={value21} />

<div class="px-4">Content: {valueClear}</div>
<Cell title="Clear Content When Open" onclick={() => (visible20 = true)} />
<NumKeyboard bind:visible={visible20} bind:value={valueClear} clear />

<Cell title="Hide Done Button" onclick={() => (visible2 = true)} />
<NumKeyboard bind:visible={visible2} done={false} />

<Cell title="Show Close Button" onclick={() => (visible3 = true)} />
<NumKeyboard bind:visible={visible3} close />

<Cell title="Show Close & Hide Done" subTitle="Must hide decimal point" onclick={() => (visible9 = true)} />
<NumKeyboard bind:visible={visible9} close dot={false} done={false} />

<Cell title="Reverse Number Order" onclick={() => (visible4 = true)} />
<NumKeyboard bind:visible={visible4} reverse />

<Cell title="Increase Key Height" onclick={() => (visible5 = true)} />
<NumKeyboard bind:visible={visible5} height="16" />

<Cell title="Increase Spacing" onclick={() => (visible6 = true)} />
<NumKeyboard bind:visible={visible6} space="4" p="4" />

<Cell title="Hide Decimal Point" onclick={() => (visible7 = true)} />
<NumKeyboard bind:visible={visible7} close dot={false} />

<Cell title="Hide All Optional Elements" onclick={() => (visible8 = true)} />
<NumKeyboard bind:visible={visible8} done={false} dot={false} />

<Cell title="Block Style" onclick={() => (visible10 = true)} />
<NumKeyboard bind:visible={visible10} type="block" height="14" p="0" />

<Cell title="Custom Done Text" onclick={() => (visible18 = true)} />
<NumKeyboard bind:visible={visible18} doneText="Transfer" />

<Cell title="Click Event Listening" onclick={() => (visible11 = true)} />
<NumKeyboard bind:visible={visible11} onclick={clickFunc} />
<Toast bind:visible={visibleToast} duration={500} message={`Clicked ${key}`}></Toast>

<div
	class="bg-primary dark:bg-dark shadow-primary/30 dark:shadow-dark/30 relative mx-16 h-10 rounded-full text-center text-xl leading-10 text-white shadow-lg transition-all dark:text-black"
	style="top:{top}px"
	bind:this={loveDom}
>
	{value}
	{#if value === '5201314'}
		<span class="absolute left-1/2"><Confetti rounded amount={100} /></span>
	{/if}
</div>
<Cell title="Please Enter 5201314" onclick={() => (visible12 = true)} />
<NumKeyboard bind:visible={visible12} doneDisabled={value !== '5201314'} bind:value onopen={openFunc} onclose={() => (top = 0)} />

<Cell title="Larger Key Border Radius" onclick={() => (visible13 = true)} />
<NumKeyboard bind:visible={visible13} radius="2xl" />

<Cell title="Inject Done Button Class" onclick={() => (visible14 = true)} />
<NumKeyboard bind:visible={visible14} doneClass="!bg-gradient-to-r from-[#9820a8] to-[#d16b98]" />

<Cell title="Inject Panel & Key Class" onclick={() => (visible15 = true)} />
<NumKeyboard
	bind:visible={visible15}
	panelClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0]"
	keyClass="!bg-transparent border border-white/40 !text-white"
/>

<Cell title="Custom Transition" subTitle="Via popup" onclick={() => (visible16 = true)} />
<NumKeyboard bind:visible={visible16} popup={{ duration: 1000, easeType: 'bounceOut' }} />

<Cell title="Opaque Background When Active" subTitle="Via popup mask" onclick={() => (visible17 = true)} />
<NumKeyboard bind:visible={visible17} popup={{ mask: { opacity: '0.4' } }} />

<Cell title="Custom Key Font" subTitle="Need to load font in CSS and configure in @theme" onclick={() => (visible19 = true)} />
<NumKeyboard bind:visible={visible19} keyClass="font-Trueno" />



================================================
FILE: packages/stdf/src/routes/numKeyboard/zh_CN/+page.svelte
================================================
<!-- NumKeyboard Demo -->
<script lang="ts">
	import { NumKeyboard, Cell, Toast } from '$lib/index.js';
	import { Confetti } from 'svelte-confetti';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);
	let visible15 = $state(false);
	let visible16 = $state(false);
	let visible17 = $state(false);
	let visible18 = $state(false);
	let visible19 = $state(false);
	let visible20 = $state(false);
	let visible21 = $state(false);

	// 演示监听点击事件
	let visibleToast = $state(false);
	let key = $state('');
	const clickFunc = (k: string) => {
		key = k;
		visibleToast = true;
	};

	// 演示监听开启与关闭事件
	let loveDom: HTMLElement | null = $state(null);
	// loveDom 距离窗口底部的距离
	let loveDomBottom = 0;
	let value = $state('');
	let top = $state(0);
	const openFunc = (height: number) => {
		// 如果 loveDom 距离窗口底部小于键盘高度，就把 loveDom 向上移动键盘高度
		loveDomBottom = window.innerHeight - (loveDom?.getBoundingClientRect().bottom || 0);
		top = loveDomBottom < height ? -(height - loveDomBottom) - 50 : 0;
	};

	let value21 = $state('');
	// 演示清空内容
	let valueClear = $state('');
</script>

<Cell title="基础用法" onclick={() => (visible1 = true)} />
<NumKeyboard bind:visible={visible1} />

<div class="px-4">输入了: {value21}</div>
<Cell title="获取内容" onclick={() => (visible21 = true)} />
<NumKeyboard bind:visible={visible21} bind:value={value21} />

<div class="px-4">输入了: {valueClear}</div>
<Cell title="打开时清空内容" onclick={() => (visible20 = true)} />
<NumKeyboard bind:visible={visible20} bind:value={valueClear} clear />

<Cell title="不显示完成" onclick={() => (visible2 = true)} />
<NumKeyboard bind:visible={visible2} done={false} />

<Cell title="显示关闭" onclick={() => (visible3 = true)} />
<NumKeyboard bind:visible={visible3} close />

<Cell title="显示关闭不显示完成" subTitle="必须隐藏小数点" onclick={() => (visible9 = true)} />
<NumKeyboard bind:visible={visible9} close dot={false} done={false} />

<Cell title="数字上下反向" onclick={() => (visible4 = true)} />
<NumKeyboard bind:visible={visible4} reverse />

<Cell title="增高按键高度" onclick={() => (visible5 = true)} />
<NumKeyboard bind:visible={visible5} height="16" />

<Cell title="增大间距" onclick={() => (visible6 = true)} />
<NumKeyboard bind:visible={visible6} space="4" p="4" />

<Cell title="不显示小数点" onclick={() => (visible7 = true)} />
<NumKeyboard bind:visible={visible7} close dot={false} />

<Cell title="不必要的全部不显示" onclick={() => (visible8 = true)} />
<NumKeyboard bind:visible={visible8} done={false} dot={false} />

<Cell title="块式" onclick={() => (visible10 = true)} />
<NumKeyboard bind:visible={visible10} type="block" height="14" p="0" />

<Cell title="自定义完成文字" onclick={() => (visible18 = true)} />
<NumKeyboard bind:visible={visible18} doneText="转账" />

<Cell title="监听点击事件" onclick={() => (visible11 = true)} />
<NumKeyboard bind:visible={visible11} onclick={clickFunc} />
<Toast bind:visible={visibleToast} duration={500} message={`点击了 ${key}`}></Toast>

<div
	class="bg-primary dark:bg-dark shadow-primary/30 dark:shadow-dark/30 relative mx-16 h-10 rounded-full text-center text-xl leading-10 text-white shadow-lg transition-all dark:text-black"
	style="top:{top}px"
	bind:this={loveDom}
>
	{value}
	{#if value === '5201314'}
		<span class="absolute left-1/2"><Confetti rounded amount={100} /></span>
	{/if}
</div>
<Cell title="请输入 5201314" onclick={() => (visible12 = true)} />
<NumKeyboard bind:visible={visible12} doneDisabled={value !== '5201314'} bind:value onopen={openFunc} onclose={() => (top = 0)} />

<Cell title="增大按键圆角" onclick={() => (visible13 = true)} />
<NumKeyboard bind:visible={visible13} radius="2xl" />

<Cell title="完成按键注入 Class" onclick={() => (visible14 = true)} />
<NumKeyboard bind:visible={visible14} doneClass="!bg-gradient-to-r from-[#9820a8] to-[#d16b98]" />

<Cell title="面板与按键注入 Class" onclick={() => (visible15 = true)} />
<NumKeyboard
	bind:visible={visible15}
	panelClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0]"
	keyClass="!bg-transparent border border-white/40 !text-white"
/>

<Cell title="自定义过渡动画" subTitle="通过 popup" onclick={() => (visible16 = true)} />
<NumKeyboard bind:visible={visible16} popup={{ duration: 1000, easeType: 'bounceOut' }} />

<Cell title="激活时背景不透明" subTitle="通过 popup 内的 mask" onclick={() => (visible17 = true)} />
<NumKeyboard bind:visible={visible17} popup={{ mask: { opacity: '0.4' } }} />

<Cell title="自定义按键字体" subTitle="需要 CSS 加载字体并在 @theme 中配置" onclick={() => (visible19 = true)} />
<NumKeyboard bind:visible={visible19} keyClass="font-Trueno" />



================================================
FILE: packages/stdf/src/routes/pagination/en_US/+page.svelte
================================================
<script lang="ts">
	import { onMount } from 'svelte';
	import { Pagination, Loading } from '$lib/index.js';
	import aphorisms from '../../../data/aphorisms.js';

	// total, usually from backend
	const total = 200;

	// current page
	let current = $state(1);

	// simulate request data
	let data: { text: string; from: string; fromItalic?: boolean }[] = $state([]);
	let currentPage = $state(1);
	let pageSize = 4;
	let totalData = $state(0);
	let loading = $state(false);
	const getData = () => {
		loading = true;
		// use setTimeout to simulate request
		setTimeout(() => {
			loading = false;
			// get pageSize data from aphorisms randomly
			data = aphorisms.sort(() => Math.random() - 0.5).slice(0, pageSize);
			totalData = 64;
		}, 2000);
	};
	const changePageFunc = (c: number) => {
		currentPage = c;
		getData();
	};
	// initial request first page
	onMount(() => {
		getData();
	});
</script>

<div class="m-4 mt-24 text-lg font-bold">Basic usage</div>
<Pagination {total} />

<div class="mx-4 mt-8 text-lg font-bold">Event listening</div>
<div class="mx-4 mb-2 text-sm">Current page: {current}</div>
<Pagination {total} onpre={(c) => (current = c)} onnext={(c) => (current = c)} onchange={(c) => (current = c)} />

<div class="mx-4 mt-24 text-lg font-bold">Initial display omitted page</div>
<div class="mx-4 mb-4 text-xs">Can be used to guide users</div>
<Pagination {total} showNextOmitPage />

<div class="m-4 mt-8 text-lg font-bold">Set initial page</div>
<Pagination {total} current={10} />

<div class="mx-4 mt-8 text-lg font-bold">Max display 11 pages</div>
<div class="mx-4 mb-4 text-xs">Display more pages but the page number is small</div>
<Pagination maxShowPage={11} {total} />

<div class="mx-4 mt-8 text-lg font-bold">Max display 5 pages</div>
<div class="mx-4 mb-4 text-xs">Suitable for scenes with a small paging area</div>
<div class="flex items-center">
	<div class="px-4">This is my territory</div>
	<div class="flex-1">
		<Pagination maxShowPage={5} {total} />
	</div>
</div>

<div class="m-4 mt-8 text-lg font-bold">No data</div>
<Pagination total={0} />

<div class="m-4 mt-8 text-lg font-bold">Only one page</div>
<Pagination total={8} />

<div class="mx-4 mt-8 text-lg font-bold">Total pages are less than the maximum display pages</div>
<div class="mx-4 mb-4 text-xs">No omitted page</div>
<Pagination total={70} />

<div class="mx-4 mt-8 text-lg font-bold">Total pages are less than the maximum display pages</div>
<div class="mx-4 mb-4 text-xs">No omitted page</div>
<Pagination total={90} maxShowPage={7} />

<div class="mx-4 mt-8 text-lg font-bold">Total pages are many</div>
<div class="mx-4 mb-4 text-xs">Will exist two omitted pages</div>
<Pagination {total} />

<div class="m-4 mt-8 text-lg font-bold">Each page is only 3 items</div>
<Pagination total={50} pageSize={3} />

<div class="m-4 mt-8 text-lg font-bold">Highlighted page is border</div>
<Pagination {total} type="border" />

<div class="m-4 mt-8 text-lg font-bold">Highlighted page is block</div>
<Pagination {total} type="block" />

<div class="m-4 mt-8 text-lg font-bold">Increase the radius of the highlighted page</div>
<Pagination {total} type="block" radius="xl" />

<div class="m-4 mt-8 text-lg font-bold">Omitted page column is 2</div>
<Pagination {total} pageCol={2} />

<div class="m-4 mt-8 text-lg font-bold">Inject injClass</div>
<Pagination {total} injClass="mx-2 rounded-full shadow-md dark:shadow-white/10" />

<div class="m-4 mt-8 text-lg font-bold">Simulate request</div>
<div class="relative min-h-[20rem] divide-y divide-black/5 px-4 py-8 dark:divide-white/5">
	{#each data as item}
		<div class:py-6={pageSize > 1}>
			<div class="text-justify text-sm">{item.text}</div>
			<div class="mt-1 text-right" class:italic={item.fromItalic}>{item.from}</div>
		</div>
	{/each}
	{#if loading}
		<div class="absolute inset-0 flex h-full w-full flex-col justify-center gap-8 text-center backdrop-blur-sm">
			<div>Querying the {currentPage} page data...</div>
			<Loading />
		</div>
	{/if}
</div>
<Pagination {pageSize} total={totalData} onchange={changePageFunc} />

<div class="mx-4 mt-8 text-lg font-bold">Continuous mode</div>
<div class="mx-4 mb-4 text-xs">Only allow clicking on the previous and next pages</div>
<Pagination {total} continuous />

<div class="pb-10"></div>



================================================
FILE: packages/stdf/src/routes/pagination/zh_CN/+page.svelte
================================================
<script lang="ts">
	import { onMount } from 'svelte';
	import { Pagination, Loading } from '$lib/index.js';
	import aphorisms from '../../../data/aphorisms.js';

	// 总数，一般是后端接口返回
	const total = 200;

	// 当前页码，演示事件监听
	let current = $state(1);

	// 模拟请求数据
	let data: { text: string; from: string; fromItalic?: boolean }[] = $state([]);
	let currentPage = $state(1);
	let pageSize = 4;
	let totalData = $state(0);
	let loading = $state(false);
	const getData = () => {
		loading = true;
		// 使用 setTimeout 模拟请求
		setTimeout(() => {
			loading = false;
			//从 aphorisms 随机取出 pageSize 条数据
			data = aphorisms.sort(() => Math.random() - 0.5).slice(0, pageSize);
			totalData = 64;
		}, 2000);
	};
	const changePageFunc = (c: number) => {
		currentPage = c;
		getData();
	};
	// 初始请求第一页
	onMount(() => {
		getData();
	});
</script>

<div class="m-4 mt-24 text-lg font-bold">基础用法</div>
<Pagination {total} />

<div class="mx-4 mt-8 text-lg font-bold">事件监听</div>
<div class="mx-4 mb-2 text-sm">当前页码：{current}</div>
<Pagination {total} onpre={(c) => (current = c)} onnext={(c) => (current = c)} onchange={(c) => (current = c)} />

<div class="mx-4 mt-24 text-lg font-bold">初始展示省略页码</div>
<div class="mx-4 mb-4 text-xs">可用于引导用户</div>
<Pagination {total} showNextOmitPage />

<div class="m-4 mt-8 text-lg font-bold">设置初始页</div>
<Pagination {total} current={10} />

<div class="mx-4 mt-8 text-lg font-bold">最大显示 11 页</div>
<div class="mx-4 mb-4 text-xs">同时显示较多页但页码较小</div>
<Pagination maxShowPage={11} {total} />

<div class="mx-4 mt-8 text-lg font-bold">最大显示 5 页</div>
<div class="mx-4 mb-4 text-xs">适合分页区域较小的场景</div>
<div class="flex items-center">
	<div class="px-4">这是我的地盘</div>
	<div class="flex-1">
		<Pagination maxShowPage={5} {total} />
	</div>
</div>

<div class="m-4 mt-8 text-lg font-bold">无数据</div>
<Pagination total={0} />

<div class="m-4 mt-8 text-lg font-bold">仅一页</div>
<Pagination total={8} />

<div class="mx-4 mt-8 text-lg font-bold">总页数未超过最大显示页数</div>
<div class="mx-4 mb-4 text-xs">不会存在省略页码</div>
<Pagination total={70} />

<div class="mx-4 mt-8 text-lg font-bold">总页数超过最大显示页数但不算多</div>
<div class="mx-4 mb-4 text-xs">不会同时存在前后两个省略页码</div>
<Pagination total={90} maxShowPage={7} />

<div class="mx-4 mt-8 text-lg font-bold">总页数很多</div>
<div class="mx-4 mb-4 text-xs">会同时存在前后两个省略页码</div>
<Pagination {total} />

<div class="m-4 mt-8 text-lg font-bold">每页仅 3 项</div>
<Pagination total={50} pageSize={3} />

<div class="m-4 mt-8 text-lg font-bold">高亮页码为边框</div>
<Pagination {total} type="border" />

<div class="m-4 mt-8 text-lg font-bold">高亮页码为块状</div>
<Pagination {total} type="block" />

<div class="m-4 mt-8 text-lg font-bold">增加高亮页码圆角</div>
<Pagination {total} type="block" radius="xl" />

<div class="m-4 mt-8 text-lg font-bold">省略页码列数为 2</div>
<Pagination {total} pageCol={2} />

<div class="m-4 mt-8 text-lg font-bold">注入 injClass</div>
<Pagination {total} injClass="mx-2 rounded-full shadow-md dark:shadow-white/10" />

<div class="m-4 mt-8 text-lg font-bold">模拟请求</div>
<div class="relative min-h-[20rem] divide-y divide-black/5 px-4 py-8 dark:divide-white/5">
	{#each data as item}
		<div class:py-6={pageSize > 1}>
			<div class="text-justify text-sm">{item.text}</div>
			<div class="mt-1 text-right" class:italic={item.fromItalic}>{item.from}</div>
		</div>
	{/each}
	{#if loading}
		<div class="absolute inset-0 flex h-full w-full flex-col justify-center gap-8 text-center backdrop-blur-sm">
			<div>查询第 {currentPage} 页数据...</div>
			<Loading />
		</div>
	{/if}
</div>
<Pagination {pageSize} total={totalData} onchange={changePageFunc} />

<div class="mx-4 mt-8 text-lg font-bold">连续模式</div>
<div class="mx-4 mb-4 text-xs">只允许点击上下页</div>
<Pagination {total} continuous />

<div class="pb-10"></div>



================================================
FILE: packages/stdf/src/routes/picker/en_US/+page.svelte
================================================
<!-- Picker Demo -->
<script lang="ts">
	import { Picker, Cell } from '$lib/index.js';
	// For the sake of clarity, the specific reference data is placed in the data_en.js file, which can be viewed at the bottom of this page.
	import {
		someProvinceList,
		weekList,
		amOrPmList,
		timeList,
		cityList,
		linkageData,
		linkagDiffLabelKeyData,
		linkagCustomChildrenKeyData
	} from './data_en.js';

	const datas = [{ data: someProvinceList }];

	const col3Datas = [{ data: weekList }, { data: amOrPmList }, { data: timeList }];

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);
	let visible15 = $state(false);
	let visible16 = $state(false);
	let visible17 = $state(false);
	let visible18 = $state(false);
	let visible19 = $state(false);
	let visible20 = $state(false);
	let visible21 = $state(false);
	let visible22 = $state(false);

	let currentDetail = $state('Please select');
	let allItems: { [key: string]: string }[] = $state([]);
	let allIndexs: number[] = $state([]);
</script>

<div class="py-4">
	<Cell title="Basic usage" onclick={() => (visible1 = true)} />
	<Picker bind:visible={visible1} {datas} />

	<Cell title="Custom title" onclick={() => (visible2 = true)} />
	<Picker bind:visible={visible2} title="Please select state" {datas} />

	<Cell title="Visible 7 rows" onclick={() => (visible3 = true)} />
	<Picker bind:visible={visible3} datas={[{ data: someProvinceList, showRow: 7 }]} />

	<Cell title="Close automatic scrolling to the last selected item" onclick={() => (visible4 = true)} />
	<Picker bind:visible={visible4} {datas} autoScrollToLast={false} />

	<Cell
		title="Initial selection is always the 4th item"
		onclick={() => (visible5 = true)}
		subTitle="Need to close automatic selection of the last selected item"
	/>
	<Picker bind:visible={visible5} datas={[{ data: someProvinceList, initIndex: 3 }]} autoScrollToLast={false} />

	<Cell title="Cancel animation when scrolling" onclick={() => (visible6 = true)} />
	<Picker bind:visible={visible6} datas={[{ data: someProvinceList, useAnimation: false }]} />

	<Cell title="Custom label key value" onclick={() => (visible7 = true)} />
	<Picker bind:visible={visible7} datas={[{ data: cityList, labelKey: 'cityName' }]} title="Please select city" />

	<Cell title="Right display selected item" detail={currentDetail} onclick={() => (visible8 = true)} />
	<Picker bind:visible={visible8} {datas} onconfirm={(items) => (currentDetail = items[0].label)} />

	<Cell title="Single column left alignment" onclick={() => (visible20 = true)} />
	<Picker bind:visible={visible20} datas={[{ data: someProvinceList, align: 'left' }]} />

	<Cell title="Multi-column picker" onclick={() => (visible9 = true)} />
	<Picker bind:visible={visible9} datas={col3Datas} />

	<Cell title="Different column visibility rows" onclick={() => (visible10 = true)} />
	<Picker bind:visible={visible10} datas={[{ data: weekList }, { data: amOrPmList, showRow: 3 }, { data: timeList, showRow: 7 }]} />

	<Cell title="Different column flex ratios" onclick={() => (visible11 = true)} />
	<Picker
		bind:visible={visible11}
		datas={[
			{ data: weekList, flex: 3 },
			{ data: amOrPmList, flex: 1 },
			{ data: timeList, flex: 2 }
		]}
	/>

	<Cell title="Different column alignments" onclick={() => (visible21 = true)} />
	<Picker
		bind:visible={visible21}
		datas={[
			{ data: weekList, align: 'left' },
			{ data: amOrPmList, align: 'center' },
			{ data: timeList, align: 'right' }
		]}
	/>

	<Cell title="Multi-level linkage" onclick={() => (visible12 = true)} />
	<Picker bind:visible={visible12} datas={linkageData} isLinkage />

	<Cell title="Multi-level linkage different visible rows" onclick={() => (visible13 = true)} />
	<Picker bind:visible={visible13} datas={linkageData} linkageShowRows={[3, 5, 7]} isLinkage />

	<Cell title="Multi-level linkage different flex ratios" onclick={() => (visible14 = true)} />
	<Picker bind:visible={visible14} datas={linkageData} linkageFlexs={[1, 2, 3]} isLinkage />

	<Cell title="Multi-level linkage custom label key for each level" onclick={() => (visible15 = true)} />
	<Picker bind:visible={visible15} datas={linkagDiffLabelKeyData} linkageLabelKeys={['province', 'city', 'region']} isLinkage />

	<Cell title="Multi-level linkage custom key for each level's children" onclick={() => (visible16 = true)} />
	<Picker bind:visible={visible16} datas={linkagCustomChildrenKeyData} linkageChildrenKey="child" isLinkage />

	<Cell title="Multi-level linkage different alignments" onclick={() => (visible22 = true)} />
	<Picker bind:visible={visible22} datas={linkageData} linkageAligns={['right', 'center', 'left']} isLinkage />

	<Cell title="Multi-level linkage set initial selected items for each column" onclick={() => (visible17 = true)} />
	<Picker bind:visible={visible17} datas={linkageData} linkageInitIndexs={[0, 1, 8]} isLinkage />

	<div class="px-4">
		{#if allItems.length}
			Currently selected:
			{#each allItems as item}
				<span class="mr-2 text-primary dark:text-dark">{item.label}</span>
			{/each}
		{:else}
			<div>Please select data</div>
		{/if}
	</div>
	<div class="px-4">
		{#if allIndexs.length}
			Currently selected value is located at the index of each column:
			{#each allIndexs as index}
				<span class="mr-2 text-primary dark:text-dark">{index}</span>
			{/each}
		{:else}
			<div>Please select data</div>
		{/if}
	</div>
	<Cell title="Get selected data" onclick={() => (visible18 = true)} />
	<Picker
		bind:visible={visible18}
		datas={col3Datas}
		onconfirm={(items, indexs) => {
			allItems = items;
			allIndexs = indexs;
		}}
	/>

	<Cell title="Top corner rounded" onclick={() => (visible19 = true)} />
	<Picker bind:visible={visible19} {datas} popup={{ radius: 'xl' }} />
</div>

<!-- data_en.js -->
<!-- 
const someProvinceList = [
	{ label: 'California' },
	{ label: 'New York' },
	{ label: 'Texas' },
	{ label: 'Florida' },
	{ label: 'Illinois' },
	{ label: 'Pennsylvania' },
	{ label: 'Ohio' },
	{ label: 'Michigan' },
	{ label: 'Georgia' },
	{ label: 'Virginia' },
	{ label: 'Washington' },
	{ label: 'Arizona' },
	{ label: 'Massachusetts' },
	{ label: 'Tennessee' },
];
const weekList = [
	{ label: 'Monday' },
	{ label: 'Tuesday' },
	{ label: 'Wednesday' },
	{ label: 'Thursday' },
	{ label: 'Friday' },
	{ label: 'Saturday' },
	{ label: 'Sunday' },
];
const amOrPmList = [{ label: 'AM' }, { label: 'PM' }];
const timeList = [
	{ label: '01:00' },
	{ label: '02:00' },
	{ label: '03:00' },
	{ label: '04:00' },
	{ label: '05:00' },
	{ label: '06:00' },
	{ label: '07:00' },
	{ label: '08:00' },
	{ label: '09:00' },
	{ label: '10:00' },
	{ label: '11:00' },
	{ label: '12:00' },
];
const cityList = [
	{ cityName: 'losangeles' },
	{ cityName: 'sandiego' },
	{ cityName: 'sanfrancisco' },
	{ cityName: 'sacramento' },
	{ cityName: 'fresno' },
	{ cityName: 'oakland' },
	{ cityName: 'sanjose' },
	{ cityName: 'bakersfield' },
	{ cityName: 'anaheim' },
	{ cityName: 'riverside' },
	{ cityName: 'stockton' },
];
const linkageData = [
	{
		label: 'California',
		children: [
			{
				label: 'Los Angeles',
				children: [
					{ label: 'Downtown' },
					{ label: 'Hollywood' },
					{ label: 'Beverly Hills' },
					{ label: 'Santa Monica' },
					{ label: 'Pasadena' },
				],
			},
			{
				label: 'San Francisco',
				children: [
					{ label: 'Downtown' },
					{ label: 'Mission District' },
					{ label: 'North Beach' },
					{ label: 'Chinatown' },
					{ label: 'Haight-Ashbury' },
					{ label: 'Castro' },
				],
			},
			{
				label: 'San Diego',
				children: [
					{ label: 'Downtown' },
					{ label: 'La Jolla' },
					{ label: 'Pacific Beach' },
					{ label: 'Mission Beach' },
					{ label: 'Coronado' },
				],
			},
			{
				label: 'Sacramento',
				children: [
					{ label: 'Downtown' },
					{ label: 'Midtown' },
					{ label: 'East Sacramento' },
					{ label: 'Land Park' },
					{ label: 'Natomas' },
					{ label: 'Arden-Arcade' },
				],
			},
			{
				label: 'Oakland',
				children: [{ label: 'Downtown' }, { label: 'Lake Merritt' }, { label: 'Rockridge' }],
			},
			{
				label: 'San Jose',
				children: [
					{ label: 'Downtown' },
					{ label: 'Willow Glen' },
					{ label: 'Almaden Valley' },
					{ label: 'Berryessa' },
					{ label: 'Evergreen' },
				],
			},
			{
				label: 'Fresno',
				children: [
					{ label: 'Downtown' },
					{ label: 'Tower District' },
					{ label: 'River Park' },
					{ label: 'Fig Garden' },
					{ label: 'Woodward Park' },
				],
			},
			{
				label: 'Long Beach',
				children: [
					{ label: 'Downtown' },
					{ label: 'Belmont Shore' },
					{ label: 'Bixby Knolls' },
					{ label: 'Naples' },
					{ label: 'Alamitos Beach' },
					{ label: 'Rose Park' },
				],
			},
			{
				label: 'Bakersfield',
				children: [{ label: 'Downtown' }, { label: 'Rosedale' }, { label: 'Oildale' }, { label: 'Seven Oaks' }, { label: 'Stockdale' }],
			},
			{
				label: 'Anaheim',
				children: [
					{ label: 'Downtown' },
					{ label: 'Anaheim Hills' },
					{ label: 'The Colony' },
					{ label: 'The Platinum Triangle' },
					{ label: 'West Anaheim' },
					{ label: 'East Anaheim' },
					{ label: 'South Anaheim' },
					{ label: 'Resort District' },
				],
			},
		],
	},
	{
		label: 'Texas',
		children: [
			{
				label: 'Houston',
				children: [
					{ label: 'Downtown' },
					{ label: 'Midtown' },
					{ label: 'Heights' },
					{ label: 'River Oaks' },
					{ label: 'Memorial' },
					{ label: 'Medical Center' },
				],
			},
			{
				label: 'Dallas',
				children: [
					{ label: 'Downtown' },
					{ label: 'Uptown' },
					{ label: 'Deep Ellum' },
					{ label: 'Oak Lawn' },
					{ label: 'Bishop Arts' },
					{ label: 'Knox Henderson' },
				],
			},
			{
				label: 'Austin',
				children: [{ label: 'Downtown' }, { label: 'South Congress' }, { label: 'East Austin' }],
			},
			{
				label: 'San Antonio',
				children: [
					{ label: 'Downtown' },
					{ label: 'Alamo Heights' },
					{ label: 'Pearl District' },
					{ label: 'King William' },
					{ label: 'Stone Oak' },
				],
			},
		],
	},
	{
		label: 'Illinois',
		children: [
			{
				label: 'Chicago',
				children: [
					{ label: 'Loop' },
					{ label: 'River North' },
					{ label: 'Lincoln Park' },
					{ label: 'Wicker Park' },
					{ label: 'Gold Coast' },
					{ label: 'Lakeview' },
				],
			},
			{
				label: 'Springfield',
				children: [
					{ label: 'Downtown' },
					{ label: 'West Side' },
					{ label: 'East Side' },
					{ label: 'North End' },
					{ label: 'South Side' },
					{ label: 'Jerome' },
				],
			},
			{
				label: 'Rockford',
				children: [
					{ label: 'Downtown' },
					{ label: 'East Side' },
					{ label: 'North End' },
					{ label: 'Rural Oaks' },
					{ label: 'Churchill Grove' },
					{ label: 'Signal Hill' },
				],
			},
			{
				label: 'Peoria',
				children: [
					{ label: 'Downtown' },
					{ label: 'West Bluff' },
					{ label: 'East Bluff' },
					{ label: 'North Valley' },
					{ label: 'South Side' },
				],
			},
		],
	},
	{
		label: 'New York',
		children: [
			{
				label: 'New York City',
				children: [
					{ label: 'Manhattan' },
					{ label: 'Brooklyn' },
					{ label: 'Queens' },
					{ label: 'The Bronx' },
					{ label: 'Staten Island' },
					{ label: 'Harlem' },
				],
			},
		],
	},
	{
		label: 'Washington',
		children: [
			{
				label: 'Seattle',
				children: [
					{ label: 'Downtown' },
					{ label: 'Capitol Hill' },
					{ label: 'Ballard' },
					{ label: 'Fremont' },
					{ label: 'Queen Anne' },
					{ label: 'South Lake Union' },
				],
			},
			{
				label: 'Spokane',
				children: [
					{ label: 'Downtown' },
					{ label: 'South Hill' },
					{ label: 'North Side' },
					{ label: 'West Central' },
					{ label: 'East Central' },
					{ label: 'Riverside' },
				],
			},
			{
				label: 'Tacoma',
				children: [
					{ label: 'Downtown' },
					{ label: 'North End' },
					{ label: 'South End' },
					{ label: 'East Side' },
					{ label: 'West End' },
					{ label: 'Central' },
				],
			},
			{
				label: 'Vancouver',
				children: [
					{ label: 'Downtown' },
					{ label: 'Uptown' },
					{ label: 'Hazel Dell' },
					{ label: 'Salmon Creek' },
					{ label: "Fisher's Landing" },
					{ label: 'Cascade Park' },
				],
			},
			{
				label: 'Bellevue',
				children: [
					{ label: 'Downtown' },
					{ label: 'West Bellevue' },
					{ label: 'Crossroads' },
					{ label: 'Eastgate' },
					{ label: 'Factoria' },
				],
			},
		],
	},
];
const linkagDiffLabelKeyData = [
	{
		province: 'California',
		children: [
			{
				city: 'Los Angeles',
				children: [
					{ region: 'Downtown' },
					{ region: 'Hollywood' },
					{ region: 'Beverly Hills' },
					{ region: 'Santa Monica' },
					{ region: 'Pasadena' },
					{ region: 'Venice Beach' },
					{ region: 'Westwood' },
				],
			},
			{
				city: 'San Francisco',
				children: [
					{ region: 'Downtown' },
					{ region: 'Mission District' },
					{ region: 'North Beach' },
					{ region: 'Chinatown' },
					{ region: 'Haight-Ashbury' },
					{ region: 'Castro' },
				],
			},
			{
				city: 'San Diego',
				children: [
					{ region: 'Downtown' },
					{ region: 'La Jolla' },
					{ region: 'Pacific Beach' },
					{ region: 'Mission Beach' },
					{ region: 'Coronado' },
					{ region: 'North Park' },
				],
			},
		],
	},
	{
		province: 'Florida',
		children: [
			{
				city: 'Miami',
				children: [
					{ region: 'Downtown' },
					{ region: 'South Beach' },
					{ region: 'Brickell' },
					{ region: 'Coconut Grove' },
					{ region: 'Little Havana' },
					{ region: 'Coral Gables' },
				],
			},
			{
				city: 'Orlando',
				children: [
					{ region: 'Downtown' },
					{ region: 'Winter Park' },
					{ region: 'Lake Nona' },
					{ region: 'College Park' },
					{ region: 'Baldwin Park' },
					{ region: 'Mills 50' },
				],
			},
			{
				city: 'Tampa',
				children: [{ region: 'Downtown' }, { region: 'Hyde Park' }, { region: 'Ybor City' }, { region: 'Channelside' }],
			},
		],
	},
	{
		province: 'Illinois',
		children: [
			{
				city: 'Chicago',
				children: [
					{ region: 'Loop' },
					{ region: 'River North' },
					{ region: 'Lincoln Park' },
					{ region: 'Wicker Park' },
					{ region: 'Gold Coast' },
					{ region: 'Lakeview' },
				],
			},
			{
				city: 'Springfield',
				children: [
					{ region: 'Downtown' },
					{ region: 'West Side' },
					{ region: 'East Side' },
					{ region: 'North End' },
					{ region: 'South Side' },
					{ region: 'Jerome' },
				],
			},
			{
				city: 'Peoria',
				children: [
					{ region: 'Downtown' },
					{ region: 'West Bluff' },
					{ region: 'East Bluff' },
					{ region: 'North Valley' },
					{ region: 'South Side' },
				],
			},
		],
	},
	{
		province: 'New York',
		children: [
			{
				city: 'New York City',
				children: [
					{ region: 'Manhattan' },
					{ region: 'Brooklyn' },
					{ region: 'Queens' },
					{ region: 'The Bronx' },
					{ region: 'Staten Island' },
					{ region: 'Harlem' },
				],
			},
		],
	},
];
const linkagCustomChildrenKeyData = [
	{
		label: 'California',
		child: [
			{
				label: 'Los Angeles',
				child: [
					{ label: 'Downtown' },
					{ label: 'Hollywood' },
					{ label: 'Beverly Hills' },
					{ label: 'Santa Monica' },
					{ label: 'Pasadena' },
					{ label: 'Venice Beach' },
					{ label: 'Westwood' },
				],
			},
			{
				label: 'San Francisco',
				child: [
					{ label: 'Downtown' },
					{ label: 'Mission District' },
					{ label: 'North Beach' },
					{ label: 'Chinatown' },
					{ label: 'Haight-Ashbury' },
					{ label: 'Castro' },
				],
			},
			{
				label: 'San Diego',
				child: [
					{ label: 'Downtown' },
					{ label: 'La Jolla' },
					{ label: 'Pacific Beach' },
					{ label: 'Mission Beach' },
					{ label: 'Coronado' },
					{ label: 'North Park' },
				],
			},
		],
	},
	{
		label: 'Florida',
		child: [
			{
				label: 'Miami',
				child: [
					{ label: 'Downtown' },
					{ label: 'South Beach' },
					{ label: 'Brickell' },
					{ label: 'Coconut Grove' },
					{ label: 'Little Havana' },
					{ label: 'Coral Gables' },
				],
			},
			{
				label: 'Orlando',
				child: [
					{ label: 'Downtown' },
					{ label: 'Winter Park' },
					{ label: 'Lake Nona' },
					{ label: 'College Park' },
					{ label: 'Baldwin Park' },
					{ label: 'Mills 50' },
				],
			},
			{
				label: 'Tampa',
				child: [{ label: 'Downtown' }, { label: 'Hyde Park' }, { label: 'Ybor City' }, { label: 'Channelside' }],
			},
		],
	},
	{
		label: 'Illinois',
		child: [
			{
				label: 'Chicago',
				child: [
					{ label: 'Loop' },
					{ label: 'River North' },
					{ label: 'Lincoln Park' },
					{ label: 'Wicker Park' },
					{ label: 'Gold Coast' },
					{ label: 'Lakeview' },
				],
			},
			{
				label: 'Springfield',
				child: [
					{ label: 'Downtown' },
					{ label: 'West Side' },
					{ label: 'East Side' },
					{ label: 'North End' },
					{ label: 'South Side' },
					{ label: 'Jerome' },
				],
			},
			{
				label: 'Peoria',
				child: [
					{ label: 'Downtown' },
					{ label: 'West Bluff' },
					{ label: 'East Bluff' },
					{ label: 'North Valley' },
					{ label: 'South Side' },
				],
			},
		],
	},
	{
		label: 'New York',
		child: [
			{
				label: 'New York City',
				child: [
					{ label: 'Manhattan' },
					{ label: 'Brooklyn' },
					{ label: 'Queens' },
					{ label: 'The Bronx' },
					{ label: 'Staten Island' },
					{ label: 'Harlem' },
				],
			},
		],
	},
	{
		label: 'Washington',
		child: [
			{
				label: 'Seattle',
				child: [
					{ label: 'Downtown' },
					{ label: 'Capitol Hill' },
					{ label: 'Ballard' },
					{ label: 'Fremont' },
					{ label: 'Queen Anne' },
					{ label: 'South Lake Union' },
				],
			},
			{
				label: 'Spokane',
				child: [
					{ label: 'Downtown' },
					{ label: 'South Hill' },
					{ label: 'North Side' },
					{ label: 'West Central' },
					{ label: 'East Central' },
					{ label: 'Riverside' },
				],
			},
			{
				label: 'Tacoma',
				child: [
					{ label: 'Downtown' },
					{ label: 'North End' },
					{ label: 'South End' },
					{ label: 'East Side' },
					{ label: 'West End' },
					{ label: 'Central' },
				],
			},
		],
	},
];

export { someProvinceList, weekList, amOrPmList, timeList, cityList, linkageData, linkagDiffLabelKeyData, linkagCustomChildrenKeyData };
-->



================================================
FILE: packages/stdf/src/routes/picker/en_US/data_en.js
================================================
const someProvinceList = [
	{ label: 'California' },
	{ label: 'New York' },
	{ label: 'Texas' },
	{ label: 'Florida' },
	{ label: 'Illinois' },
	{ label: 'Pennsylvania' },
	{ label: 'Ohio' },
	{ label: 'Michigan' },
	{ label: 'Georgia' },
	{ label: 'Virginia' },
	{ label: 'Washington' },
	{ label: 'Arizona' },
	{ label: 'Massachusetts' },
	{ label: 'Tennessee' },
];
const weekList = [
	{ label: 'Monday' },
	{ label: 'Tuesday' },
	{ label: 'Wednesday' },
	{ label: 'Thursday' },
	{ label: 'Friday' },
	{ label: 'Saturday' },
	{ label: 'Sunday' },
];
const amOrPmList = [{ label: 'AM' }, { label: 'PM' }];
const timeList = [
	{ label: '01:00' },
	{ label: '02:00' },
	{ label: '03:00' },
	{ label: '04:00' },
	{ label: '05:00' },
	{ label: '06:00' },
	{ label: '07:00' },
	{ label: '08:00' },
	{ label: '09:00' },
	{ label: '10:00' },
	{ label: '11:00' },
	{ label: '12:00' },
];
const cityList = [
	{ cityName: 'losangeles' },
	{ cityName: 'sandiego' },
	{ cityName: 'sanfrancisco' },
	{ cityName: 'sacramento' },
	{ cityName: 'fresno' },
	{ cityName: 'oakland' },
	{ cityName: 'sanjose' },
	{ cityName: 'bakersfield' },
	{ cityName: 'anaheim' },
	{ cityName: 'riverside' },
	{ cityName: 'stockton' },
];
const linkageData = [
	{
		label: 'California',
		children: [
			{
				label: 'Los Angeles',
				children: [
					{ label: 'Downtown' },
					{ label: 'Hollywood' },
					{ label: 'Beverly Hills' },
					{ label: 'Santa Monica' },
					{ label: 'Pasadena' },
				],
			},
			{
				label: 'San Francisco',
				children: [
					{ label: 'Downtown' },
					{ label: 'Mission District' },
					{ label: 'North Beach' },
					{ label: 'Chinatown' },
					{ label: 'Haight-Ashbury' },
					{ label: 'Castro' },
				],
			},
			{
				label: 'San Diego',
				children: [
					{ label: 'Downtown' },
					{ label: 'La Jolla' },
					{ label: 'Pacific Beach' },
					{ label: 'Mission Beach' },
					{ label: 'Coronado' },
				],
			},
			{
				label: 'Sacramento',
				children: [
					{ label: 'Downtown' },
					{ label: 'Midtown' },
					{ label: 'East Sacramento' },
					{ label: 'Land Park' },
					{ label: 'Natomas' },
					{ label: 'Arden-Arcade' },
				],
			},
			{
				label: 'Oakland',
				children: [{ label: 'Downtown' }, { label: 'Lake Merritt' }, { label: 'Rockridge' }],
			},
			{
				label: 'San Jose',
				children: [
					{ label: 'Downtown' },
					{ label: 'Willow Glen' },
					{ label: 'Almaden Valley' },
					{ label: 'Berryessa' },
					{ label: 'Evergreen' },
				],
			},
			{
				label: 'Fresno',
				children: [
					{ label: 'Downtown' },
					{ label: 'Tower District' },
					{ label: 'River Park' },
					{ label: 'Fig Garden' },
					{ label: 'Woodward Park' },
				],
			},
			{
				label: 'Long Beach',
				children: [
					{ label: 'Downtown' },
					{ label: 'Belmont Shore' },
					{ label: 'Bixby Knolls' },
					{ label: 'Naples' },
					{ label: 'Alamitos Beach' },
					{ label: 'Rose Park' },
				],
			},
			{
				label: 'Bakersfield',
				children: [{ label: 'Downtown' }, { label: 'Rosedale' }, { label: 'Oildale' }, { label: 'Seven Oaks' }, { label: 'Stockdale' }],
			},
			{
				label: 'Anaheim',
				children: [
					{ label: 'Downtown' },
					{ label: 'Anaheim Hills' },
					{ label: 'The Colony' },
					{ label: 'The Platinum Triangle' },
					{ label: 'West Anaheim' },
					{ label: 'East Anaheim' },
					{ label: 'South Anaheim' },
					{ label: 'Resort District' },
				],
			},
		],
	},
	{
		label: 'Texas',
		children: [
			{
				label: 'Houston',
				children: [
					{ label: 'Downtown' },
					{ label: 'Midtown' },
					{ label: 'Heights' },
					{ label: 'River Oaks' },
					{ label: 'Memorial' },
					{ label: 'Medical Center' },
				],
			},
			{
				label: 'Dallas',
				children: [
					{ label: 'Downtown' },
					{ label: 'Uptown' },
					{ label: 'Deep Ellum' },
					{ label: 'Oak Lawn' },
					{ label: 'Bishop Arts' },
					{ label: 'Knox Henderson' },
				],
			},
			{
				label: 'Austin',
				children: [{ label: 'Downtown' }, { label: 'South Congress' }, { label: 'East Austin' }],
			},
			{
				label: 'San Antonio',
				children: [
					{ label: 'Downtown' },
					{ label: 'Alamo Heights' },
					{ label: 'Pearl District' },
					{ label: 'King William' },
					{ label: 'Stone Oak' },
				],
			},
		],
	},
	{
		label: 'Illinois',
		children: [
			{
				label: 'Chicago',
				children: [
					{ label: 'Loop' },
					{ label: 'River North' },
					{ label: 'Lincoln Park' },
					{ label: 'Wicker Park' },
					{ label: 'Gold Coast' },
					{ label: 'Lakeview' },
				],
			},
			{
				label: 'Springfield',
				children: [
					{ label: 'Downtown' },
					{ label: 'West Side' },
					{ label: 'East Side' },
					{ label: 'North End' },
					{ label: 'South Side' },
					{ label: 'Jerome' },
				],
			},
			{
				label: 'Rockford',
				children: [
					{ label: 'Downtown' },
					{ label: 'East Side' },
					{ label: 'North End' },
					{ label: 'Rural Oaks' },
					{ label: 'Churchill Grove' },
					{ label: 'Signal Hill' },
				],
			},
			{
				label: 'Peoria',
				children: [
					{ label: 'Downtown' },
					{ label: 'West Bluff' },
					{ label: 'East Bluff' },
					{ label: 'North Valley' },
					{ label: 'South Side' },
				],
			},
		],
	},
	{
		label: 'New York',
		children: [
			{
				label: 'New York City',
				children: [
					{ label: 'Manhattan' },
					{ label: 'Brooklyn' },
					{ label: 'Queens' },
					{ label: 'The Bronx' },
					{ label: 'Staten Island' },
					{ label: 'Harlem' },
				],
			},
		],
	},
	{
		label: 'Washington',
		children: [
			{
				label: 'Seattle',
				children: [
					{ label: 'Downtown' },
					{ label: 'Capitol Hill' },
					{ label: 'Ballard' },
					{ label: 'Fremont' },
					{ label: 'Queen Anne' },
					{ label: 'South Lake Union' },
				],
			},
			{
				label: 'Spokane',
				children: [
					{ label: 'Downtown' },
					{ label: 'South Hill' },
					{ label: 'North Side' },
					{ label: 'West Central' },
					{ label: 'East Central' },
					{ label: 'Riverside' },
				],
			},
			{
				label: 'Tacoma',
				children: [
					{ label: 'Downtown' },
					{ label: 'North End' },
					{ label: 'South End' },
					{ label: 'East Side' },
					{ label: 'West End' },
					{ label: 'Central' },
				],
			},
			{
				label: 'Vancouver',
				children: [
					{ label: 'Downtown' },
					{ label: 'Uptown' },
					{ label: 'Hazel Dell' },
					{ label: 'Salmon Creek' },
					{ label: "Fisher's Landing" },
					{ label: 'Cascade Park' },
				],
			},
			{
				label: 'Bellevue',
				children: [
					{ label: 'Downtown' },
					{ label: 'West Bellevue' },
					{ label: 'Crossroads' },
					{ label: 'Eastgate' },
					{ label: 'Factoria' },
				],
			},
		],
	},
];
const linkagDiffLabelKeyData = [
	{
		province: 'California',
		children: [
			{
				city: 'Los Angeles',
				children: [
					{ region: 'Downtown' },
					{ region: 'Hollywood' },
					{ region: 'Beverly Hills' },
					{ region: 'Santa Monica' },
					{ region: 'Pasadena' },
					{ region: 'Venice Beach' },
					{ region: 'Westwood' },
				],
			},
			{
				city: 'San Francisco',
				children: [
					{ region: 'Downtown' },
					{ region: 'Mission District' },
					{ region: 'North Beach' },
					{ region: 'Chinatown' },
					{ region: 'Haight-Ashbury' },
					{ region: 'Castro' },
				],
			},
			{
				city: 'San Diego',
				children: [
					{ region: 'Downtown' },
					{ region: 'La Jolla' },
					{ region: 'Pacific Beach' },
					{ region: 'Mission Beach' },
					{ region: 'Coronado' },
					{ region: 'North Park' },
				],
			},
		],
	},
	{
		province: 'Florida',
		children: [
			{
				city: 'Miami',
				children: [
					{ region: 'Downtown' },
					{ region: 'South Beach' },
					{ region: 'Brickell' },
					{ region: 'Coconut Grove' },
					{ region: 'Little Havana' },
					{ region: 'Coral Gables' },
				],
			},
			{
				city: 'Orlando',
				children: [
					{ region: 'Downtown' },
					{ region: 'Winter Park' },
					{ region: 'Lake Nona' },
					{ region: 'College Park' },
					{ region: 'Baldwin Park' },
					{ region: 'Mills 50' },
				],
			},
			{
				city: 'Tampa',
				children: [{ region: 'Downtown' }, { region: 'Hyde Park' }, { region: 'Ybor City' }, { region: 'Channelside' }],
			},
		],
	},
	{
		province: 'Illinois',
		children: [
			{
				city: 'Chicago',
				children: [
					{ region: 'Loop' },
					{ region: 'River North' },
					{ region: 'Lincoln Park' },
					{ region: 'Wicker Park' },
					{ region: 'Gold Coast' },
					{ region: 'Lakeview' },
				],
			},
			{
				city: 'Springfield',
				children: [
					{ region: 'Downtown' },
					{ region: 'West Side' },
					{ region: 'East Side' },
					{ region: 'North End' },
					{ region: 'South Side' },
					{ region: 'Jerome' },
				],
			},
			{
				city: 'Peoria',
				children: [
					{ region: 'Downtown' },
					{ region: 'West Bluff' },
					{ region: 'East Bluff' },
					{ region: 'North Valley' },
					{ region: 'South Side' },
				],
			},
		],
	},
	{
		province: 'New York',
		children: [
			{
				city: 'New York City',
				children: [
					{ region: 'Manhattan' },
					{ region: 'Brooklyn' },
					{ region: 'Queens' },
					{ region: 'The Bronx' },
					{ region: 'Staten Island' },
					{ region: 'Harlem' },
				],
			},
		],
	},
];
const linkagCustomChildrenKeyData = [
	{
		label: 'California',
		child: [
			{
				label: 'Los Angeles',
				child: [
					{ label: 'Downtown' },
					{ label: 'Hollywood' },
					{ label: 'Beverly Hills' },
					{ label: 'Santa Monica' },
					{ label: 'Pasadena' },
					{ label: 'Venice Beach' },
					{ label: 'Westwood' },
				],
			},
			{
				label: 'San Francisco',
				child: [
					{ label: 'Downtown' },
					{ label: 'Mission District' },
					{ label: 'North Beach' },
					{ label: 'Chinatown' },
					{ label: 'Haight-Ashbury' },
					{ label: 'Castro' },
				],
			},
			{
				label: 'San Diego',
				child: [
					{ label: 'Downtown' },
					{ label: 'La Jolla' },
					{ label: 'Pacific Beach' },
					{ label: 'Mission Beach' },
					{ label: 'Coronado' },
					{ label: 'North Park' },
				],
			},
		],
	},
	{
		label: 'Florida',
		child: [
			{
				label: 'Miami',
				child: [
					{ label: 'Downtown' },
					{ label: 'South Beach' },
					{ label: 'Brickell' },
					{ label: 'Coconut Grove' },
					{ label: 'Little Havana' },
					{ label: 'Coral Gables' },
				],
			},
			{
				label: 'Orlando',
				child: [
					{ label: 'Downtown' },
					{ label: 'Winter Park' },
					{ label: 'Lake Nona' },
					{ label: 'College Park' },
					{ label: 'Baldwin Park' },
					{ label: 'Mills 50' },
				],
			},
			{
				label: 'Tampa',
				child: [{ label: 'Downtown' }, { label: 'Hyde Park' }, { label: 'Ybor City' }, { label: 'Channelside' }],
			},
		],
	},
	{
		label: 'Illinois',
		child: [
			{
				label: 'Chicago',
				child: [
					{ label: 'Loop' },
					{ label: 'River North' },
					{ label: 'Lincoln Park' },
					{ label: 'Wicker Park' },
					{ label: 'Gold Coast' },
					{ label: 'Lakeview' },
				],
			},
			{
				label: 'Springfield',
				child: [
					{ label: 'Downtown' },
					{ label: 'West Side' },
					{ label: 'East Side' },
					{ label: 'North End' },
					{ label: 'South Side' },
					{ label: 'Jerome' },
				],
			},
			{
				label: 'Peoria',
				child: [
					{ label: 'Downtown' },
					{ label: 'West Bluff' },
					{ label: 'East Bluff' },
					{ label: 'North Valley' },
					{ label: 'South Side' },
				],
			},
		],
	},
	{
		label: 'New York',
		child: [
			{
				label: 'New York City',
				child: [
					{ label: 'Manhattan' },
					{ label: 'Brooklyn' },
					{ label: 'Queens' },
					{ label: 'The Bronx' },
					{ label: 'Staten Island' },
					{ label: 'Harlem' },
				],
			},
		],
	},
	{
		label: 'Washington',
		child: [
			{
				label: 'Seattle',
				child: [
					{ label: 'Downtown' },
					{ label: 'Capitol Hill' },
					{ label: 'Ballard' },
					{ label: 'Fremont' },
					{ label: 'Queen Anne' },
					{ label: 'South Lake Union' },
				],
			},
			{
				label: 'Spokane',
				child: [
					{ label: 'Downtown' },
					{ label: 'South Hill' },
					{ label: 'North Side' },
					{ label: 'West Central' },
					{ label: 'East Central' },
					{ label: 'Riverside' },
				],
			},
			{
				label: 'Tacoma',
				child: [
					{ label: 'Downtown' },
					{ label: 'North End' },
					{ label: 'South End' },
					{ label: 'East Side' },
					{ label: 'West End' },
					{ label: 'Central' },
				],
			},
		],
	},
];

export { someProvinceList, weekList, amOrPmList, timeList, cityList, linkageData, linkagDiffLabelKeyData, linkagCustomChildrenKeyData };



================================================
FILE: packages/stdf/src/routes/picker/zh_CN/+page.svelte
================================================
<!-- Picker Demo -->
<script lang="ts">
	import { Picker, Cell } from '$lib/index.js';
	// 为避免 Demo 页面杂乱，具体参考数据放在 data.js 文件内，可查看此页面底部注释。
	import {
		someProvinceList,
		weekList,
		amOrPmList,
		timeList,
		cityList,
		linkageData,
		linkagDiffLabelKeyData,
		linkagCustomChildrenKeyData
	} from './data.js';

	const datas = [{ data: someProvinceList }];

	const col3Datas = [{ data: weekList }, { data: amOrPmList }, { data: timeList }];

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);
	let visible15 = $state(false);
	let visible16 = $state(false);
	let visible17 = $state(false);
	let visible18 = $state(false);
	let visible19 = $state(false);
	let visible20 = $state(false);
	let visible21 = $state(false);
	let visible22 = $state(false);

	let currentDetail = $state('请选择');
	let allItems: { [key: string]: string }[] = $state([]);
	let allIndexs: number[] = $state([]);
</script>

<div class="py-4">
	<Cell title="基础用法" onclick={() => (visible1 = true)} />
	<Picker bind:visible={visible1} {datas} />

	<Cell title="自定义标题" onclick={() => (visible2 = true)} />
	<Picker bind:visible={visible2} title="请选择省份" {datas} />

	<Cell title="可见 7 行" onclick={() => (visible3 = true)} />
	<Picker bind:visible={visible3} datas={[{ data: someProvinceList, showRow: 7 }]} />

	<Cell title="关闭自动滚动至上次选定项" onclick={() => (visible4 = true)} />
	<Picker bind:visible={visible4} {datas} autoScrollToLast={false} />

	<Cell title="初始选定始终为第 4 项" onclick={() => (visible5 = true)} subTitle="需要关闭自动选定上次选中项" />
	<Picker bind:visible={visible5} datas={[{ data: someProvinceList, initIndex: 3 }]} autoScrollToLast={false} />

	<Cell title="自动滚动时取消动画" onclick={() => (visible6 = true)} />
	<Picker bind:visible={visible6} datas={[{ data: someProvinceList, useAnimation: false }]} />

	<Cell title="自定义 label 的 key 值" onclick={() => (visible7 = true)} />
	<Picker bind:visible={visible7} datas={[{ data: cityList, labelKey: 'cityName' }]} title="请选择城市" />

	<Cell title="右侧展示选定项" detail={currentDetail} onclick={() => (visible8 = true)} />
	<Picker bind:visible={visible8} {datas} onconfirm={(items) => (currentDetail = items[0].label)} />

	<Cell title="单列左对齐" onclick={() => (visible20 = true)} />
	<Picker bind:visible={visible20} datas={[{ data: someProvinceList, align: 'left' }]} />

	<Cell title="多列选择器" onclick={() => (visible9 = true)} />
	<Picker bind:visible={visible9} datas={col3Datas} />

	<Cell title="不同列可见行数" onclick={() => (visible10 = true)} />
	<Picker bind:visible={visible10} datas={[{ data: weekList }, { data: amOrPmList, showRow: 3 }, { data: timeList, showRow: 7 }]} />

	<Cell title="不同列 flex 比例" onclick={() => (visible11 = true)} />
	<Picker
		bind:visible={visible11}
		datas={[
			{ data: weekList, flex: 3 },
			{ data: amOrPmList, flex: 1 },
			{ data: timeList, flex: 2 }
		]}
	/>

	<Cell title="多列不同对齐方式" onclick={() => (visible21 = true)} />
	<Picker
		bind:visible={visible21}
		datas={[
			{ data: weekList, align: 'left' },
			{ data: amOrPmList, align: 'center' },
			{ data: timeList, align: 'right' }
		]}
	/>

	<Cell title="多级联动" onclick={() => (visible12 = true)} />
	<Picker bind:visible={visible12} datas={linkageData} isLinkage />

	<Cell title="多级联动不同可见行数" onclick={() => (visible13 = true)} />
	<Picker bind:visible={visible13} datas={linkageData} linkageShowRows={[3, 5, 7]} isLinkage />

	<Cell title="多级联动不同 flex 比例" onclick={() => (visible14 = true)} />
	<Picker bind:visible={visible14} datas={linkageData} linkageFlexs={[1, 2, 3]} isLinkage />

	<Cell title="多级联动自定义每级 label 的 key 值" onclick={() => (visible15 = true)} />
	<Picker bind:visible={visible15} datas={linkagDiffLabelKeyData} linkageLabelKeys={['province', 'city', 'region']} isLinkage />

	<Cell title="多级联动自定义上下级 children 的 key 值" onclick={() => (visible16 = true)} />
	<Picker bind:visible={visible16} datas={linkagCustomChildrenKeyData} linkageChildrenKey="child" isLinkage />

	<Cell title="联动不同对齐方式" onclick={() => (visible22 = true)} />
	<Picker bind:visible={visible22} datas={linkageData} linkageAligns={['right', 'center', 'left']} isLinkage />

	<Cell title="多级联动设置每列初始选定项" onclick={() => (visible17 = true)} />
	<Picker bind:visible={visible17} datas={linkageData} linkageInitIndexs={[0, 1, 8]} isLinkage />

	<div class="px-4">
		{#if allItems.length}
			当前选定了：
			{#each allItems as item}
				<span class="mr-2 text-primary dark:text-dark">{item.label}</span>
			{/each}
		{:else}
			<div>请选定数据</div>
		{/if}
	</div>
	<div class="px-4">
		{#if allIndexs.length}
			当前选定值位于所在列的索引值分别为：
			{#each allIndexs as index}
				<span class="mr-2 text-primary dark:text-dark">{index}</span>
			{/each}
		{:else}
			<div>请选定数据</div>
		{/if}
	</div>
	<Cell title="获取选定数据" onclick={() => (visible18 = true)} />
	<Picker
		bind:visible={visible18}
		datas={col3Datas}
		onconfirm={(items, indexs) => {
			allItems = items;
			allIndexs = indexs;
		}}
	/>

	<Cell title="顶部来点圆角" onclick={() => (visible19 = true)} />
	<Picker bind:visible={visible19} {datas} popup={{ radius: 'xl' }} />
</div>

<!-- data.js -->
<!-- 
const someProvinceList = [
    { label: '云南' },
    { label: '北京' },
    { label: '广东' },
    { label: '重庆' },
    { label: '四川' },
    { label: '湖北' },
    { label: '河南' },
    { label: '湖南' },
    { label: '山东' },
    { label: '江苏' },
    { label: '浙江' },
    { label: '江西' },
    { label: '安徽' },
    { label: '福建' },
];
const weekList = [
    { label: '星期一' },
    { label: '星期二' },
    { label: '星期三' },
    { label: '星期四' },
    { label: '星期五' },
    { label: '星期六' },
    { label: '星期日' },
];
const amOrPmList = [{ label: '上午' }, { label: '下午' }];
const timeList = [
    { label: '01:00' },
    { label: '02:00' },
    { label: '03:00' },
    { label: '04:00' },
    { label: '05:00' },
    { label: '06:00' },
    { label: '07:00' },
    { label: '08:00' },
    { label: '09:00' },
    { label: '10:00' },
    { label: '11:00' },
    { label: '12:00' },
];
const cityList = [
    { cityName: '昆明' },
    { cityName: '曲靖' },
    { cityName: '玉溪' },
    { cityName: '保山' },
    { cityName: '昭通' },
    { cityName: '丽江' },
    { cityName: '普洱' },
    { cityName: '临沧' },
    { cityName: '楚雄' },
    { cityName: '红河' },
    { cityName: '文山' },
];
const linkageData = [
    {
        label: '云南',
        children: [
            {
                label: '昆明',
                children: [
                    { label: '盘龙区' },
                    { label: '五华区' },
                    { label: '官渡区' },
                    { label: '西山区' },
                    { label: '东川区' },
                    { label: '呈贡区' },
                    { label: '晋宁区' },
                    { label: '富民县' },
                    { label: '宜良县' },
                    { label: '石林彝族自治县' },
                    { label: '嵩明县' },
                    { label: '禄劝彝族苗族自治县' },
                    { label: '寻甸回族彝族自治县' },
                    { label: '安宁市' },
                ],
            },
            {
                label: '曲靖',
                children: [
                    { label: '麒麟区' },
                    { label: '沾益区' },
                    { label: '马龙县' },
                    { label: '陆良县' },
                    { label: '师宗县' },
                    { label: '罗平县' },
                    { label: '富源县' },
                    { label: '会泽县' },
                    { label: '宣威市' },
                ],
            },
            {
                label: '玉溪',
                children: [
                    { label: '红塔区' },
                    { label: '江川区' },
                    { label: '澄江县' },
                    { label: '通海县' },
                    { label: '华宁县' },
                    { label: '易门县' },
                    { label: '峨山彝族自治县' },
                    { label: '新平彝族傣族自治县' },
                    { label: '元江哈尼族彝族傣族自治县' },
                ],
            },
            {
                label: '保山',
                children: [
                    { label: '隆阳区' },
                    { label: '施甸县' },
                    { label: '龙陵县' },
                    { label: '昌宁县' },
                    { label: '腾冲市' },
                    { label: '龙陵县' },
                ],
            },
            {
                label: '丽江',
                children: [
                    { label: '古城区' },
                    { label: '永胜县' },
                    { label: '华坪县' },
                    { label: '玉龙纳西族自治县' },
                    { label: '宁蒗彝族自治县' },
                ],
            },
            {
                label: '普洱',
                children: [
                    { label: '思茅区' },
                    { label: '宁洱哈尼族彝族自治县' },
                    { label: '墨江哈尼族自治县' },
                    { label: '景东彝族自治县' },
                    { label: '景谷傣族彝族自治县' },
                    { label: '镇沅彝族哈尼族拉祜族自治县' },
                    { label: '江城哈尼族彝族自治县' },
                    { label: '孟连傣族拉祜族佤族自治县' },
                    { label: '澜沧拉祜族自治县' },
                    { label: '西盟佤族自治县' },
                ],
            },
            {
                label: '临沧',
                children: [
                    { label: '临翔区' },
                    { label: '凤庆县' },
                    { label: '云县' },
                    { label: '永德县' },
                    { label: '镇康县' },
                    { label: '双江拉祜族佤族布朗族傣族自治县' },
                    { label: '耿马傣族佤族自治县' },
                    { label: '沧源佤族自治县' },
                ],
            },
            {
                label: '楚雄',
                children: [
                    { label: '楚雄市' },
                    { label: '双柏县' },
                    { label: '牟定县' },
                    { label: '南华县' },
                    { label: '姚安县' },
                    { label: '大姚县' },
                    { label: '永仁县' },
                    { label: '元谋县' },
                    { label: '武定县' },
                    { label: '禄丰县' },
                ],
            },
            {
                label: '红河',
                children: [
                    { label: '个旧市' },
                    { label: '开远市' },
                    { label: '蒙自市' },
                    { label: '弥勒市' },
                    { label: '屏边苗族自治县' },
                    { label: '建水县' },
                    { label: '石屏县' },
                    { label: '泸西县' },
                    { label: '元阳县' },
                    { label: '红河县' },
                    { label: '金平苗族瑶族傣族自治县' },
                    { label: '绿春县' },
                    { label: '河口瑶族自治县' },
                ],
            },
            {
                label: '文山',
                children: [
                    { label: '文山市' },
                    { label: '砚山县' },
                    { label: '西畴县' },
                    { label: '麻栗坡县' },
                    { label: '马关县' },
                    { label: '丘北县' },
                    { label: '广南县' },
                    { label: '富宁县' },
                ],
            },
        ],
    },
    {
        label: '广东',
        children: [
            {
                label: '广州',
                children: [
                    { label: '天河区' },
                    { label: '海珠区' },
                    { label: '荔湾区' },
                    { label: '越秀区' },
                    { label: '白云区' },
                    { label: '黄埔区' },
                ],
            },
            {
                label: '深圳',
                children: [
                    { label: '罗湖区' },
                    { label: '福田区' },
                    { label: '南山区' },
                    { label: '宝安区' },
                    { label: '龙岗区' },
                    { label: '盐田区' },
                ],
            },
            {
                label: '珠海',
                children: [{ label: '香洲区' }, { label: '斗门区' }, { label: '金湾区' }],
            },
            {
                label: '汕头',
                children: [
                    { label: '龙湖区' },
                    { label: '金平区' },
                    { label: '濠江区' },
                    { label: '潮阳区' },
                    { label: '潮南区' },
                    { label: '澄海区' },
                ],
            },
            {
                label: '佛山',
                children: [{ label: '禅城区' }, { label: '南海区' }, { label: '顺德区' }, { label: '三水区' }, { label: '高明区' }],
            },
        ],
    },
    {
        label: '四川',
        children: [
            {
                label: '成都',
                children: [
                    { label: '锦江区' },
                    { label: '青羊区' },
                    { label: '金牛区' },
                    { label: '武侯区' },
                    { label: '成华区' },
                    { label: '龙泉驿区' },
                ],
            },
            {
                label: '绵阳',
                children: [
                    { label: '涪城区' },
                    { label: '游仙区' },
                    { label: '安州区' },
                    { label: '三台县' },
                    { label: '盐亭县' },
                    { label: '梓潼县' },
                ],
            },
            {
                label: '自贡',
                children: [
                    { label: '自流井区' },
                    { label: '贡井区' },
                    { label: '大安区' },
                    { label: '沿滩区' },
                    { label: '荣县' },
                    { label: '富顺县' },
                ],
            },
            {
                label: '攀枝花',
                children: [{ label: '东区' }, { label: '西区' }, { label: '仁和区' }, { label: '米易县' }, { label: '盐边县' }],
            },
        ],
    },
    {
        label: '北京',
        children: [
            {
                label: '北京市',
                children: [
                    { label: '东城区' },
                    { label: '西城区' },
                    { label: '朝阳区' },
                    { label: '丰台区' },
                    { label: '石景山区' },
                    { label: '海淀区' },
                ],
            },
        ],
    },
    {
        label: '浙江',
        children: [
            {
                label: '杭州',
                children: [
                    { label: '上城区' },
                    { label: '下城区' },
                    { label: '江干区' },
                    { label: '拱墅区' },
                    { label: '西湖区' },
                    { label: '滨江区' },
                ],
            },
            {
                label: '宁波',
                children: [
                    { label: '海曙区' },
                    { label: '江东区' },
                    { label: '江北区' },
                    { label: '北仑区' },
                    { label: '镇海区' },
                    { label: '鄞州区' },
                ],
            },
            {
                label: '温州',
                children: [
                    { label: '鹿城区' },
                    { label: '龙湾区' },
                    { label: '瓯海区' },
                    { label: '洞头区' },
                    { label: '永嘉县' },
                    { label: '平阳县' },
                ],
            },
            {
                label: '嘉兴',
                children: [
                    { label: '南湖区' },
                    { label: '秀洲区' },
                    { label: '嘉善县' },
                    { label: '海盐县' },
                    { label: '海宁市' },
                    { label: '平湖市' },
                ],
            },
            {
                label: '湖州',
                children: [{ label: '吴兴区' }, { label: '南浔区' }, { label: '德清县' }, { label: '长兴县' }, { label: '安吉县' }],
            },
        ],
    },
];
const linkagDiffLabelKeyData = [
    {
        province: '云南',
        children: [
            {
                city: '昆明',
                children: [
                    { region: '盘龙区' },
                    { region: '五华区' },
                    { region: '官渡区' },
                    { region: '西山区' },
                    { region: '东川区' },
                    { region: '呈贡区' },
                    { region: '晋宁区' },
                ],
            },
            {
                city: '曲靖',
                children: [
                    { region: '麒麟区' },
                    { region: '沾益区' },
                    { region: '马龙县' },
                    { region: '陆良县' },
                    { region: '师宗县' },
                    { region: '罗平县' },
                ],
            },
            {
                city: '玉溪',
                children: [
                    { region: '红塔区' },
                    { region: '江川区' },
                    { region: '澄江县' },
                    { region: '通海县' },
                    { region: '华宁县' },
                    { region: '易门县' },
                ],
            },
        ],
    },
    {
        province: '贵州',
        children: [
            {
                city: '贵阳',
                children: [
                    { region: '南明区' },
                    { region: '云岩区' },
                    { region: '花溪区' },
                    { region: '乌当区' },
                    { region: '白云区' },
                    { region: '观山湖区' },
                ],
            },
            {
                city: '遵义',
                children: [
                    { region: '红花岗区' },
                    { region: '汇川区' },
                    { region: '播州区' },
                    { region: '桐梓县' },
                    { region: '绥阳县' },
                    { region: '正安县' },
                ],
            },
            {
                city: '六盘水',
                children: [{ region: '钟山区' }, { region: '六枝特区' }, { region: '水城县' }, { region: '盘县' }],
            },
        ],
    },
    {
        province: '四川',
        children: [
            {
                city: '成都',
                children: [
                    { region: '锦江区' },
                    { region: '青羊区' },
                    { region: '金牛区' },
                    { region: '武侯区' },
                    { region: '成华区' },
                    { region: '龙泉驿区' },
                ],
            },
            {
                city: '绵阳',
                children: [
                    { region: '涪城区' },
                    { region: '游仙区' },
                    { region: '安州区' },
                    { region: '三台县' },
                    { region: '盐亭县' },
                    { region: '梓潼县' },
                ],
            },
            {
                city: '攀枝花',
                children: [{ region: '东区' }, { region: '西区' }, { region: '仁和区' }, { region: '米易县' }, { region: '盐边县' }],
            },
        ],
    },
    {
        province: '北京',
        children: [
            {
                city: '北京',
                children: [
                    { region: '东城区' },
                    { region: '西城区' },
                    { region: '朝阳区' },
                    { region: '丰台区' },
                    { region: '石景山区' },
                    { region: '海淀区' },
                ],
            },
        ],
    },
];
const linkagCustomChildrenKeyData = [
    {
        label: '云南',
        child: [
            {
                label: '昆明',
                child: [
                    { label: '盘龙区' },
                    { label: '五华区' },
                    { label: '官渡区' },
                    { label: '西山区' },
                    { label: '东川区' },
                    { label: '呈贡区' },
                    { label: '晋宁区' },
                ],
            },
            {
                label: '曲靖',
                child: [
                    { label: '麒麟区' },
                    { label: '沾益区' },
                    { label: '马龙县' },
                    { label: '陆良县' },
                    { label: '师宗县' },
                    { label: '罗平县' },
                ],
            },
            {
                label: '玉溪',
                child: [
                    { label: '红塔区' },
                    { label: '江川区' },
                    { label: '澄江县' },
                    { label: '通海县' },
                    { label: '华宁县' },
                    { label: '易门县' },
                ],
            },
        ],
    },
    {
        label: '贵州',
        child: [
            {
                label: '贵阳',
                child: [
                    { label: '南明区' },
                    { label: '云岩区' },
                    { label: '花溪区' },
                    { label: '乌当区' },
                    { label: '白云区' },
                    { label: '观山湖区' },
                ],
            },
            {
                label: '遵义',
                child: [
                    { label: '红花岗区' },
                    { label: '汇川区' },
                    { label: '播州区' },
                    { label: '桐梓县' },
                    { label: '绥阳县' },
                    { label: '正安县' },
                ],
            },
            {
                label: '六盘水',
                child: [{ label: '钟山区' }, { label: '六枝特区' }, { label: '水城县' }, { label: '盘县' }],
            },
        ],
    },
    {
        label: '四川',
        child: [
            {
                label: '成都',
                child: [
                    { label: '锦江区' },
                    { label: '青羊区' },
                    { label: '金牛区' },
                    { label: '武侯区' },
                    { label: '成华区' },
                    { label: '龙泉驿区' },
                ],
            },
            {
                label: '绵阳',
                child: [
                    { label: '涪城区' },
                    { label: '游仙区' },
                    { label: '安州区' },
                    { label: '三台县' },
                    { label: '盐亭县' },
                    { label: '梓潼县' },
                ],
            },
            {
                label: '攀枝花',
                child: [{ label: '东区' }, { label: '西区' }, { label: '仁和区' }, { label: '米易县' }, { label: '盐边县' }],
            },
        ],
    },
    {
        label: '北京',
        child: [
            {
                label: '北京',
                child: [
                    { label: '东城区' },
                    { label: '西城区' },
                    { label: '朝阳区' },
                    { label: '丰台区' },
                    { label: '石景山区' },
                    { label: '海淀区' },
                ],
            },
        ],
    },
    {
        label: '浙江',
        child: [
            {
                label: '杭州',
                child: [
                    { label: '西湖区' },
                    { label: '上城区' },
                    { label: '下城区' },
                    { label: '江干区' },
                    { label: '拱墅区' },
                    { label: '滨江区' },
                ],
            },
            {
                label: '宁波',
                child: [
                    { label: '海曙区' },
                    { label: '江东区' },
                    { label: '江北区' },
                    { label: '北仑区' },
                    { label: '镇海区' },
                    { label: '鄞州区' },
                ],
            },
            {
                label: '温州',
                child: [
                    { label: '鹿城区' },
                    { label: '龙湾区' },
                    { label: '瓯海区' },
                    { label: '洞头区' },
                    { label: '永嘉县' },
                    { label: '平阳县' },
                ],
            },
        ],
    },
];

export { someProvinceList, weekList, amOrPmList, timeList, cityList, linkageData, linkagDiffLabelKeyData, linkagCustomChildrenKeyData };
-->



================================================
FILE: packages/stdf/src/routes/picker/zh_CN/data.js
================================================
const someProvinceList = [
	{ label: '云南' },
	{ label: '北京' },
	{ label: '广东' },
	{ label: '重庆' },
	{ label: '四川' },
	{ label: '湖北' },
	{ label: '河南' },
	{ label: '湖南' },
	{ label: '山东' },
	{ label: '江苏' },
	{ label: '浙江' },
	{ label: '江西' },
	{ label: '安徽' },
	{ label: '福建' },
];
const weekList = [
	{ label: '星期一' },
	{ label: '星期二' },
	{ label: '星期三' },
	{ label: '星期四' },
	{ label: '星期五' },
	{ label: '星期六' },
	{ label: '星期日' },
];
const amOrPmList = [{ label: '上午' }, { label: '下午' }];
const timeList = [
	{ label: '01:00' },
	{ label: '02:00' },
	{ label: '03:00' },
	{ label: '04:00' },
	{ label: '05:00' },
	{ label: '06:00' },
	{ label: '07:00' },
	{ label: '08:00' },
	{ label: '09:00' },
	{ label: '10:00' },
	{ label: '11:00' },
	{ label: '12:00' },
];
const cityList = [
	{ cityName: '昆明' },
	{ cityName: '曲靖' },
	{ cityName: '玉溪' },
	{ cityName: '保山' },
	{ cityName: '昭通' },
	{ cityName: '丽江' },
	{ cityName: '普洱' },
	{ cityName: '临沧' },
	{ cityName: '楚雄' },
	{ cityName: '红河' },
	{ cityName: '文山' },
];
const linkageData = [
	{
		label: '云南',
		children: [
			{
				label: '昆明',
				children: [
					{ label: '盘龙区' },
					{ label: '五华区' },
					{ label: '官渡区' },
					{ label: '西山区' },
					{ label: '东川区' },
					{ label: '呈贡区' },
					{ label: '晋宁区' },
					{ label: '富民县' },
					{ label: '宜良县' },
					{ label: '石林彝族自治县' },
					{ label: '嵩明县' },
					{ label: '禄劝彝族苗族自治县' },
					{ label: '寻甸回族彝族自治县' },
					{ label: '安宁市' },
				],
			},
			{
				label: '曲靖',
				children: [
					{ label: '麒麟区' },
					{ label: '沾益区' },
					{ label: '马龙县' },
					{ label: '陆良县' },
					{ label: '师宗县' },
					{ label: '罗平县' },
					{ label: '富源县' },
					{ label: '会泽县' },
					{ label: '宣威市' },
				],
			},
			{
				label: '玉溪',
				children: [
					{ label: '红塔区' },
					{ label: '江川区' },
					{ label: '澄江县' },
					{ label: '通海县' },
					{ label: '华宁县' },
					{ label: '易门县' },
					{ label: '峨山彝族自治县' },
					{ label: '新平彝族傣族自治县' },
					{ label: '元江哈尼族彝族傣族自治县' },
				],
			},
			{
				label: '保山',
				children: [
					{ label: '隆阳区' },
					{ label: '施甸县' },
					{ label: '龙陵县' },
					{ label: '昌宁县' },
					{ label: '腾冲市' },
					{ label: '龙陵县' },
				],
			},
			{
				label: '丽江',
				children: [
					{ label: '古城区' },
					{ label: '永胜县' },
					{ label: '华坪县' },
					{ label: '玉龙纳西族自治县' },
					{ label: '宁蒗彝族自治县' },
				],
			},
			{
				label: '普洱',
				children: [
					{ label: '思茅区' },
					{ label: '宁洱哈尼族彝族自治县' },
					{ label: '墨江哈尼族自治县' },
					{ label: '景东彝族自治县' },
					{ label: '景谷傣族彝族自治县' },
					{ label: '镇沅彝族哈尼族拉祜族自治县' },
					{ label: '江城哈尼族彝族自治县' },
					{ label: '孟连傣族拉祜族佤族自治县' },
					{ label: '澜沧拉祜族自治县' },
					{ label: '西盟佤族自治县' },
				],
			},
			{
				label: '临沧',
				children: [
					{ label: '临翔区' },
					{ label: '凤庆县' },
					{ label: '云县' },
					{ label: '永德县' },
					{ label: '镇康县' },
					{ label: '双江拉祜族佤族布朗族傣族自治县' },
					{ label: '耿马傣族佤族自治县' },
					{ label: '沧源佤族自治县' },
				],
			},
			{
				label: '楚雄',
				children: [
					{ label: '楚雄市' },
					{ label: '双柏县' },
					{ label: '牟定县' },
					{ label: '南华县' },
					{ label: '姚安县' },
					{ label: '大姚县' },
					{ label: '永仁县' },
					{ label: '元谋县' },
					{ label: '武定县' },
					{ label: '禄丰县' },
				],
			},
			{
				label: '红河',
				children: [
					{ label: '个旧市' },
					{ label: '开远市' },
					{ label: '蒙自市' },
					{ label: '弥勒市' },
					{ label: '屏边苗族自治县' },
					{ label: '建水县' },
					{ label: '石屏县' },
					{ label: '泸西县' },
					{ label: '元阳县' },
					{ label: '红河县' },
					{ label: '金平苗族瑶族傣族自治县' },
					{ label: '绿春县' },
					{ label: '河口瑶族自治县' },
				],
			},
			{
				label: '文山',
				children: [
					{ label: '文山市' },
					{ label: '砚山县' },
					{ label: '西畴县' },
					{ label: '麻栗坡县' },
					{ label: '马关县' },
					{ label: '丘北县' },
					{ label: '广南县' },
					{ label: '富宁县' },
				],
			},
		],
	},
	{
		label: '广东',
		children: [
			{
				label: '广州',
				children: [
					{ label: '天河区' },
					{ label: '海珠区' },
					{ label: '荔湾区' },
					{ label: '越秀区' },
					{ label: '白云区' },
					{ label: '黄埔区' },
				],
			},
			{
				label: '深圳',
				children: [
					{ label: '罗湖区' },
					{ label: '福田区' },
					{ label: '南山区' },
					{ label: '宝安区' },
					{ label: '龙岗区' },
					{ label: '盐田区' },
				],
			},
			{
				label: '珠海',
				children: [{ label: '香洲区' }, { label: '斗门区' }, { label: '金湾区' }],
			},
			{
				label: '汕头',
				children: [
					{ label: '龙湖区' },
					{ label: '金平区' },
					{ label: '濠江区' },
					{ label: '潮阳区' },
					{ label: '潮南区' },
					{ label: '澄海区' },
				],
			},
			{
				label: '佛山',
				children: [{ label: '禅城区' }, { label: '南海区' }, { label: '顺德区' }, { label: '三水区' }, { label: '高明区' }],
			},
		],
	},
	{
		label: '四川',
		children: [
			{
				label: '成都',
				children: [
					{ label: '锦江区' },
					{ label: '青羊区' },
					{ label: '金牛区' },
					{ label: '武侯区' },
					{ label: '成华区' },
					{ label: '龙泉驿区' },
				],
			},
			{
				label: '绵阳',
				children: [
					{ label: '涪城区' },
					{ label: '游仙区' },
					{ label: '安州区' },
					{ label: '三台县' },
					{ label: '盐亭县' },
					{ label: '梓潼县' },
				],
			},
			{
				label: '自贡',
				children: [
					{ label: '自流井区' },
					{ label: '贡井区' },
					{ label: '大安区' },
					{ label: '沿滩区' },
					{ label: '荣县' },
					{ label: '富顺县' },
				],
			},
			{
				label: '攀枝花',
				children: [{ label: '东区' }, { label: '西区' }, { label: '仁和区' }, { label: '米易县' }, { label: '盐边县' }],
			},
		],
	},
	{
		label: '北京',
		children: [
			{
				label: '北京市',
				children: [
					{ label: '东城区' },
					{ label: '西城区' },
					{ label: '朝阳区' },
					{ label: '丰台区' },
					{ label: '石景山区' },
					{ label: '海淀区' },
				],
			},
		],
	},
	{
		label: '浙江',
		children: [
			{
				label: '杭州',
				children: [
					{ label: '上城区' },
					{ label: '下城区' },
					{ label: '江干区' },
					{ label: '拱墅区' },
					{ label: '西湖区' },
					{ label: '滨江区' },
				],
			},
			{
				label: '宁波',
				children: [
					{ label: '海曙区' },
					{ label: '江东区' },
					{ label: '江北区' },
					{ label: '北仑区' },
					{ label: '镇海区' },
					{ label: '鄞州区' },
				],
			},
			{
				label: '温州',
				children: [
					{ label: '鹿城区' },
					{ label: '龙湾区' },
					{ label: '瓯海区' },
					{ label: '洞头区' },
					{ label: '永嘉县' },
					{ label: '平阳县' },
				],
			},
			{
				label: '嘉兴',
				children: [
					{ label: '南湖区' },
					{ label: '秀洲区' },
					{ label: '嘉善县' },
					{ label: '海盐县' },
					{ label: '海宁市' },
					{ label: '平湖市' },
				],
			},
			{
				label: '湖州',
				children: [{ label: '吴兴区' }, { label: '南浔区' }, { label: '德清县' }, { label: '长兴县' }, { label: '安吉县' }],
			},
		],
	},
];
const linkagDiffLabelKeyData = [
	{
		province: '云南',
		children: [
			{
				city: '昆明',
				children: [
					{ region: '盘龙区' },
					{ region: '五华区' },
					{ region: '官渡区' },
					{ region: '西山区' },
					{ region: '东川区' },
					{ region: '呈贡区' },
					{ region: '晋宁区' },
				],
			},
			{
				city: '曲靖',
				children: [
					{ region: '麒麟区' },
					{ region: '沾益区' },
					{ region: '马龙县' },
					{ region: '陆良县' },
					{ region: '师宗县' },
					{ region: '罗平县' },
				],
			},
			{
				city: '玉溪',
				children: [
					{ region: '红塔区' },
					{ region: '江川区' },
					{ region: '澄江县' },
					{ region: '通海县' },
					{ region: '华宁县' },
					{ region: '易门县' },
				],
			},
		],
	},
	{
		province: '贵州',
		children: [
			{
				city: '贵阳',
				children: [
					{ region: '南明区' },
					{ region: '云岩区' },
					{ region: '花溪区' },
					{ region: '乌当区' },
					{ region: '白云区' },
					{ region: '观山湖区' },
				],
			},
			{
				city: '遵义',
				children: [
					{ region: '红花岗区' },
					{ region: '汇川区' },
					{ region: '播州区' },
					{ region: '桐梓县' },
					{ region: '绥阳县' },
					{ region: '正安县' },
				],
			},
			{
				city: '六盘水',
				children: [{ region: '钟山区' }, { region: '六枝特区' }, { region: '水城县' }, { region: '盘县' }],
			},
		],
	},
	{
		province: '四川',
		children: [
			{
				city: '成都',
				children: [
					{ region: '锦江区' },
					{ region: '青羊区' },
					{ region: '金牛区' },
					{ region: '武侯区' },
					{ region: '成华区' },
					{ region: '龙泉驿区' },
				],
			},
			{
				city: '绵阳',
				children: [
					{ region: '涪城区' },
					{ region: '游仙区' },
					{ region: '安州区' },
					{ region: '三台县' },
					{ region: '盐亭县' },
					{ region: '梓潼县' },
				],
			},
			{
				city: '攀枝花',
				children: [{ region: '东区' }, { region: '西区' }, { region: '仁和区' }, { region: '米易县' }, { region: '盐边县' }],
			},
		],
	},
	{
		province: '北京',
		children: [
			{
				city: '北京',
				children: [
					{ region: '东城区' },
					{ region: '西城区' },
					{ region: '朝阳区' },
					{ region: '丰台区' },
					{ region: '石景山区' },
					{ region: '海淀区' },
				],
			},
		],
	},
];
const linkagCustomChildrenKeyData = [
	{
		label: '云南',
		child: [
			{
				label: '昆明',
				child: [
					{ label: '盘龙区' },
					{ label: '五华区' },
					{ label: '官渡区' },
					{ label: '西山区' },
					{ label: '东川区' },
					{ label: '呈贡区' },
					{ label: '晋宁区' },
				],
			},
			{
				label: '曲靖',
				child: [
					{ label: '麒麟区' },
					{ label: '沾益区' },
					{ label: '马龙县' },
					{ label: '陆良县' },
					{ label: '师宗县' },
					{ label: '罗平县' },
				],
			},
			{
				label: '玉溪',
				child: [
					{ label: '红塔区' },
					{ label: '江川区' },
					{ label: '澄江县' },
					{ label: '通海县' },
					{ label: '华宁县' },
					{ label: '易门县' },
				],
			},
		],
	},
	{
		label: '贵州',
		child: [
			{
				label: '贵阳',
				child: [
					{ label: '南明区' },
					{ label: '云岩区' },
					{ label: '花溪区' },
					{ label: '乌当区' },
					{ label: '白云区' },
					{ label: '观山湖区' },
				],
			},
			{
				label: '遵义',
				child: [
					{ label: '红花岗区' },
					{ label: '汇川区' },
					{ label: '播州区' },
					{ label: '桐梓县' },
					{ label: '绥阳县' },
					{ label: '正安县' },
				],
			},
			{
				label: '六盘水',
				child: [{ label: '钟山区' }, { label: '六枝特区' }, { label: '水城县' }, { label: '盘县' }],
			},
		],
	},
	{
		label: '四川',
		child: [
			{
				label: '成都',
				child: [
					{ label: '锦江区' },
					{ label: '青羊区' },
					{ label: '金牛区' },
					{ label: '武侯区' },
					{ label: '成华区' },
					{ label: '龙泉驿区' },
				],
			},
			{
				label: '绵阳',
				child: [
					{ label: '涪城区' },
					{ label: '游仙区' },
					{ label: '安州区' },
					{ label: '三台县' },
					{ label: '盐亭县' },
					{ label: '梓潼县' },
				],
			},
			{
				label: '攀枝花',
				child: [{ label: '东区' }, { label: '西区' }, { label: '仁和区' }, { label: '米易县' }, { label: '盐边县' }],
			},
		],
	},
	{
		label: '北京',
		child: [
			{
				label: '北京',
				child: [
					{ label: '东城区' },
					{ label: '西城区' },
					{ label: '朝阳区' },
					{ label: '丰台区' },
					{ label: '石景山区' },
					{ label: '海淀区' },
				],
			},
		],
	},
	{
		label: '浙江',
		child: [
			{
				label: '杭州',
				child: [
					{ label: '西湖区' },
					{ label: '上城区' },
					{ label: '下城区' },
					{ label: '江干区' },
					{ label: '拱墅区' },
					{ label: '滨江区' },
				],
			},
			{
				label: '宁波',
				child: [
					{ label: '海曙区' },
					{ label: '江东区' },
					{ label: '江北区' },
					{ label: '北仑区' },
					{ label: '镇海区' },
					{ label: '鄞州区' },
				],
			},
			{
				label: '温州',
				child: [
					{ label: '鹿城区' },
					{ label: '龙湾区' },
					{ label: '瓯海区' },
					{ label: '洞头区' },
					{ label: '永嘉县' },
					{ label: '平阳县' },
				],
			},
		],
	},
];

export { someProvinceList, weekList, amOrPmList, timeList, cityList, linkageData, linkagDiffLabelKeyData, linkagCustomChildrenKeyData };



================================================
FILE: packages/stdf/src/routes/placeholder/en_US/+page.svelte
================================================
<!-- Placeholder Demo -->
<script lang="ts">
	import { Placeholder, Grids, Grid } from '$lib/index.js';
</script>

<div class="m-4 text-lg font-bold">Basic usage</div>
<Placeholder>Basic usage</Placeholder>

<div class="m-4 text-lg font-bold">Set height</div>
<Placeholder height="32">High for 32</Placeholder>

<div class="m-4 text-lg font-bold">Different fillet</div>
<div class="flex flex-col space-y-4">
	<Placeholder radius="none">unfillet</Placeholder>
	<Placeholder radius="xl">XL Rounded corner</Placeholder>
	<Placeholder radius="full">Full fillet</Placeholder>
</div>

<div class="m-4 text-lg font-bold">shaded</div>
<Placeholder shadow="md">shadow</Placeholder>

<div class="m-4 text-lg font-bold">customize injClass</div>
<Placeholder height="24" injClass="!bg-gradient-to-r from-[#CE9FFC] to-[#7367F0] !text-white">Gradient background</Placeholder>

<div class="m-4 text-lg font-bold">Combined with Grids</div>
<Grids>
	<Grid row="3" col="2"><Placeholder>3﹡2</Placeholder></Grid>
	<Grid col="3"><Placeholder>1﹡3</Placeholder></Grid>
	<Grid row="3"><Placeholder>3﹡1</Placeholder></Grid>
	<Grid row="2" col="2"><Placeholder>2﹡2</Placeholder></Grid>
	<Grid><Placeholder>1﹡1</Placeholder></Grid>
	<Grid><Placeholder>1﹡1</Placeholder></Grid>
</Grids>
<div class="pb-4"></div>



================================================
FILE: packages/stdf/src/routes/placeholder/zh_CN/+page.svelte
================================================
<!-- Placeholder Demo -->
<script lang="ts">
	import { Placeholder, Grids, Grid } from '$lib/index.js';
</script>

<div class="m-4 text-lg font-bold">基础用法</div>
<Placeholder>基础用法</Placeholder>

<div class="m-4 text-lg font-bold">设置高度</div>
<Placeholder height="32">高为 32</Placeholder>

<div class="m-4 text-lg font-bold">不同圆角</div>
<div class="flex flex-col space-y-4">
	<Placeholder radius="none">无圆角</Placeholder>
	<Placeholder radius="xl">XL 圆角</Placeholder>
	<Placeholder radius="full">全圆角</Placeholder>
</div>

<div class="m-4 text-lg font-bold">有阴影</div>
<Placeholder shadow="md">阴影</Placeholder>

<div class="m-4 text-lg font-bold">自定义 injClass</div>
<Placeholder height="24" injClass="!bg-gradient-to-r from-[#CE9FFC] to-[#7367F0] !text-white">渐变背景</Placeholder>

<div class="m-4 text-lg font-bold">与 Grids 结合</div>
<Grids>
	<Grid row="3" col="2"><Placeholder>3﹡2</Placeholder></Grid>
	<Grid col="3"><Placeholder>1﹡3</Placeholder></Grid>
	<Grid row="3"><Placeholder>3﹡1</Placeholder></Grid>
	<Grid row="2" col="2"><Placeholder>2﹡2</Placeholder></Grid>
	<Grid><Placeholder>1﹡1</Placeholder></Grid>
	<Grid><Placeholder>1﹡1</Placeholder></Grid>
</Grids>
<div class="pb-4"></div>



================================================
FILE: packages/stdf/src/routes/popup/en_US/+page.svelte
================================================
<!-- Popup Demo -->
<script lang="ts">
	import { Cell, Popup, Button, Icon } from '$lib/index.js';
	import Aphorism from '../../components/Aphorism.svelte';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);
	let visible15 = $state(false);
	let visible16 = $state(false);
	let visible17 = $state(false);
	let visible18 = $state(false);
	let visible19 = $state(false);
	let visible20 = $state(false);
	let visible21 = $state(false);
</script>

<div class="py-4">
	<Cell title="Basic usage" onclick={() => (visible1 = true)} />
	<Popup bind:visible={visible1} />

	<Cell title="Top position" onclick={() => (visible2 = true)} />
	<Popup bind:visible={visible2} position="top" />

	<Cell title="Left position" onclick={() => (visible3 = true)} />
	<Popup bind:visible={visible3} position="left" />

	<Cell title="Right side position" onclick={() => (visible4 = true)} />
	<Popup bind:visible={visible4} position="right" />

	<Cell title="Intermediate position" onclick={() => (visible5 = true)} />
	<Popup bind:visible={visible5} position="center" />

	<Cell title="Rounded corners at the top" onclick={() => (visible6 = true)} />
	<Popup bind:visible={visible6} radius="xl" />

	<Cell title="Have rounded corners and spacing" onclick={() => (visible7 = true)} />
	<Popup bind:visible={visible7} radiusPosition="all" radius="3xl" px="4" py="4" />

	<Cell title="The center is spaced and rounded" onclick={() => (visible10 = true)} />
	<Popup bind:visible={visible10} position="center" radiusPosition="all" radius="xl" px="8" />

	<Cell title="Set animation easing to appear" detail="rebound" onclick={() => (visible11 = true)} />
	<Popup bind:visible={visible11} position="center" radiusPosition="all" radius="xl" px="8" easeType="backOut" />

	<Cell title="Let's replace it with a slow animation" detail="bounce" onclick={() => (visible16 = true)} />
	<Popup bind:visible={visible16} easeType="bounceOut" />

	<Cell title="Different size" onclick={() => (visible8 = true)} />
	<Popup bind:visible={visible8} size={80} />

	<Cell title="The left side has different sizes" onclick={() => (visible9 = true)} />
	<Popup bind:visible={visible9} size={80} position="left" />

	<Cell title="The mask is completely transparent and fuzzy" onclick={() => (visible12 = true)} />
	<Popup bind:visible={visible12} position="center" radiusPosition="all" radius="xl" px="8" mask={{ opacity: '0', backdropBlur: 'sm' }} />

	<Cell title="Clicking the mask does not close" onclick={() => (visible13 = true)} />
	<Popup bind:visible={visible13} maskClosable={false}>
		<div class="flex h-full flex-col justify-center">
			<Button onclick={() => (visible13 = false)}>Shut down</Button>
		</div>
	</Popup>

	<Cell title="Size automatic" detail="Depends on internal elements" onclick={() => (visible14 = true)} />
	<Popup bind:visible={visible14} size={0} radiusPosition="all" radius="3xl" px="4" py="4" transitionDistance={353}>
		<div class="w-full text-center">
			<div class="py-6 text-xl font-bold">AirPods Pro connected</div>
			<div class="m-auto w-1/2">
				<img class="w-full object-cover" src="/assets/images/airpods-pro2.png" alt="" />
			</div>
			<div class="text-primary dark:text-dark flex justify-around py-6">
				<div>set</div>
				<div>music</div>
			</div>
		</div>
	</Popup>

	<Cell title="The left position is automatically sized" onclick={() => (visible20 = true)} />
	<Popup bind:visible={visible20} size={0} position="left" py="48" radiusPosition="right" radius="2xl" transitionDistance={80}>
		<div class="text-primary dark:text-dark flex h-full flex-col justify-around">
			<button class="p-6" onclick={() => (visible20 = false)}>Home</button>
			<button class="p-6" onclick={() => (visible20 = false)}>Setting</button>
			<button class="p-6" onclick={() => (visible20 = false)}>About</button>
		</div>
	</Popup>

	<Cell title="Size automatic background transparent" onclick={() => (visible17 = true)} />
	<Popup bind:visible={visible17} position="top" size={0} px="4" py="8" transparent transitionDistance={136}>
		<div class="flex w-full justify-between rounded-full bg-black p-3 text-white">
			<div class="flex">
				<div class="h-12 w-12 overflow-hidden rounded-full">
					<img class="w-full object-cover" src="/assets/images/avatar_1.jpg" alt="" />
				</div>
				<div class="flex flex-col justify-end pl-4">
					<div class="text-xs text-white/40">Mobile phone</div>
					<div>Hu Ge</div>
				</div>
			</div>
			<div class="flex space-x-3">
				<div class="flex h-12 w-12 flex-col items-center justify-center rounded-full bg-[#ff3b30]" style="transform: rotate(135deg);">
					<Icon name="ri-phone-fill" />
				</div>
				<div class="flex h-12 w-12 flex-col items-center justify-center rounded-full bg-[#4cd964]">
					<Icon name="ri-phone-fill" />
				</div>
			</div>
		</div>
	</Popup>

	<Cell title="The center position has a transparent background" onclick={() => (visible18 = true)} />
	<Popup bind:visible={visible18} size={0} position="center" transparent>
		<div class="flex flex-col justify-center">
			<div class="m-auto w-1/2">
				<img class="w-full object-cover" src="/assets/images/airpods-pro2.png" alt="" />
			</div>
		</div>
	</Popup>

	<Cell title="Reverse color mask" onclick={() => (visible15 = true)} />
	<Popup bind:visible={visible15} mask={{ inverse: true }} />

	<Cell title="Overflow roll" onclick={() => (visible19 = true)} />
	<Popup bind:visible={visible19} size={30} position="center">
		<Aphorism num={4} />
	</Popup>

	<Cell title="allow body roll" onclick={() => (visible21 = true)} />
	<Popup bind:visible={visible21} allowBodyScroll />
</div>

<!-- Aphorism.svelte -->
<!-- 
<script lang="ts">
	// 引入数据
	// import data
	import aphorisms from '../../data/aphorisms';

	/**
	 * @typedef {Object} Props
	 * @property {number} [num] - number of items to display
	 * @property {boolean} [compact] - whether to use compact mode
	 */
	/** @type {Props} */
	let { num = 0, compact = false } = $props();

	// 从 aphorisms 随机取出 num 条数据
	// get num items from aphorisms randomly
	const aphorismsList = aphorisms.sort(() => Math.random() - 0.5).slice(0, num);
</script>

<div class="{compact ? '' : 'px-4 py-8 '}divide-y divide-black/5 dark:divide-white/5">
	{#each aphorismsList as item}
		<div class:py-6={num > 1}>
			<div class="text-sm text-justify">{item.text}</div>
			<div class="text-right mt-1" class:italic={item.fromItalic}>{item.from}</div>
		</div>
	{/each}
</div>
-->



================================================
FILE: packages/stdf/src/routes/popup/zh_CN/+page.svelte
================================================
<!-- Popup Demo -->
<script lang="ts">
	import { Cell, Popup, Button, Icon } from '$lib/index.js';
	import Aphorism from '../../components/Aphorism.svelte';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);
	let visible15 = $state(false);
	let visible16 = $state(false);
	let visible17 = $state(false);
	let visible18 = $state(false);
	let visible19 = $state(false);
	let visible20 = $state(false);
	let visible21 = $state(false);
</script>

<div class="py-4">
	<Cell title="基础用法" onclick={() => (visible1 = true)} />
	<Popup bind:visible={visible1} />

	<Cell title="顶部位置" onclick={() => (visible2 = true)} />
	<Popup bind:visible={visible2} position="top" />

	<Cell title="左侧位置" onclick={() => (visible3 = true)} />
	<Popup bind:visible={visible3} position="left" />

	<Cell title="右侧位置" onclick={() => (visible4 = true)} />
	<Popup bind:visible={visible4} position="right" />

	<Cell title="中间位置" onclick={() => (visible5 = true)} />
	<Popup bind:visible={visible5} position="center" />

	<Cell title="顶部位置有圆角" onclick={() => (visible6 = true)} />
	<Popup bind:visible={visible6} radius="xl" />

	<Cell title="有圆角和间距" onclick={() => (visible7 = true)} />
	<Popup bind:visible={visible7} radiusPosition="all" radius="3xl" px="4" py="4" />

	<Cell title="中间位置有间距和圆角" onclick={() => (visible10 = true)} />
	<Popup bind:visible={visible10} position="center" radiusPosition="all" radius="xl" px="8" />

	<Cell title="设置出现动画缓动" detail="回弹" onclick={() => (visible11 = true)} />
	<Popup bind:visible={visible11} position="center" radiusPosition="all" radius="xl" px="8" easeType="backOut" />

	<Cell title="换一个出现动画缓动" detail="弹跳" onclick={() => (visible16 = true)} />
	<Popup bind:visible={visible16} easeType="bounceOut" />

	<Cell title="不同大小" onclick={() => (visible8 = true)} />
	<Popup bind:visible={visible8} size={80} />

	<Cell title="左侧位置不同大小" onclick={() => (visible9 = true)} />
	<Popup bind:visible={visible9} size={80} position="left" />

	<Cell title="遮罩完全透明且模糊" onclick={() => (visible12 = true)} />
	<Popup bind:visible={visible12} position="center" radiusPosition="all" radius="xl" px="8" mask={{ opacity: '0', backdropBlur: 'sm' }} />

	<Cell title="点击遮罩不会关闭" onclick={() => (visible13 = true)} />
	<Popup bind:visible={visible13} maskClosable={false}>
		<div class="flex h-full flex-col justify-center">
			<Button onclick={() => (visible13 = false)}>关闭</Button>
		</div>
	</Popup>

	<Cell title="大小自动" detail="取决于内部元素" onclick={() => (visible14 = true)} />
	<Popup bind:visible={visible14} size={0} radiusPosition="all" radius="3xl" px="4" py="4" transitionDistance={353}>
		<div class="w-full text-center">
			<div class="py-6 text-xl font-bold">AirPods Pro 已连接</div>
			<div class="m-auto w-1/2">
				<img class="w-full object-cover" src="/assets/images/airpods-pro2.png" alt="" />
			</div>
			<div class="text-primary dark:text-dark flex justify-around py-6">
				<div>设置</div>
				<div>音乐</div>
			</div>
		</div>
	</Popup>

	<Cell title="左侧位置自动大小" onclick={() => (visible20 = true)} />
	<Popup bind:visible={visible20} size={0} position="left" py="48" radiusPosition="right" radius="2xl" transitionDistance={80}>
		<div class="text-primary dark:text-dark flex h-full flex-col justify-around">
			<button class="p-6" onclick={() => (visible20 = false)}>首页</button>
			<button class="p-6" onclick={() => (visible20 = false)}>设置</button>
			<button class="p-6" onclick={() => (visible20 = false)}>关于</button>
		</div>
	</Popup>

	<Cell title="大小自动背景透明" onclick={() => (visible17 = true)} />
	<Popup bind:visible={visible17} position="top" size={0} px="4" py="8" transparent transitionDistance={136}>
		<div class="flex w-full justify-between rounded-full bg-black p-3 text-white">
			<div class="flex">
				<div class="h-12 w-12 overflow-hidden rounded-full">
					<img class="w-full object-cover" src="/assets/images/avatar_1.jpg" alt="" />
				</div>
				<div class="flex flex-col justify-end pl-4">
					<div class="text-xs text-white/40">手机</div>
					<div>胡歌</div>
				</div>
			</div>
			<div class="flex space-x-3">
				<div class="flex h-12 w-12 flex-col items-center justify-center rounded-full bg-[#ff3b30]" style="transform: rotate(135deg);">
					<Icon name="ri-phone-fill" />
				</div>
				<div class="flex h-12 w-12 flex-col items-center justify-center rounded-full bg-[#4cd964]">
					<Icon name="ri-phone-fill" />
				</div>
			</div>
		</div>
	</Popup>

	<Cell title="居中位置背景透明" onclick={() => (visible18 = true)} />
	<Popup bind:visible={visible18} size={0} position="center" transparent>
		<div class="flex flex-col justify-center">
			<div class="m-auto w-1/2">
				<img class="w-full object-cover" src="/assets/images/airpods-pro2.png" alt="" />
			</div>
		</div>
	</Popup>

	<Cell title="反色遮罩" onclick={() => (visible15 = true)} />
	<Popup bind:visible={visible15} mask={{ inverse: true }} />

	<Cell title="溢出滚动" onclick={() => (visible19 = true)} />
	<Popup bind:visible={visible19} size={30} position="center">
		<Aphorism num={4} />
	</Popup>

	<Cell title="允许 body 滚动" onclick={() => (visible21 = true)} />
	<Popup bind:visible={visible21} allowBodyScroll />
</div>

<!-- Aphorism.svelte -->
<!-- 
<script lang="ts">
	// 引入数据
	// import data
	import aphorisms from '../../data/aphorisms.js';

	/**
	 * @typedef {Object} Props
	 * @property {number} [num] - number of items to display
	 * @property {boolean} [compact] - whether to use compact mode
	 */
	/** @type {Props} */
	let { num = 0, compact = false } = $props();

	// 从 aphorisms 随机取出 num 条数据
	// get num items from aphorisms randomly
	const aphorismsList = aphorisms.sort(() => Math.random() - 0.5).slice(0, num);
</script>

<div class="{compact ? '' : 'px-4 py-8 '}divide-y divide-black/5 dark:divide-white/5">
	{#each aphorismsList as item}
		<div class:py-6={num > 1}>
			<div class="text-justify text-sm">{item.text}</div>
			<div class="mt-1 text-right" class:italic={item.fromItalic}>{item.from}</div>
		</div>
	{/each}
</div>
-->



================================================
FILE: packages/stdf/src/routes/progress/en_US/+page.svelte
================================================
<!--Progress Demo-->
<script lang="ts">
	import { Progress, Button } from '$lib/index.js';

	let percent = $state(20);
	const changePercentFun = (type: string) => {
		if (type === '+10') {
			percent = percent >= 100 ? 100 : percent + 10;
		} else {
			percent = percent <= 0 ? 0 : percent - 10;
		}
	};
</script>

<div class="px-4 pb-8">
	<div class="m-4 mt-8 text-lg font-bold">Basic usage</div>
	<Progress />

	<div class="m-4 mt-8 text-lg font-bold">Different heights</div>
	<div class="flex flex-col space-y-4">
		<Progress height="1" />
		<Progress height="2" />
		<Progress height="3" />
		<Progress height="4" />
	</div>

	<div class="m-4 mt-8 text-lg font-bold">Percentage different position</div>
	<div class="flex flex-col space-y-4">
		<Progress />
		<Progress percentPosition="inner" />
		<Progress percentPosition="block" />
		<Progress percentPosition={null} />
	</div>

	<div class="m-4 mt-8 text-lg font-bold">Different styles of rounded corners</div>
	<div class="flex flex-col space-y-4">
		<Progress radius="none" />
		<Progress radius="middle" />
		<Progress radius="none" percentPosition="block" />
		<Progress radius="middle" percentPosition="block" />
		<Progress percentPosition="block" />
	</div>

	<div class="m-4 mt-8 text-lg font-bold">Ash setting</div>
	<div class="flex flex-col space-y-4">
		<Progress inactive />
		<Progress inactive percentPosition="block" />
	</div>

	<div class="m-4 mt-8 text-lg font-bold">Transition effect</div>
	<div class="mb-4 flex flex-col space-y-4 px-2">
		<Progress {percent} />
		<Progress {percent} percentPosition="inner" />
		<Progress {percent} percentPosition="block" />
		<Progress {percent} duration="500" />
		<Progress {percent} duration="1000" />
	</div>
	<Button heightIn="0" group size="full">
		<div class="flex w-full">
			<button class="flex-1 border-r border-white py-2 active:opacity-80 dark:border-black" onclick={() => changePercentFun('-10')}>
				-10
			</button>
			<button class="flex-1 border-r border-white py-2 active:opacity-80 dark:border-black" onclick={() => changePercentFun('+10')}>
				+10
			</button>
			<button class="flex-1 py-2 active:opacity-80" onclick={() => (percent = 20)}>Reset</button>
		</div>
	</Button>

	<div class="m-4 mt-8 text-lg font-bold">Custom color</div>
	<div class="flex flex-col space-y-4">
		<Progress injClass="bg-success dark:bg-error" />
		<Progress injClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0]" />
		<Progress percentPosition="block" injClass="bg-[#FF9F7D] dark:bg-[#9e4f5e]" />
		<Progress trackInjClass="!bg-primary/20 dark:!bg-dark/20" />
	</div>

	<div class="m-4 mt-8 text-lg font-bold">Custom text</div>
	<div class="flex flex-col space-y-4">
		<Progress>
			<div class="whitespace-nowrap text-xs">completed 2/3</div>
		</Progress>
		<Progress percentPosition="block">
			<div class="whitespace-nowrap text-xs">completed 2/3</div>
		</Progress>
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/progress/zh_CN/+page.svelte
================================================
<!--Progress Demo-->
<script lang="ts">
	import { Progress, Button } from '$lib/index.js';

	let percent = $state(20);
	const changePercentFun = (type: string) => {
		if (type === '+10') {
			percent = percent >= 100 ? 100 : percent + 10;
		} else {
			percent = percent <= 0 ? 0 : percent - 10;
		}
	};
</script>

<div class="px-4 pb-8">
	<div class="m-4 mt-8 text-lg font-bold">基础用法</div>
	<Progress />

	<div class="m-4 mt-8 text-lg font-bold">不同高度</div>
	<div class="flex flex-col space-y-4">
		<Progress height="1" />
		<Progress height="2" />
		<Progress height="3" />
		<Progress height="4" />
	</div>

	<div class="m-4 mt-8 text-lg font-bold">百分比不同位置</div>
	<div class="flex flex-col space-y-4">
		<Progress />
		<Progress percentPosition="inner" />
		<Progress percentPosition="block" />
		<Progress percentPosition={null} />
	</div>

	<div class="m-4 mt-8 text-lg font-bold">不同圆角风格</div>
	<div class="flex flex-col space-y-4">
		<Progress radius="none" />
		<Progress radius="middle" />
		<Progress radius="none" percentPosition="block" />
		<Progress radius="middle" percentPosition="block" />
		<Progress percentPosition="block" />
	</div>

	<div class="m-4 mt-8 text-lg font-bold">禁用</div>
	<div class="flex flex-col space-y-4">
		<Progress inactive />
		<Progress inactive percentPosition="block" />
	</div>

	<div class="m-4 mt-8 text-lg font-bold">过渡效果</div>
	<div class="mb-4 flex flex-col space-y-4 px-2">
		<Progress {percent} />
		<Progress {percent} percentPosition="inner" />
		<Progress {percent} percentPosition="block" />
		<Progress {percent} duration="500" />
		<Progress {percent} duration="1000" />
	</div>
	<Button heightIn="0" group size="full">
		<div class="flex w-full">
			<button class="flex-1 border-r border-white py-2 active:opacity-80 dark:border-black" onclick={() => changePercentFun('-10')}>
				-10
			</button>
			<button class="flex-1 border-r border-white py-2 active:opacity-80 dark:border-black" onclick={() => changePercentFun('+10')}>
				+10
			</button>
			<button class="flex-1 py-2 active:opacity-80" onclick={() => (percent = 20)}>重置</button>
		</div>
	</Button>

	<div class="m-4 mt-8 text-lg font-bold">自定义颜色</div>
	<div class="flex flex-col space-y-4">
		<Progress injClass="bg-success dark:bg-error" />
		<Progress injClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0]" />
		<Progress percentPosition="block" injClass="bg-[#FF9F7D] dark:bg-[#9e4f5e]" />
		<Progress trackInjClass="!bg-primary/20 dark:!bg-dark/20" />
	</div>

	<div class="m-4 mt-8 text-lg font-bold">自定义文字</div>
	<div class="flex flex-col space-y-4">
		<Progress>
			<div class="whitespace-nowrap text-xs">已完成 2/3</div>
		</Progress>
		<Progress percentPosition="block">
			<div class="whitespace-nowrap text-xs">已完成 2/3</div>
		</Progress>
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/progressLoop/en_US/+page.svelte
================================================
<!--ProgressLoop Demo-->
<script lang="ts">
	import { ProgressLoop, Button } from '$lib/index.js';

	let percent = $state(20);
	const changePercentFun = (type: string) => {
		if (type === '+10') {
			percent = percent >= 100 ? 100 : percent + 10;
		} else {
			percent = percent <= 0 ? 0 : percent - 10;
		}
	};
</script>

<div class="m-4 mt-8 text-lg font-bold">Basic usage</div>
<div class="mx-4 w-1/3">
	<ProgressLoop />
</div>

<div class="m-4 mt-8 text-lg font-bold">Different width</div>
<div class="mx-4 flex grow gap-4">
	<div class="flex-1">
		<ProgressLoop strokeWidth={0.5} />
	</div>
	<div class="flex-1">
		<ProgressLoop strokeWidth={1} />
	</div>
	<div class="flex-1">
		<ProgressLoop strokeWidth={6} />
	</div>
</div>

<div class="m-4 mt-8 text-lg font-bold">Straight end</div>
<div class="mx-4 w-1/3">
	<ProgressLoop butt />
</div>

<div class="m-4 mt-8 text-lg font-bold">Counterclockwise direction</div>
<div class="mx-4 w-1/3">
	<ProgressLoop reverse />
</div>

<div class="m-4 mt-8 text-lg font-bold">Custom color</div>
<div class="m-4 flex grow gap-2">
	<div class="flex-1">
		<ProgressLoop injClass="stroke-success dark:stroke-error" />
	</div>
	<div class="flex-1">
		<ProgressLoop gradient={['#CE9FFC', '#7367F0']} />
	</div>
	<div class="flex-1">
		<ProgressLoop gradient={['#CE9FFC', '#7367F0']} reverse />
	</div>
	<div class="flex-1">
		<ProgressLoop trackInjClass="!stroke-primary/20 dark:!stroke-dark/20" />
	</div>
</div>

<div class="m-4 mt-8 text-lg font-bold">Custom text</div>
<div class="m-4 flex grow gap-2">
	<div class="flex-1">
		<ProgressLoop>
			<div class="text-center text-xs">
				<div>Completed</div>
				<div class="text-primary dark:text-dark text-lg">6666</div>
				<div>step</div>
			</div>
		</ProgressLoop>
	</div>
	<div class="flex-1">
		<ProgressLoop>
			<div class="text-center text-xs">
				<div>Residual flow</div>
				<div class="text-primary dark:text-dark text-lg">66</div>
				<div>GB</div>
			</div>
		</ProgressLoop>
	</div>
	<div class="flex-1">
		<ProgressLoop>
			<div class="text-xs">complete 2/3</div>
		</ProgressLoop>
	</div>
</div>

<div class="m-4 mb-1 mt-8 text-lg font-bold">Transition effect</div>
<div class="mx-4 text-xs">Different end points, ring width, direction, transition time, color</div>
<div class="m-4 flex grow gap-2">
	<div class="flex-1">
		<ProgressLoop {percent} />
	</div>
	<div class="flex-1">
		<ProgressLoop {percent} butt />
	</div>
	<div class="flex-1">
		<ProgressLoop {percent} strokeWidth={4} />
	</div>
	<div class="flex-1">
		<ProgressLoop {percent} reverse />
	</div>
</div>
<div class="m-4 flex grow gap-2">
	<div class="flex-1">
		<ProgressLoop {percent} duration="150" />
	</div>
	<div class="flex-1">
		<ProgressLoop {percent} duration="500" />
	</div>
	<div class="flex-1">
		<ProgressLoop {percent} duration="1000" />
	</div>
	<div class="flex-1">
		<ProgressLoop {percent} gradient={['#CE9FFC', '#7367F0']} />
	</div>
</div>
<div class="mx-4 pb-8">
	<Button heightIn="0" group size="full">
		<div class="flex w-full">
			<button class="flex-1 border-r border-white py-2 active:opacity-80 dark:border-black" onclick={() => changePercentFun('-10')}>
				-10
			</button>
			<button class="flex-1 border-r border-white py-2 active:opacity-80 dark:border-black" onclick={() => changePercentFun('+10')}>
				+10
			</button>
			<button class="flex-1 py-2 active:opacity-80" onclick={() => (percent = 20)}>Reset</button>
		</div>
	</Button>
</div>



================================================
FILE: packages/stdf/src/routes/progressLoop/zh_CN/+page.svelte
================================================
<!--ProgressLoop Demo-->
<script lang="ts">
	import { ProgressLoop, Button } from '$lib/index.js';

	let percent = $state(20);
	const changePercentFun = (type: string) => {
		if (type === '+10') {
			percent = percent >= 100 ? 100 : percent + 10;
		} else {
			percent = percent <= 0 ? 0 : percent - 10;
		}
	};
</script>

<div class="m-4 mt-8 text-lg font-bold">基础用法</div>
<div class="mx-4 w-1/3">
	<ProgressLoop />
</div>

<div class="m-4 mt-8 text-lg font-bold">不同宽度</div>
<div class="mx-4 flex grow gap-4">
	<div class="flex-1">
		<ProgressLoop strokeWidth={0.5} />
	</div>
	<div class="flex-1">
		<ProgressLoop strokeWidth={1} />
	</div>
	<div class="flex-1">
		<ProgressLoop strokeWidth={6} />
	</div>
</div>

<div class="m-4 mt-8 text-lg font-bold">直边端点</div>
<div class="mx-4 w-1/3">
	<ProgressLoop butt />
</div>

<div class="m-4 mt-8 text-lg font-bold">逆时针方向</div>
<div class="mx-4 w-1/3">
	<ProgressLoop reverse />
</div>

<div class="m-4 mt-8 text-lg font-bold">自定义颜色</div>
<div class="m-4 flex grow gap-2">
	<div class="flex-1">
		<ProgressLoop injClass="stroke-success dark:stroke-error" />
	</div>
	<div class="flex-1">
		<ProgressLoop gradient={['#CE9FFC', '#7367F0']} />
	</div>
	<div class="flex-1">
		<ProgressLoop gradient={['#CE9FFC', '#7367F0']} reverse />
	</div>
	<div class="flex-1">
		<ProgressLoop trackInjClass="!stroke-primary/20 dark:!stroke-dark/20" />
	</div>
</div>

<div class="m-4 mt-8 text-lg font-bold">自定义文字</div>
<div class="m-4 flex grow gap-2">
	<div class="flex-1">
		<ProgressLoop>
			<div class="text-center text-xs">
				<div>已完成</div>
				<div class="text-primary dark:text-dark text-lg">6666</div>
				<div>步</div>
			</div>
		</ProgressLoop>
	</div>
	<div class="flex-1">
		<ProgressLoop>
			<div class="text-center text-xs">
				<div>剩余流量</div>
				<div class="text-primary dark:text-dark text-lg">66</div>
				<div>GB</div>
			</div>
		</ProgressLoop>
	</div>
	<div class="flex-1">
		<ProgressLoop>
			<div class="text-xs">完成 2/3</div>
		</ProgressLoop>
	</div>
</div>

<div class="m-4 mb-1 mt-8 text-lg font-bold">过渡效果</div>
<div class="mx-4 text-xs">不同端点、圆环宽度、方向、过渡时间、颜色</div>
<div class="m-4 flex grow gap-2">
	<div class="flex-1">
		<ProgressLoop {percent} />
	</div>
	<div class="flex-1">
		<ProgressLoop {percent} butt />
	</div>
	<div class="flex-1">
		<ProgressLoop {percent} strokeWidth={4} />
	</div>
	<div class="flex-1">
		<ProgressLoop {percent} reverse />
	</div>
</div>
<div class="m-4 flex grow gap-2">
	<div class="flex-1">
		<ProgressLoop {percent} duration="150" />
	</div>
	<div class="flex-1">
		<ProgressLoop {percent} duration="500" />
	</div>
	<div class="flex-1">
		<ProgressLoop {percent} duration="1000" />
	</div>
	<div class="flex-1">
		<ProgressLoop {percent} gradient={['#CE9FFC', '#7367F0']} />
	</div>
</div>
<div class="mx-4 pb-8">
	<Button heightIn="0" group size="full">
		<div class="flex w-full">
			<button class="flex-1 border-r border-white py-2 active:opacity-80 dark:border-black" onclick={() => changePercentFun('-10')}>
				-10
			</button>
			<button class="flex-1 border-r border-white py-2 active:opacity-80 dark:border-black" onclick={() => changePercentFun('+10')}>
				+10
			</button>
			<button class="flex-1 py-2 active:opacity-80" onclick={() => (percent = 20)}>重置</button>
		</div>
	</Button>
</div>



================================================
FILE: packages/stdf/src/routes/radio/en_US/+page.svelte
================================================
<!-- Radio Demo -->
<script lang="ts">
	import { Radio, Divider, Button, Icon } from '$lib/index.js';
	import type { RadioItemProps } from '$lib/types/index.js';

	const dota: RadioItemProps[] = [
		{ label: 'Jugg', name: 'Juggernaut' },
		{ label: 'SB', name: 'Spirit Breaker' },
		{ label: 'KOTL', name: 'Keeper of the Light' },
		{ label: 'Mag', name: 'Magnus' }
	];
	let value = $state(dota[0].name);
	let checkedsCustom = $state('');

	const dotaInlines: RadioItemProps[] = [
		{ label: 'Lina', name: 'Lina' },
		{ label: 'SB', name: 'Spirit Breaker' },
		{ label: 'Morph', name: 'Morphling' },
		{ label: 'Sniper', name: 'Sniper' },
		{ label: 'Sven', name: 'Sven' },
		{ label: 'Invoker', name: 'Invoker' },
		{ label: 'Tide', name: 'Tidehunter' },
		{ label: 'Bat', name: 'Batrider' },
		{ label: 'Mag', name: 'Magnus' }
	];
	let checkInline = $state('Morphling');

	const dotaImgs: (RadioItemProps & { imgName: string })[] = [
		{ label: 'Lina', name: 'Lina', imgName: '火女' },
		{ label: 'SB', name: 'Spirit Breaker', imgName: '小牛' },
		{ label: 'Morph', name: 'Morphling', imgName: '水人' },
		{ label: 'Sniper', name: 'Sniper', imgName: '火枪' },
		{ label: 'Sven', name: 'Sven', imgName: '斯温' }
	];
	let imgChecked = $state('Lina');

	const dotaLong: RadioItemProps[] = [
		{ name: 'Jugg', label: 'Juggernaut is a melee agility hero who can quickly engage in combat.' },
		{ name: 'SB', label: 'Barathrum, Spirit Breaker is a powerful ganking strength melee hero.' },
		{ name: 'KOTL', label: 'Ezalor, Keeper of the Light, is a famous support intelligence hero.' },
		{ name: 'Mag', label: 'Magnus? Why not ban Magnus? Why not ban Magnus?' }
	];

	const dotaVoices: (RadioItemProps & { voices: string[] })[] = [
		{ name: 'Invoker', label: 'Invoker', voices: ['"From the first point was begat a line."'] },
		{ name: 'Storm', label: 'Storm', voices: ['"Hey, wake up! Get some coffee, our tower is under attack."'] },
		{
			name: 'Batrider',
			label: 'Batrider',
			voices: [
				'"Oh Lina, wanna be my queen?"',
				'"Oh Windrunner, no need to run from me."',
				'"Crystal Maiden, you\'re like a tall glass of water."'
			]
		},
		{ name: 'Tidehunter', label: 'Tidehunter', voices: ['"I could eat a sea cucumber."'] }
	];
	let voiceChecked = $state('');
</script>

<div class="px-4">
	<div class="mb-4 mt-8 text-2xl font-bold">Horizontal Layout</div>
	<div class="mb-4 mt-6 text-lg font-bold">Basic Usage</div>
	<Radio layout="h" data={dota} />
	<Divider />

	<div class="mb-4 mt-6 text-lg font-bold">Get Selected Value</div>
	<Radio layout="h" data={dota} bind:value />
	<div class="mt-4 text-sm">Selected: {value}</div>
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Text Position</div>
	<Radio layout="h" data={dota} textPosition="l" />
	<Divider />
	<Radio layout="h" data={dota} textPosition="b" />
	<Divider />
	<Radio layout="h" data={dota} textPosition="t" />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Custom Icon</div>
	<Radio layout="h" data={dota} icon={{ name: 'ri-checkbox-blank-circle-line' }} iconChecked={{ name: 'ri-radio-button-fill' }} />
	<Divider />
	<Radio layout="h" data={dota} icon={{ name: 'ri-checkbox-circle-line' }} iconChecked={{ name: 'ri-checkbox-circle-fill' }} />
	<Divider />
	<Radio layout="h" data={dota} icon={{ name: 'ri-checkbox-multiple-line' }} iconChecked={{ name: 'ri-checkbox-multiple-fill' }} />
	<Divider />
	<Radio layout="h" data={dota} icon={{ name: 'ri-check-line' }} iconChecked={{ name: 'ri-check-fill' }} />
	<Divider />
	<Radio layout="h" data={dota} icon={{ name: 'ri-check-double-line' }} iconChecked={{ name: 'ri-check-double-line' }} />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Snippet as Button Component</div>
	<Radio layout="h" data={dota}>
		{#snippet radioChild({ item })}
			<Button fill={value === item.name ? 'base' : 'lineLight'} injClass="px-2 !py-1" onclick={() => (value = item.name)}>
				{item.label}
			</Button>
		{/snippet}
	</Radio>
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Snippet as Custom Element</div>
	<Radio layout="h" data={dota}>
		{#snippet radioChild({ item })}
			<button
				class="rounded-sm border px-5 py-0.5 text-sm {checkedsCustom === item.name
					? 'bg-primary/10 text-primary dark:bg-dark/10 dark:text-dark'
					: 'border-gray-200 bg-gray-100 dark:border-gray-500 dark:bg-gray-600'}"
				onclick={() => (checkedsCustom = item.name)}
			>
				{item.label}
			</button>
		{/snippet}
	</Radio>
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Image Options</div>
	<Radio layout="h" data={dotaImgs}>
		{#snippet radioChild({ item })}
			<div class="flex flex-col items-center">
				<!-- svelte-ignore a11y_click_events_have_key_events -->
				<!-- svelte-ignore a11y_no_static_element_interactions -->
				<div
					class="mb-1 h-12 w-12 overflow-hidden rounded-sm {imgChecked === item.name ? 'ring-primary dark:ring-dark ring-2' : ''}"
					onclick={() => (imgChecked = item.name)}
				>
					<img class="h-full w-full object-cover" src={`/assets/images/dota_${item.imgName}.png`} alt="" />
				</div>
				<div>
					<Icon
						name={imgChecked === item.name ? 'ri-arrow-up-s-fill' : 'ri-arrow-up-s-line'}
						theme={imgChecked === item.name}
						alpha={imgChecked === item.name ? 1 : 0.2}
					/>
				</div>
			</div>
		{/snippet}
	</Radio>
	<div class="text-sm">
		Selected <span class="text-[red]">{imgChecked}</span>
	</div>
	<Divider />
</div>

<div class="px-4">
	<div class="mb-4 text-2xl font-bold">Inline Layout</div>
	<div class="mb-4 mt-8 text-lg font-bold">Snippet Inline Layout</div>
	<Radio layout="inline" data={dotaInlines}>
		{#snippet radioChild({ item })}
			<!-- svelte-ignore a11y_click_events_have_key_events -->
			<!-- svelte-ignore a11y_no_static_element_interactions -->
			<div
				class="m-1 rounded-sm border px-2 py-0.5 text-sm {checkInline === item.name
					? 'bg-primary/10 text-primary dark:bg-dark/10 dark:text-dark'
					: 'border-gray-200 bg-gray-100 dark:border-gray-500 dark:bg-gray-600'}"
				onclick={() => (checkInline = item.name)}
			>
				{item.label}
			</div>
		{/snippet}
	</Radio>
	<div class="mt-2 text-xs">Selected: {checkInline}</div>
</div>
<Divider />

<div class="px-4 pb-8">
	<div class="mb-4 text-2xl font-bold">Vertical Layout</div>
	<div class="mb-4 mt-8 text-lg font-bold">Basic Usage</div>
	<Radio data={dota} />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Long Text Options</div>
	<Radio data={dotaLong} />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Text Position</div>
	<Radio data={dota} textPosition="l" />

	<div class="mb-4 mt-8 text-lg font-bold">Complex Options && Custom Selected Effect</div>
	<Radio data={dotaVoices}>
		{#snippet radioChild({ item })}
			<!-- svelte-ignore a11y_click_events_have_key_events -->
			<!-- svelte-ignore a11y_no_static_element_interactions -->
			<div class="flex cursor-pointer items-center" onclick={() => (voiceChecked = item.name)}>
				<div>
					<Icon
						name={voiceChecked === item.name ? 'ri-radio-button-line' : 'ri-checkbox-blank-circle-line'}
						theme={voiceChecked === item.name}
						alpha={voiceChecked === item.name ? 1 : 0.2}
					/>
				</div>
				<div class="ml-2 grow {voiceChecked === item.name ? 'text-primary dark:text-dark' : ''}">
					{item.label}
					{#each item.voices as string[] as voice}
						<div class="text-xs">{voice}</div>
					{/each}
					<div class="mt-1 h-px bg-black/10 dark:bg-white/10"></div>
				</div>
			</div>
		{/snippet}
	</Radio>
</div>



================================================
FILE: packages/stdf/src/routes/radio/zh_CN/+page.svelte
================================================
<!-- Radio Demo -->
<script lang="ts">
	import { Radio, Divider, Button, Icon } from '$lib/index.js';
	import type { RadioItemProps } from '$lib/types/index.js';

	const dota: RadioItemProps[] = [
		{ label: '主宰', name: '奶棒人' },
		{ label: '白牛', name: '令狐冲' },
		{ label: '光法', name: '光之守卫' },
		{ label: '猛犸', name: '马格纳斯' }
	];
	let value = $state(dota[0].name);
	let checkedsCustom = $state('');

	const dotaInlines: RadioItemProps[] = [
		{ label: '火女', name: '火女' },
		{ label: '小牛', name: '小牛' },
		{ label: '水人', name: '水人' },
		{ label: '火枪', name: '火枪' },
		{ label: '斯温', name: '斯温' },
		{ label: '祈求者', name: '祈求者' },
		{ label: '潮汐', name: '潮汐' },
		{ label: '蝙蝠', name: '蝙蝠' },
		{ label: '猛犸', name: '猛犸' }
	];
	let checkInline = $state('小牛');

	const dotaImgs: RadioItemProps[] = [
		{ label: '火女', name: '火女' },
		{ label: '小牛', name: '小牛' },
		{ label: '水人', name: '水人' },
		{ label: '火枪', name: '火枪' },
		{ label: '斯温', name: '斯温' }
	];
	let imgChecked = $state('火女');

	const dotaLong: RadioItemProps[] = [
		{ name: '主宰', label: '主宰是一个近战敏捷英雄，他能够迅速切入战斗。' },
		{ name: '白牛', label: '巴拉森，裂魂人是一个强大的 Gank 型的力量型近战英雄。' },
		{ name: '光法', label: '伊扎洛，光之守卫，他是一个著名的辅助性智力英雄。' },
		{ name: '猛犸', label: '猛犸？为什么不 BAN 猛犸？为什么不 BAN 猛犸？' }
	];

	type DotaVoices = (RadioItemProps & { voices: string[] })[];
	const dotaVoices: DotaVoices = [
		{ name: '祈求者', label: '祈求者', voices: ['"来自于伟大的奥秘。"'] },
		{ name: '风暴之灵', label: '风暴之灵', voices: ['"喂~快醒醒，快喝点咖啡，我方上塔正遭受攻击。"'] },
		{
			name: '蝙蝠骑士',
			label: '蝙蝠骑士',
			voices: ['“哦，莉娜，当我的压寨夫人怎么样？”', '“哦，风行者，见着我你不用跑。”', '“水晶室女，你就像一个装满冰水的高脚杯。”']
		},
		{ name: '潮汐猎人', label: '潮汐猎人', voices: ['“我还能吃下一根海藻。”'] }
	];
	let voiceChecked = $state('');
</script>

<div class="px-4">
	<div class="mb-4 mt-8 text-2xl font-bold">横向排列</div>
	<div class="mb-4 mt-6 text-lg font-bold">简单用法</div>
	<Radio layout="h" data={dota} />
	<Divider />

	<div class="mb-4 mt-6 text-lg font-bold">获取选中值</div>
	<Radio layout="h" data={dota} bind:value />
	<div class="mt-4 text-sm">已选：{value}</div>
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">文字在不同位置</div>
	<Radio layout="h" data={dota} textPosition="l" />
	<Divider />
	<Radio layout="h" data={dota} textPosition="b" />
	<Divider />
	<Radio layout="h" data={dota} textPosition="t" />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">自定义图标</div>
	<Radio layout="h" data={dota} icon={{ name: 'ri-checkbox-blank-circle-line' }} iconChecked={{ name: 'ri-radio-button-fill' }} />
	<Divider />
	<Radio layout="h" data={dota} icon={{ name: 'ri-checkbox-circle-line' }} iconChecked={{ name: 'ri-checkbox-circle-fill' }} />
	<Divider />
	<Radio layout="h" data={dota} icon={{ name: 'ri-checkbox-multiple-line' }} iconChecked={{ name: 'ri-checkbox-multiple-fill' }} />
	<Divider />
	<Radio layout="h" data={dota} icon={{ name: 'ri-check-line' }} iconChecked={{ name: 'ri-check-fill' }} />
	<Divider />
	<Radio layout="h" data={dota} icon={{ name: 'ri-check-double-line' }} iconChecked={{ name: 'ri-check-double-line' }} />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Snippet 为 Button 组件</div>
	<Radio layout="h" data={dota}>
		{#snippet radioChild({ item })}
			<Button fill={value === item.name ? 'base' : 'lineLight'} injClass="px-2 !py-1" onclick={() => (value = item.name)}>
				{item.label}
			</Button>
		{/snippet}
	</Radio>
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">Snippet 为自定义元素</div>
	<Radio layout="h" data={dota}>
		{#snippet radioChild({ item })}
			<button
				class="rounded-sm border px-5 py-0.5 text-sm {checkedsCustom === item.name
					? 'bg-primary/10 text-primary dark:bg-dark/10 dark:text-dark'
					: 'border-gray-200 bg-gray-100 dark:border-gray-500 dark:bg-gray-600'}"
				onclick={() => (checkedsCustom = item.name)}
			>
				{item.label}
			</button>
		{/snippet}
	</Radio>
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">图片选项</div>
	<Radio layout="h" data={dotaImgs}>
		{#snippet radioChild({ item })}
			<div class="flex flex-col items-center">
				<!-- svelte-ignore a11y_click_events_have_key_events -->
				<!-- svelte-ignore a11y_no_static_element_interactions -->
				<div
					class="mb-1 h-12 w-12 overflow-hidden rounded-sm {imgChecked === item.name ? 'ring-primary dark:ring-dark ring-2' : ''}"
					onclick={() => (imgChecked = item.name)}
				>
					<img class="h-full w-full object-cover" src={`/assets/images/dota_${item.name}.png`} alt="" />
				</div>
				<div>
					<Icon
						name={imgChecked === item.name ? 'ri-arrow-up-s-fill' : 'ri-arrow-up-s-line'}
						theme={imgChecked === item.name}
						alpha={imgChecked === item.name ? 1 : 0.2}
					/>
				</div>
			</div>
		{/snippet}
	</Radio>
	<div class="text-sm">
		已选 <span class="text-[red]">{imgChecked}</span>
	</div>
	<Divider />
</div>

<div class="px-4">
	<div class="mb-4 text-2xl font-bold">行内元素排列</div>
	<div class="mb-4 mt-8 text-lg font-bold">Snippet 行内元素排列</div>
	<Radio layout="inline" data={dotaInlines}>
		{#snippet radioChild({ item })}
			<!-- svelte-ignore a11y_click_events_have_key_events -->
			<!-- svelte-ignore a11y_no_static_element_interactions -->
			<div
				class="m-1 rounded-sm border px-2 py-0.5 text-sm {checkInline === item.name
					? 'bg-primary/10 text-primary dark:bg-dark/10 dark:text-dark'
					: 'border-gray-200 bg-gray-100 dark:border-gray-500 dark:bg-gray-600'}"
				onclick={() => (checkInline = item.name)}
			>
				{item.label}
			</div>
		{/snippet}
	</Radio>
	<div class="mt-2 text-xs">已选：{checkInline}</div>
</div>
<Divider />

<div class="px-4 pb-8">
	<div class="mb-4 text-2xl font-bold">纵向排列</div>
	<div class="mb-4 mt-8 text-lg font-bold">基础用法</div>
	<Radio data={dota} />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">长文字选项</div>
	<Radio data={dotaLong} />
	<Divider />

	<div class="mb-4 mt-8 text-lg font-bold">文字靠左</div>
	<Radio data={dota} textPosition="l" />

	<div class="mb-4 mt-8 text-lg font-bold">复杂选项 && 自定义选中效果</div>
	<Radio data={dotaVoices}>
		{#snippet radioChild({ item })}
			<!-- svelte-ignore a11y_click_events_have_key_events -->
			<!-- svelte-ignore a11y_no_static_element_interactions -->
			<div class="flex cursor-pointer items-center" onclick={() => (voiceChecked = item.name)}>
				<div>
					<Icon
						name={voiceChecked === item.name ? 'ri-radio-button-line' : 'ri-checkbox-blank-circle-line'}
						theme={voiceChecked === item.name}
						alpha={voiceChecked === item.name ? 1 : 0.2}
					/>
				</div>
				<div class="ml-2 grow {voiceChecked === item.name ? 'text-primary dark:text-dark' : ''}">
					{item.label}
					{#each item.voices as string[] as voice}
						<div class="text-xs">{voice}</div>
					{/each}
					<div class="mt-1 h-px bg-black/10 dark:bg-white/10"></div>
				</div>
			</div>
		{/snippet}
	</Radio>
</div>



================================================
FILE: packages/stdf/src/routes/rate/en_US/+page.svelte
================================================
<!-- Rate Demo -->
<script lang="ts">
	import { Rate, Icon } from '$lib/index.js';

	let value = $state(2.5);
</script>

<div class="mx-4 mt-8 text-lg font-bold">Basic Usage</div>
<div class="p-4">
	<Rate />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Set Initial Score</div>
<div class="p-4">
	<Rate value={1} />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Allow Zero Score</div>
<div class="p-4">
	<Rate zero />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Custom Total Score</div>
<div class="p-4">
	<Rate total={12} />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Set Unselected Opacity</div>
<div class="p-4">
	<Rate opacity="0.8" />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Allow Half Selection</div>
<div class="p-4">
	<Rate half />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Vertical Half Selection</div>
<div class="p-4">
	<Rate half vertical />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Half Selection with Zero Score</div>
<div class="p-4">
	<Rate half zero />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Increase Spacing</div>
<div class="p-4">
	<Rate space="8" />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Disabled</div>
<div class="p-4">
	<Rate disabled />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Read Only</div>
<div class="p-4">
	<Rate readonly />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Different Sizes</div>
<div class="p-4">
	<Rate width={20} height={20} />
</div>
<div class="p-4">
	<Rate width={28} height={28} />
</div>
<div class="p-4">
	<Rate width={36} height={36} />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Custom Icons</div>
<div class="p-4">
	<Rate opacity="0.6">
		<Icon name="ri-star-fill" injClass="text-[#f5b53f]" />
	</Rate>
</div>
<div class="p-4">
	<Rate>
		<Icon name="ri-heart-3-fill" injClass="text-[red]" />
	</Rate>
</div>
<div class="p-4">
	<Rate half>
		<Icon name="ri-heart-3-fill" injClass="text-[red]" />
	</Rate>
</div>
<div class="p-4">
	<Rate half opacity="0.5" width={30} height={36}>
		<div class="text-3xl">👍</div>
	</Rate>
</div>
<div class="p-4">
	<Rate half opacity="0.5" width={30} height={36} vertical>
		<div class="text-3xl">🍺</div>
	</Rate>
</div>
<div class="p-4">
	<Rate half opacity="0.5" width={30} height={36}>
		<div class="text-3xl text-primary dark:text-dark">M</div>
	</Rate>
</div>
<div class="mx-4 mt-8 text-lg font-bold">Event Listening</div>
<div class="p-4">
	<Rate half {value} onclick={(v) => (value = v)} />
	<p class="mt-2">Rating: {value} stars</p>
</div>

<div class="mx-4 mt-8 text-lg font-bold">Click Animation for All Active Icons</div>
<div class="p-4">
	<Rate animation="active" />
</div>

<div class="mx-4 mt-8 text-lg font-bold">Disable Click Animation</div>
<div class="p-4">
	<Rate animation={null} />
</div>



================================================
FILE: packages/stdf/src/routes/rate/zh_CN/+page.svelte
================================================
<!-- Rate Demo -->
<script lang="ts">
	import { Rate, Icon } from '$lib/index.js';

	let value = $state(2.5);
</script>

<div class="mx-4 mt-8 text-lg font-bold">基础用法</div>
<div class="p-4">
	<Rate />
</div>
<div class="mx-4 mt-8 text-lg font-bold">设置初始分数</div>
<div class="p-4">
	<Rate value={1} />
</div>
<div class="mx-4 mt-8 text-lg font-bold">允许零分</div>
<div class="p-4">
	<Rate zero />
</div>
<div class="mx-4 mt-8 text-lg font-bold">自定义总分</div>
<div class="p-4">
	<Rate total={12} />
</div>
<div class="mx-4 mt-8 text-lg font-bold">设置未选中透明度</div>
<div class="p-4">
	<Rate opacity="0.8" />
</div>
<div class="mx-4 mt-8 text-lg font-bold">允许半选</div>
<div class="p-4">
	<Rate half />
</div>
<div class="mx-4 mt-8 text-lg font-bold">竖向半选</div>
<div class="p-4">
	<Rate half vertical />
</div>
<div class="mx-4 mt-8 text-lg font-bold">半选允许零分</div>
<div class="p-4">
	<Rate half zero />
</div>
<div class="mx-4 mt-8 text-lg font-bold">加大间距</div>
<div class="p-4">
	<Rate space="8" />
</div>
<div class="mx-4 mt-8 text-lg font-bold">禁用</div>
<div class="p-4">
	<Rate disabled />
</div>
<div class="mx-4 mt-8 text-lg font-bold">只读</div>
<div class="p-4">
	<Rate readonly />
</div>
<div class="mx-4 mt-8 text-lg font-bold">不同大小</div>
<div class="p-4">
	<Rate width={20} height={20} />
</div>
<div class="p-4">
	<Rate width={28} height={28} />
</div>
<div class="p-4">
	<Rate width={36} height={36} />
</div>
<div class="mx-4 mt-8 text-lg font-bold">自定义</div>
<div class="p-4">
	<Rate opacity="0.6">
		<Icon name="ri-star-fill" injClass="text-[#f5b53f]" />
	</Rate>
</div>
<div class="p-4">
	<Rate>
		<Icon name="ri-heart-3-fill" injClass="text-[red]" />
	</Rate>
</div>
<div class="p-4">
	<Rate half>
		<Icon name="ri-heart-3-fill" injClass="text-[red]" />
	</Rate>
</div>
<div class="p-4">
	<Rate half opacity="0.5" width={30} height={36}>
		<div class="text-3xl">👍</div>
	</Rate>
</div>
<div class="p-4">
	<Rate half opacity="0.5" width={30} height={36} vertical>
		<div class="text-3xl">🍺</div>
	</Rate>
</div>
<div class="p-4">
	<Rate half opacity="0.5" width={30} height={36}>
		<div class="text-3xl text-primary dark:text-dark">富</div>
	</Rate>
</div>
<div class="mx-4 mt-8 text-lg font-bold">监听事件</div>
<div class="p-4">
	<Rate half {value} onclick={(v) => (value = v)} />
	<p class="mt-2">评分：{value} 星</p>
</div>

<div class="mx-4 mt-8 text-lg font-bold">所有激活图标都有点击动画</div>
<div class="p-4">
	<Rate animation="active" />
</div>

<div class="mx-4 mt-8 text-lg font-bold">关闭点击动画</div>
<div class="p-4">
	<Rate animation={null} />
</div>



================================================
FILE: packages/stdf/src/routes/skeleton/en_US/+page.svelte
================================================
<!-- Skeleton Demo -->
<script lang="ts">
	import { Skeleton } from '$lib/index.js';
</script>

<div class="p-2">
	<div class="m-4 text-lg font-bold">example 1</div>
	<div class="flex">
		<Skeleton width="16" height="16" radius="full" />
		<div class="grow">
			<Skeleton width="32" height="8" />
			<Skeleton type="p" />
		</div>
	</div>

	<div class="m-4 text-lg font-bold">example 2</div>
	<div class="flex justify-between">
		<Skeleton width="16" height="16" />
		<Skeleton width="16" height="16" />
		<Skeleton width="16" height="16" />
		<Skeleton width="16" height="16" />
	</div>
	<Skeleton width="32" height="8" />
	<Skeleton type="p" lines={5} />

	<div class="m-4 text-lg font-bold">example 3</div>
	<div class="flex">
		<Skeleton type="img" width="24" height="24" />
		<div class="grow">
			<Skeleton type="p" />
		</div>
	</div>

	<div class="m-4 text-lg font-bold">example 4</div>
	<div class="flex">
		<div class="grow">
			<Skeleton width="32" height="8" />
			<Skeleton type="p" />
		</div>
		<Skeleton type="video" width="32" height="32" />
	</div>

	<div class="m-4 text-lg font-bold">example 5</div>
	<div class="flex flex-col items-center">
		<Skeleton width="24" height="24" radius="full" />
		<Skeleton width="16" height="6" />
		<Skeleton width="32" height="4" />
		<Skeleton type="qrcode" width="64" height="64" />
	</div>

	<div class="m-4 text-lg font-bold">example 6</div>
	{#each [1, 1, 1] as item}
		<div class="flex items-center justify-between">
			<div class="flex">
				<div class="flex">
					<Skeleton width="12" height="12" radius="full" />
					<div class="flex flex-col justify-between">
						<Skeleton width="16" height="6" />
						<Skeleton width="32" height="4" />
					</div>
				</div>
			</div>
			<Skeleton width="16" height="8" radius="full" />
		</div>
		<Skeleton width="full" height="1" />
	{/each}
</div>



================================================
FILE: packages/stdf/src/routes/skeleton/zh_CN/+page.svelte
================================================
<!-- Skeleton Demo -->
<script lang="ts">
	import { Skeleton } from '$lib/index.js';
</script>

<div class="p-2">
	<div class="m-4 text-lg font-bold">示例 1</div>
	<div class="flex">
		<Skeleton width="16" height="16" radius="full" />
		<div class="grow">
			<Skeleton width="32" height="8" />
			<Skeleton type="p" />
		</div>
	</div>

	<div class="m-4 text-lg font-bold">示例 2</div>
	<div class="flex justify-between">
		<Skeleton width="16" height="16" />
		<Skeleton width="16" height="16" />
		<Skeleton width="16" height="16" />
		<Skeleton width="16" height="16" />
	</div>
	<Skeleton width="32" height="8" />
	<Skeleton type="p" lines={5} />

	<div class="m-4 text-lg font-bold">示例 3</div>
	<div class="flex">
		<Skeleton type="img" width="24" height="24" />
		<div class="grow">
			<Skeleton type="p" />
		</div>
	</div>

	<div class="m-4 text-lg font-bold">示例 4</div>
	<div class="flex">
		<div class="grow">
			<Skeleton width="32" height="8" />
			<Skeleton type="p" />
		</div>
		<Skeleton type="video" width="32" height="32" />
	</div>

	<div class="m-4 text-lg font-bold">示例 5</div>
	<div class="flex flex-col items-center">
		<Skeleton width="24" height="24" radius="full" />
		<Skeleton width="16" height="6" />
		<Skeleton width="32" height="4" />
		<Skeleton type="qrcode" width="64" height="64" />
	</div>

	<div class="m-4 text-lg font-bold">示例 6</div>
	<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
	{#each [1, 1, 1] as _}
		<div class="flex items-center justify-between">
			<div class="flex">
				<div class="flex">
					<Skeleton width="12" height="12" radius="full" />
					<div class="flex flex-col justify-between">
						<Skeleton width="16" height="6" />
						<Skeleton width="32" height="4" />
					</div>
				</div>
			</div>
			<Skeleton width="16" height="8" radius="full" />
		</div>
		<Skeleton width="full" height="1" />
	{/each}
</div>



================================================
FILE: packages/stdf/src/routes/slider/en_US/+page.svelte
================================================
<!-- Slider Demo -->
<script lang="ts">
	import { Slider, Icon } from '$lib/index.js';

	let value = $state(20);

	let valueRange = $state([50, 60]);
	// Generate an array of random numbers within a specified range
	const randomArray = (min: number, max: number, length: number) => {
		let arr = [];
		for (let i = 0; i < length; i++) {
			arr.push(Math.floor(Math.random() * (max - min + 1) + min));
		}
		return arr;
	};
	// Sort the array in ascending or descending order
	const sortArray = (arr: number[], isAsc: boolean) => arr.sort((a, b) => (isAsc ? a - b : b - a));
	const barList1 = sortArray(randomArray(2, 60, 20), true);
	const barList2 = sortArray(randomArray(2, 60, 20), false);
	const barList = [...barList1, ...barList2];
	let valueBar: number = $state(70);
</script>

<div class="mx-4 mt-8 text-lg font-bold">Basic Usage</div>
<div class="px-6 py-4">
	<Slider />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Monitor value</div>
<div class="px-6 py-4">
	<Slider onchange={(v: number) => (value = v)} {value} />
	Current value: {value}
</div>
<div class="mx-4 mt-8 text-lg font-bold">Step size of 5</div>
<div class="px-6 py-4">
	<Slider step={5} />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Step size of 0.1</div>
<div class="px-6 py-4">
	<Slider step={0.1} value={0.2} minRange={0} maxRange={1} />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Set selectable range (60-80)</div>
<div class="px-6 py-4">
	<Slider value={68} minRange={60} maxRange={80} />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Range selection</div>
<div class="px-6 py-4">
	<Slider isRange />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Set range for interval (40-80)</div>
<div class="px-6 py-4">
	<Slider
		isRange
		minRange={40}
		maxRange={80}
		startValue={valueRange[0]}
		endValue={valueRange[1]}
		onchange={(_, valueRange) => (valueRange = valueRange)}
	/>
	Current range: {valueRange[0]} - {valueRange[1]}
</div>
<div class="mx-4 mt-8 text-lg font-bold">Different border radius</div>
<div class="px-6 py-4">
	<Slider radius="sm" />
</div>
<div class="px-6 py-4">
	<Slider radius="none" />
</div>
<div class="px-6 py-4">
	<Slider radius="sm" isRange />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Outlined slider</div>
<div class="px-6 py-4">
	<Slider lineBlock radius="sm" />
</div>
<div class="px-6 py-4">
	<Slider lineBlock isRange />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Always show Tip</div>
<div class="px-6 py-4">
	<Slider showTip="always" />
</div>
<div class="px-6 py-4">
	<Slider showTip="always" isRange />
</div>
<div class="px-6 py-4">
	<Slider showTip="always" radius="none" />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Don't show Tip</div>
<div class="px-6 py-4">
	<Slider showTip="never" />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Combined layout</div>
<div class="flex space-x-3 p-4">
	<Icon name="ri-volume-mute-line" />
	<div class="grow">
		<Slider />
	</div>
	<Icon name="ri-volume-up-line" />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Using Snippet</div>
<div class="px-6 pt-16">
	<Slider lineBlock showTip="never" value={valueBar} onchange={(v: number) => (valueBar = v)}>
		{#snippet children()}
			<div class="relative grow items-end">
				<div class="flex items-end justify-between overflow-hidden" style="transform: translateY(-30px);">
					{#each barList as item, i}
						<div
							class="w-1 rounded-full{i / 40 < valueBar / 100 ? ' bg-primary dark:bg-dark' : ' bg-gray-200 dark:bg-gray-500'}"
							style="height: {item}px"
						></div>
					{/each}
				</div>
			</div>
		{/snippet}
	</Slider>
</div>
<div class="mx-4 mt-8 text-lg font-bold">Disabled</div>
<div class="px-6 py-4">
	<Slider disabled />
</div>
<div class="mx-4 mt-8 text-lg font-bold">Read-only</div>
<div class="px-6 py-4">
	<Slider readonly />
</div>



================================================
FILE: packages/stdf/src/routes/slider/zh_CN/+page.svelte
================================================
<!-- Slider Demo -->
<script lang="ts">
	import { Slider, Icon } from '$lib/index.js';

	let value = $state(20);

	let valueRange: [number, number] = $state([50, 60]);
	//生成指定数字之间的随机数组成的数组
	const randomArray = (min: number, max: number, length: number) => {
		let arr = [];
		for (let i = 0; i < length; i++) {
			arr.push(Math.floor(Math.random() * (max - min + 1) + min));
		}
		return arr;
	};
	//将数组递增或递减排序
	const sortArray = (arr: number[], isAsc: boolean) => arr.sort((a, b) => (isAsc ? a - b : b - a));
	const barList1 = sortArray(randomArray(2, 60, 20), true);
	const barList2 = sortArray(randomArray(2, 60, 20), false);
	const barList = [...barList1, ...barList2];
	let valueBar: number = $state(70);
</script>

<div class="mx-4 mt-8 text-lg font-bold">基础用法</div>
<div class="px-6 py-4">
	<Slider />
</div>
<div class="mx-4 mt-8 text-lg font-bold">监听 value</div>
<div class="px-6 py-4">
	<Slider onchange={(v: number) => (value = v)} {value} />
	当前值：{value}
</div>
<div class="mx-4 mt-8 text-lg font-bold">步长为 5</div>
<div class="px-6 py-4">
	<Slider step={5} />
</div>
<div class="mx-4 mt-8 text-lg font-bold">步长为 0.1</div>
<div class="px-6 py-4">
	<Slider step={0.1} value={0.2} minRange={0} maxRange={1} />
</div>
<div class="mx-4 mt-8 text-lg font-bold">设定可选范围（60-80）</div>
<div class="px-6 py-4">
	<Slider value={68} minRange={60} maxRange={80} />
</div>
<div class="mx-4 mt-8 text-lg font-bold">区间选择</div>
<div class="px-6 py-4">
	<Slider isRange />
</div>
<div class="mx-4 mt-8 text-lg font-bold">区间设定可选范围（40-80）</div>
<div class="px-6 py-4">
	<Slider
		isRange
		minRange={40}
		maxRange={80}
		startValue={valueRange[0]}
		endValue={valueRange[1]}
		onchange={(_, valueRange) => (valueRange = valueRange)}
	/>
	当前区间：{valueRange[0]} - {valueRange[1]}
</div>
<div class="mx-4 mt-8 text-lg font-bold">不同圆角</div>
<div class="px-6 py-4">
	<Slider radius="sm" />
</div>
<div class="px-6 py-4">
	<Slider radius="none" />
</div>
<div class="px-6 py-4">
	<Slider radius="sm" isRange />
</div>
<div class="mx-4 mt-8 text-lg font-bold">线框滑块</div>
<div class="px-6 py-4">
	<Slider lineBlock radius="sm" />
</div>
<div class="px-6 py-4">
	<Slider lineBlock isRange />
</div>
<div class="mx-4 mt-8 text-lg font-bold">一直显示 Tip</div>
<div class="px-6 py-4">
	<Slider showTip="always" />
</div>
<div class="px-6 py-4">
	<Slider showTip="always" isRange />
</div>
<div class="px-6 py-4">
	<Slider showTip="always" radius="none" />
</div>
<div class="mx-4 mt-8 text-lg font-bold">不显示 Tip</div>
<div class="px-6 py-4">
	<Slider showTip="never" />
</div>
<div class="mx-4 mt-8 text-lg font-bold">组合布局</div>
<div class="flex space-x-3 p-4">
	<Icon name="ri-volume-mute-line" />
	<div class="grow">
		<Slider />
	</div>
	<Icon name="ri-volume-up-line" />
</div>
<div class="mx-4 mt-8 text-lg font-bold">使用 Snippet</div>
<div class="px-6 pt-16">
	<Slider lineBlock showTip="never" value={valueBar} onchange={(v: number) => (valueBar = v)}>
		{#snippet children()}
			<div class="relative grow items-end">
				<div class="flex items-end justify-between overflow-hidden" style="transform: translateY(-30px);">
					{#each barList as item, i}
						<div
							class="w-1 rounded-full{i / 40 < valueBar / 100 ? ' bg-primary dark:bg-dark' : ' bg-gray-200 dark:bg-gray-500'}"
							style="height: {item}px"
						></div>
					{/each}
				</div>
			</div>
		{/snippet}
	</Slider>
</div>
<div class="mx-4 mt-8 text-lg font-bold">禁用</div>
<div class="px-6 py-4">
	<Slider disabled />
</div>
<div class="mx-4 mt-8 text-lg font-bold">只读</div>
<div class="px-6 py-4">
	<Slider readonly />
</div>



================================================
FILE: packages/stdf/src/routes/stepper/en_US/+page.svelte
================================================
<!-- Stepper Demo -->
<script lang="ts">
	import { Stepper, Toast } from '$lib/index.js';

	let asyncValue1 = $state(1);
	let loading1 = $state(false);
	let asyncValue2 = $state(1);
	let loading2 = $state(false);
	let asyncValue3 = $state(1);
	let loading3 = $state(false);
	const handleChange1 = (type: 'increase' | 'decrease') => {
		loading1 = true;
		setTimeout(() => {
			asyncValue1 += type === 'increase' ? 1 : -1;
			loading1 = false;
		}, 2000);
	};
	const handleChange2 = (type: 'increase' | 'decrease') => {
		loading2 = true;
		setTimeout(() => {
			asyncValue2 += type === 'increase' ? 1 : -1;
			loading2 = false;
		}, 3000);
	};
	const handleChange3 = (type: 'increase' | 'decrease') => {
		loading3 = true;
		setTimeout(() => {
			asyncValue3 += type === 'increase' ? 1 : -1;
			loading3 = false;
		}, 4000);
	};
</script>

<div class="mx-4 mt-8 text-lg font-bold">Basic Usage</div>
<div class="px-4 py-4">
	<Stepper />
</div>

<div class="mx-4 mt-8 text-lg font-bold">Set Maximum/Minimum/Initial Value</div>
<div class="px-4 py-4">
	<Stepper min={2} max={10} value={5} />
</div>

<div class="mx-4 mt-8 text-lg font-bold">Set Step</div>
<div class="px-4 py-4">
	<Stepper step={5} />
</div>

<div class="mx-4 mt-8 text-lg font-bold">Highlight Number Area</div>
<div class="px-4 py-4">
	<Stepper numberHighlight />
</div>

<div class="mx-4 mt-8 text-lg font-bold">Highlight Number Area</div>
<div class="flex gap-2 px-4 py-4">
	<Stepper theme={false} />
	<Stepper theme={false} numberHighlight />
</div>

<div class="mx-4 mt-8 text-lg font-bold">Different Radius</div>
<div class="flex flex-wrap gap-2 px-4 py-4">
	<div><Stepper radius="none" /></div>
	<div><Stepper radius="sm" /></div>
	<div><Stepper radius="xl" /></div>
	<div><Stepper radius="full" /></div>
	<div><Stepper radius="full" numberHighlight /></div>
	<div><Stepper radius="full" theme={false} /></div>
</div>

<div class="mx-4 mt-8 text-lg font-bold">Vertical</div>
<div class="flex justify-around px-2 py-4">
	<Stepper vertical />
	<Stepper vertical numberHighlight />
	<Stepper vertical theme={false} />
	<Stepper vertical radius="none" />
	<Stepper radius="xl" vertical />
</div>

<div class="mx-4 mt-8 text-lg font-bold">Format Display Numbers</div>
<div class="px-4 py-4">
	<div class="mb-2 text-sm">Keep one decimal place</div>
	<Stepper decimal={1} step={0.1} max={1} min={0.1} value={0.5} />
</div>
<div class="px-4 py-4">
	<div class="mb-2 text-sm">Keep four decimal places</div>
	<Stepper decimal={4} step={0.0001} max={1} min={0.0001} value={0.5} />
</div>

<div class="mx-4 mt-8 text-lg font-bold">Asynchronous Display Numbers</div>
<div class="px-4 py-4">
	<div class="mb-2 text-sm">Toast shows asynchronous status</div>
	<Stepper async={loading1} value={asyncValue1} onincrease={() => handleChange1('increase')} ondecrease={() => handleChange1('decrease')} />
</div>
<Toast bind:visible={loading1} type="loading" message="Saving..." />
<div class="mb-2 px-4 text-sm">Internal display asynchronous status</div>
<div class="flex gap-2 px-4 py-4">
	<Stepper
		async={loading2}
		value={asyncValue2}
		asyncLoading
		onincrease={() => handleChange2('increase')}
		ondecrease={() => handleChange2('decrease')}
	/>
	<Stepper
		async={loading3}
		value={asyncValue3}
		asyncLoading
		loading={{ type: '1_51' }}
		onincrease={() => handleChange3('increase')}
		ondecrease={() => handleChange3('decrease')}
	/>
</div>

<div class="mx-4 mt-8 text-lg font-bold">No external padding</div>
<div class="px-4 py-2">
	<Stepper padding={false} />
</div>
<div class="px-4 py-2">
	<Stepper padding={false} numberHighlight />
</div>
<div class="px-4 py-2">
	<Stepper padding={false} theme={false} />
</div>

<div class="mx-4 mt-8 text-lg font-bold">Inject Class in Different Positions</div>
<div class="px-4 py-2">
	<Stepper theme={false} injClassOut="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0]" />
</div>
<div class="px-4 py-2">
	<Stepper injClassNum="text-primary dark:text-dark" />
</div>
<div class="px-4 py-2">
	<Stepper injClassBtn="rounded-full" />
</div>



================================================
FILE: packages/stdf/src/routes/stepper/zh_CN/+page.svelte
================================================
<!-- Stepper Demo -->
<script lang="ts">
	import { Stepper, Toast } from '$lib/index.js';

	let asyncValue1 = $state(1);
	let loading1 = $state(false);
	let asyncValue2 = $state(1);
	let loading2 = $state(false);
	let asyncValue3 = $state(1);
	let loading3 = $state(false);
	const handleChange1 = (type: 'increase' | 'decrease') => {
		loading1 = true;
		setTimeout(() => {
			asyncValue1 += type === 'increase' ? 1 : -1;
			loading1 = false;
		}, 2000);
	};
	const handleChange2 = (type: 'increase' | 'decrease') => {
		loading2 = true;
		setTimeout(() => {
			asyncValue2 += type === 'increase' ? 1 : -1;
			loading2 = false;
		}, 3000);
	};
	const handleChange3 = (type: 'increase' | 'decrease') => {
		loading3 = true;
		setTimeout(() => {
			asyncValue3 += type === 'increase' ? 1 : -1;
			loading3 = false;
		}, 4000);
	};
</script>

<div class="mx-4 mt-8 text-lg font-bold">基础用法</div>
<div class="px-4 py-4">
	<Stepper />
</div>

<div class="mx-4 mt-8 text-lg font-bold">设置最大值/最小值/初始值</div>
<div class="px-4 py-4">
	<Stepper min={2} max={10} value={5} />
</div>

<div class="mx-4 mt-8 text-lg font-bold">设置步长</div>
<div class="px-4 py-4">
	<Stepper step={5} />
</div>

<div class="mx-4 mt-8 text-lg font-bold">强调数字区域</div>
<div class="px-4 py-4">
	<Stepper numberHighlight />
</div>

<div class="mx-4 mt-8 text-lg font-bold">强调区域不用主题色</div>
<div class="flex gap-2 px-4 py-4">
	<Stepper theme={false} />
	<Stepper theme={false} numberHighlight />
</div>

<div class="mx-4 mt-8 text-lg font-bold">不同圆角</div>
<div class="flex flex-wrap gap-2 px-4 py-4">
	<div><Stepper radius="none" /></div>
	<div><Stepper radius="sm" /></div>
	<div><Stepper radius="xl" /></div>
	<div><Stepper radius="full" /></div>
	<div><Stepper radius="full" numberHighlight /></div>
	<div><Stepper radius="full" theme={false} /></div>
</div>

<div class="mx-4 mt-8 text-lg font-bold">竖向</div>
<div class="flex justify-around px-2 py-4">
	<Stepper vertical />
	<Stepper vertical numberHighlight />
	<Stepper vertical theme={false} />
	<Stepper vertical radius="none" />
	<Stepper radius="xl" vertical />
</div>

<div class="mx-4 mt-8 text-lg font-bold">格式化显示数字</div>
<div class="px-4 py-4">
	<div class="mb-2 text-sm">保留一位小数</div>
	<Stepper decimal={1} step={0.1} max={1} min={0.1} value={0.5} />
</div>
<div class="px-4 py-4">
	<div class="mb-2 text-sm">保留四位小数</div>
	<Stepper decimal={4} step={0.0001} max={1} min={0.0001} value={0.5} />
</div>

<div class="mx-4 mt-8 text-lg font-bold">异步显示数字</div>
<div class="px-4 py-4">
	<div class="mb-2 text-sm">Toast 显示异步状态</div>
	<Stepper async={loading1} value={asyncValue1} onincrease={() => handleChange1('increase')} ondecrease={() => handleChange1('decrease')} />
</div>
<Toast bind:visible={loading1} type="loading" message="保存中..." />
<div class="mb-2 px-4 text-sm">内部显示异步状态</div>
<div class="flex gap-2 px-4 py-4">
	<Stepper
		async={loading2}
		value={asyncValue2}
		asyncLoading
		onincrease={() => handleChange2('increase')}
		ondecrease={() => handleChange2('decrease')}
	/>
	<Stepper
		async={loading3}
		value={asyncValue3}
		asyncLoading
		loading={{ type: '1_51' }}
		onincrease={() => handleChange3('increase')}
		ondecrease={() => handleChange3('decrease')}
	/>
</div>

<div class="mx-4 mt-8 text-lg font-bold">外部无 padding</div>
<div class="px-4 py-2">
	<Stepper padding={false} />
</div>
<div class="px-4 py-2">
	<Stepper padding={false} numberHighlight />
</div>
<div class="px-4 py-2">
	<Stepper padding={false} theme={false} />
</div>

<div class="mx-4 mt-8 text-lg font-bold">不同位置注入 Class</div>
<div class="px-4 py-2">
	<Stepper theme={false} injClassOut="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0]" />
</div>
<div class="px-4 py-2">
	<Stepper injClassNum="text-primary dark:text-dark" />
</div>
<div class="px-4 py-2">
	<Stepper injClassBtn="rounded-full" />
</div>



================================================
FILE: packages/stdf/src/routes/steps/en_US/+page.svelte
================================================
<!--Steps Demo -->
<script lang="ts">
	import { Steps, Button, Divider } from '$lib/index.js';
	import type { StepsItemProps } from '$lib/types/index.js';
	import injCom1 from './injCom1_en.svelte';
	import injCom2 from './injCom2_en.svelte';

	const steps: StepsItemProps[] = [
		{ step: { title: 'Get up' } },
		{ step: { title: 'Eat' } },
		{ step: { title: 'Drink' } },
		{ step: { title: 'Beat beans' } },
		{ step: { title: 'sleep' } }
	];
	const steps1: StepsItemProps[] = [
		{ step: { title: 'Get up', bar: { type: 'icon', content: { name: 'ri-hotel-bed-line' } } } },
		{ step: { title: 'Eat', bar: { type: 'icon', content: { name: 'ri-restaurant-2-line' } } } },
		{ step: { title: 'Drink', bar: { type: 'icon', content: { name: 'ri-cup-line' } } } },
		{ step: { title: 'Beat beans', bar: { type: 'icon', content: { name: 'ri-emotion-sad-line' } } } },
		{ step: { title: 'sleep', bar: { type: 'icon', content: { name: 'ri-zzz-line' } } } }
	];
	const steps2: StepsItemProps[] = [
		{ step: { title: 'Get up' }, finishStep: { title: 'Have got up' } },
		{ step: { title: 'Eat' }, finishStep: { title: 'Have had enough' } },
		{ step: { title: 'Drink' }, finishStep: { title: 'Drink up' } },
		{ step: { title: 'Beat beans' }, finishStep: { title: 'Have a good time' } },
		{ step: { title: 'sleep' }, finishStep: { title: 'Fall asleep' } }
	];
	const steps3: StepsItemProps[] = [
		{
			step: { title: 'Get up', bar: { type: 'icon', content: { name: 'ri-hotel-bed-line' } } },
			finishStep: { title: 'Have got up', bar: { type: 'icon', content: { name: 'ri-hotel-bed-fill' } } }
		},
		{
			step: { title: 'Eat', bar: { type: 'icon', content: { name: 'ri-restaurant-2-line' } } },
			finishStep: { title: 'Have had enough', bar: { type: 'icon', content: { name: 'ri-restaurant-2-fill' } } }
		},
		{
			step: { title: 'Drink', bar: { type: 'icon', content: { name: 'ri-cup-line' } } },
			finishStep: { title: 'Drink up', bar: { type: 'icon', content: { name: 'ri-cup-fill' } } }
		},
		{
			step: { title: 'Beat beans', bar: { type: 'icon', content: { name: 'ri-emotion-sad-line' } } },
			finishStep: { title: 'Have a good time', bar: { type: 'icon', content: { name: 'ri-emotion-sad-fill' } } }
		},
		{
			step: { title: 'sleep', bar: { type: 'icon', content: { name: 'ri-zzz-line' } } },
			finishStep: { title: 'Fall asleep', bar: { type: 'icon', content: { name: 'ri-zzz-fill' } } }
		}
	];
	const steps4: StepsItemProps[] = [
		{ step: { title: 'Get up', desc: 'Get up and move bricks!' } },
		{ step: { title: 'Eat', desc: 'Eat, eat, eat, eat, fat you.' } },
		{ step: { title: 'Drink', desc: 'Walk slowly and drink lots of water.' } },
		{
			step: {
				title: 'Beat beans',
				desc: "Eat, sleep, play peas it's cool, it's cool, it's cool, it's cool. By the way to verify the progress bar height adaptive step text height."
			}
		},
		{ step: { title: 'sleep', desc: 'Too full to sleep.' } }
	];
	const steps5: StepsItemProps[] = [
		{ step: { title: 'Get up', desc: 'Get up and move bricks!', bar: { type: 'icon', content: { name: 'ri-hotel-bed-line' } } } },
		{ step: { title: 'Eat', desc: 'Eat, eat, eat, eat, fat you.', bar: { type: 'icon', content: { name: 'ri-restaurant-2-line' } } } },
		{ step: { title: 'Drink', desc: 'Walk slowly and drink lots of water.', bar: { type: 'icon', content: { name: 'ri-cup-line' } } } },
		{
			step: {
				title: 'Beat beans',
				desc: "Eat, sleep, play peas It's cool, it's cool, it's cool, it's cool, it's cool. By the way to verify the progress bar height adaptive step text height.",
				bar: { type: 'icon', content: { name: 'ri-emotion-sad-line' } }
			}
		},
		{ step: { title: 'sleep', desc: 'Too full to sleep.', bar: { type: 'icon', content: { name: 'ri-zzz-line' } } } }
	];
	const steps6: StepsItemProps[] = [
		{
			step: { title: 'Get up', desc: 'Get up and move bricks!', bar: { type: 'icon', content: { name: 'ri-hotel-bed-line' } } },
			finishStep: { title: 'Have got up', desc: 'The bricks are gone!', bar: { type: 'icon', content: { name: 'ri-hotel-bed-fill' } } }
		},
		{
			step: { title: 'Eat', desc: 'Eat, eat, eat, eat, fat you.', bar: { type: 'icon', content: { name: 'ri-restaurant-2-line' } } },
			finishStep: {
				title: 'Have had enough',
				desc: 'The meal has been eaten up!',
				bar: { type: 'icon', content: { name: 'ri-restaurant-2-fill' } }
			}
		},
		{
			step: { title: 'Drink', desc: 'Walk slowly and drink lots of water.', bar: { type: 'icon', content: { name: 'ri-cup-line' } } },
			finishStep: {
				title: 'Drink up',
				desc: 'I drink too much water and it spills out of my eyes!',
				bar: { type: 'icon', content: { name: 'ri-cup-fill' } }
			}
		},
		{
			step: { title: 'Beat beans', desc: 'Eat, sleep, play beans.', bar: { type: 'icon', content: { name: 'ri-emotion-sad-line' } } },
			finishStep: {
				title: 'Have a good time',
				desc: 'Doudou has been beaten to the ground.',
				bar: { type: 'icon', content: { name: 'ri-emotion-sad-fill' } }
			}
		},
		{
			step: { title: 'sleep', desc: 'Too full to sleep.', bar: { type: 'icon', content: { name: 'ri-zzz-line' } } },
			finishStep: { title: 'Fall asleep', desc: 'Asleep and dreaming!', bar: { type: 'icon', content: { name: 'ri-zzz-fill' } } }
		}
	];
	const steps7: StepsItemProps[] = [
		{ step: { title: 'Get up', desc: 'Get up and move bricks!', bar: { type: 'string', content: '1' } } },
		{ step: { title: 'Eat', desc: 'Eat, eat, eat, eat, fat you.', bar: { type: 'string', content: 'eat' } } },
		{ step: { title: 'Drink', desc: 'Walk slowly and drink lots of water.', bar: { type: 'string', content: '3' } } },
		{ step: { title: 'Beat beans', desc: 'Eat, sleep, play beans.', bar: { type: 'icon', content: { name: 'ri-emotion-sad-line' } } } },
		{ step: { title: 'sleep', desc: 'Too full to sleep.', bar: { type: 'string', content: '😴' } } }
	];
	const steps8: StepsItemProps[] = [
		{ step: { title: 'Get up', bar: { type: 'image', content: '/assets/images/avatar_2.png' } } },
		{ step: { title: 'Eat', bar: { type: 'icon', content: { name: 'ri-restaurant-2-line' } } } },
		{ step: { title: 'Drink', bar: { type: 'icon', content: { name: 'ri-cup-line' } } } },
		{ step: { title: 'Beat beans', bar: { type: 'image', content: '/assets/images/avatar_1.jpg' } } },
		{ step: { title: 'sleep', bar: { type: 'icon', content: { name: 'ri-zzz-line' } } } }
	];
	const steps9: StepsItemProps[] = [
		{ step: { title: 'Get up', desc: 'Get up and move bricks!', bar: { type: 'icon', content: { name: 'ri-hotel-bed-line' } } } },
		{
			step: {
				title: 'Eat',
				desc: 'Eat, eat, eat, eat, fat you.',
				bar: { type: 'icon', content: { name: 'ri-restaurant-2-line' } },
				injComponent: injCom1
			}
		},
		{ step: { title: 'Drink', desc: 'Walk slowly and drink lots of water.', bar: { type: 'icon', content: { name: 'ri-cup-line' } } } },
		{
			step: {
				title: 'Beat beans',
				desc: 'Eat, sleep, play beans.',
				bar: { type: 'icon', content: { name: 'ri-emotion-sad-line' } },
				injComponent: injCom2
			}
		},
		{ step: { title: 'sleep', desc: 'Too full to sleep.', bar: { type: 'icon', content: { name: 'ri-zzz-line' } } } }
	];

	let current = $state(1);
</script>

<div class="mb-4 mt-8 px-4 text-2xl font-bold">Horizontal arrangement</div>
<div class="mb-4 mt-8 px-4 text-lg font-bold">Simple usage</div>
<Steps {steps} {current} />

<div class="mb-4 mt-8 px-4 text-lg font-bold">Different fillet</div>
<Steps {steps} {current} radius="none" />
<Steps {steps} {current} radius="full" />

<div class="mb-4 mt-8 px-4 text-lg font-bold">Tape icon</div>
<Steps steps={steps1} {current} />

<div class="mb-4 mt-8 px-4 text-lg font-bold">Different icon border</div>
<Steps steps={steps1} {current} barBorder={false} />
<Steps steps={steps1} {current} barBorder={false} radius="full" />
<Steps steps={steps1} {current} radius="none" />
<Steps steps={steps1} {current} radius="xl" />
<Steps steps={steps1} {current} radius="full" />

<div class="mb-4 mt-8 px-4 text-lg font-bold">Tape completion step</div>
<Steps steps={steps2} {current} />

<div class="mb-4 mt-8 px-4 text-lg font-bold">Tape icon && Complete steps</div>
<Steps steps={steps3} {current} />

<div class="mb-4 mt-8 px-4 text-lg font-bold">The step bar area uses text</div>
<Steps steps={steps7} {current} />

<div class="mb-4 mt-8 px-4 text-lg font-bold">Use images for the step bar area</div>
<Steps steps={steps8} {current} />
<Steps steps={steps8} radius="full" {current} />
<Divider />

<div class="mb-4 mt-4 px-4 text-2xl font-bold">Longitudinal arrangement</div>
<div class="mb-4 mt-8 px-4 text-lg font-bold">Different fillet</div>
<div class="flex justify-around">
	<Steps {steps} {current} vertical />
	<Steps {steps} {current} radius="none" vertical />
	<Steps {steps} {current} radius="full" vertical />
</div>

<div class="mb-4 mt-8 px-4 text-lg font-bold">Different icon border</div>
<div class="flex justify-around">
	<Steps steps={steps1} {current} vertical />
	<Steps steps={steps1} {current} vertical radius="full" barBorder={false} />
</div>
<Divider px="8" />
<div class="flex justify-around">
	<Steps steps={steps1} {current} vertical barBorder={false} radius="none" />
	<Steps steps={steps1} {current} vertical radius="none" />
</div>
<Divider px="8" />
<div class="flex justify-around">
	<Steps steps={steps1} {current} vertical radius="xl" />
	<Steps steps={steps1} {current} vertical radius="full" />
</div>

<div class="mb-4 mt-8 px-4 text-lg font-bold">Tape description information</div>
<Steps steps={steps4} {current} vertical />
<Divider px="8" />
<Steps steps={steps5} {current} vertical />

<div class="mb-4 mt-8 px-4 text-lg font-bold">Tape completion step</div>
<Steps steps={steps6} {current} vertical />

<div class="mb-4 mt-8 px-4 text-lg font-bold">The step bar area uses text</div>
<Steps steps={steps7} {current} vertical />

<div class="mb-4 mt-8 px-4 text-lg font-bold">Use images for the step bar area</div>
<div class="flex justify-around">
	<Steps steps={steps8} {current} vertical />
	<Steps steps={steps8} {current} radius="full" vertical />
</div>

<div class="mb-4 mt-8 px-4 text-lg font-bold">The content area injects elements</div>
<Steps steps={steps9} {current} vertical />

<div class="sticky bottom-0 z-10 flex bg-white/50 backdrop-blur-sm dark:bg-black/50">
	<div class="flex-1">
		<Button fill="lineTheme" disabled={current === 1} onclick={() => current > 1 && current--}>Previous step</Button>
	</div>
	<div class="flex-1">
		<Button fill="lineTheme" disabled={current === steps.length} onclick={() => current < steps.length + 1 && current++}>Next step</Button>
	</div>
</div>

<!-- injCom1.svelte -->
<!-- 
<div class="text-primary dark:text-dark text-sm">
    <div>Here you inject a picture as a component</div>
    <div class="rounded-full overflow-hidden h-20 w-20">
        <img src="/assets/images/avatar_1.jpg" alt="" />
    </div>
</div>
-->

<!-- injCom2.svelte -->
<!-- 
<script lang="ts">
    import { Button, Icon, Avatar } from '$lib/index.js';
</script>

<div class="text-primary dark:text-dark text-sm">Here you inject something in the form of a component</div>
<div class="flex items-center space-x-4">
    <Button size="full" heightIn="2" injClass="px-4">button</Button>
    <Avatar image="/assets/images/avatar_1.jpg" size="sm" />
    <Icon name="ri-money-cny-circle-line" theme />
    <Icon name="ri-fingerprint-line" theme />
</div> 
-->



================================================
FILE: packages/stdf/src/routes/steps/en_US/injCom1_en.svelte
================================================
<div class="text-primary dark:text-dark text-sm">
	<div>Here you inject a picture as a component</div>
	<div class="rounded-full overflow-hidden h-20 w-20">
		<img src="/assets/images/avatar_1.jpg" alt="" />
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/steps/en_US/injCom2_en.svelte
================================================
<script lang="ts">
	import { Button, Icon, Avatar } from '$lib/index.js';
</script>

<div class="text-sm text-primary dark:text-dark">Here you inject something in the form of a component</div>
<div class="flex items-center space-x-4">
	<Button size="full" heightIn="2" injClass="px-4">button</Button>
	<Avatar image="/assets/images/avatar_1.jpg" size="sm" />
	<Icon name="ri-money-cny-circle-line" theme />
	<Icon name="ri-fingerprint-line" theme />
</div>



================================================
FILE: packages/stdf/src/routes/steps/zh_CN/+page.svelte
================================================
<!--Steps Demo -->
<script lang="ts">
	import { Steps, Button, Divider } from '$lib/index.js';
	import type { StepsItemProps } from '$lib/types/index.js';
	import injCom1 from './injCom1.svelte';
	import injCom2 from './injCom2.svelte';

	const steps: StepsItemProps[] = [
		{ step: { title: '起床' } },
		{ step: { title: '吃饭' } },
		{ step: { title: '喝水' } },
		{ step: { title: '打豆豆' } },
		{ step: { title: '睡觉' } }
	];
	const steps1: StepsItemProps[] = [
		{ step: { title: '起床', bar: { type: 'icon', content: { name: 'ri-hotel-bed-line' } } } },
		{ step: { title: '吃饭', bar: { type: 'icon', content: { name: 'ri-restaurant-2-line' } } } },
		{ step: { title: '喝水', bar: { type: 'icon', content: { name: 'ri-cup-line' } } } },
		{ step: { title: '打豆豆', bar: { type: 'icon', content: { name: 'ri-emotion-sad-line' } } } },
		{ step: { title: '睡觉', bar: { type: 'icon', content: { name: 'ri-zzz-line' } } } }
	];
	const steps2: StepsItemProps[] = [
		{ step: { title: '起床' }, finishStep: { title: '已起床' } },
		{ step: { title: '吃饭' }, finishStep: { title: '吃饱了' } },
		{ step: { title: '喝水' }, finishStep: { title: '喝足了' } },
		{ step: { title: '打豆豆' }, finishStep: { title: '打爽了' } },
		{ step: { title: '睡觉' }, finishStep: { title: '睡着了' } }
	];
	const steps3: StepsItemProps[] = [
		{
			step: { title: '起床', bar: { type: 'icon', content: { name: 'ri-hotel-bed-line' } } },
			finishStep: { title: '已起床', bar: { type: 'icon', content: { name: 'ri-hotel-bed-fill' } } }
		},
		{
			step: { title: '吃饭', bar: { type: 'icon', content: { name: 'ri-restaurant-2-line' } } },
			finishStep: { title: '吃饱了', bar: { type: 'icon', content: { name: 'ri-restaurant-2-fill' } } }
		},
		{
			step: { title: '喝水', bar: { type: 'icon', content: { name: 'ri-cup-line' } } },
			finishStep: { title: '喝足了', bar: { type: 'icon', content: { name: 'ri-cup-fill' } } }
		},
		{
			step: { title: '打豆豆', bar: { type: 'icon', content: { name: 'ri-emotion-sad-line' } } },
			finishStep: { title: '打爽了', bar: { type: 'icon', content: { name: 'ri-emotion-sad-fill' } } }
		},
		{
			step: { title: '睡觉', bar: { type: 'icon', content: { name: 'ri-zzz-line' } } },
			finishStep: { title: '睡着了', bar: { type: 'icon', content: { name: 'ri-zzz-fill' } } }
		}
	];
	const steps4: StepsItemProps[] = [
		{ step: { title: '起床', desc: '起床搬砖了！' } },
		{ step: { title: '吃饭', desc: '吃吃吃，肥死你。' } },
		{ step: { title: '喝水', desc: '慢慢走路，多多喝水。' } },
		{
			step: {
				title: '打豆豆',
				desc: '吃饭睡觉，打豆豆很爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽。顺便验证进度条高度自适应步骤文字高度。'
			}
		},
		{ step: { title: '睡觉', desc: '吃太饱，睡不着。' } }
	];
	const steps5: StepsItemProps[] = [
		{ step: { title: '起床', desc: '起床搬砖了！', bar: { type: 'icon', content: { name: 'ri-hotel-bed-line' } } } },
		{ step: { title: '吃饭', desc: '吃吃吃，肥死你。', bar: { type: 'icon', content: { name: 'ri-restaurant-2-line' } } } },
		{ step: { title: '喝水', desc: '慢慢走路，多多喝水。', bar: { type: 'icon', content: { name: 'ri-cup-line' } } } },
		{
			step: {
				title: '打豆豆',
				desc: '吃饭睡觉，打豆豆很爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽爽。顺便验证进度条高度自适应步骤文字高度。',
				bar: { type: 'icon', content: { name: 'ri-emotion-sad-line' } }
			}
		},
		{ step: { title: '睡觉', desc: '吃太饱，睡不着。', bar: { type: 'icon', content: { name: 'ri-zzz-line' } } } }
	];
	const steps6: StepsItemProps[] = [
		{
			step: { title: '起床', desc: '起床搬砖了！', bar: { type: 'icon', content: { name: 'ri-hotel-bed-line' } } },
			finishStep: { title: '已起床', desc: '砖已经搬完了！', bar: { type: 'icon', content: { name: 'ri-hotel-bed-fill' } } }
		},
		{
			step: { title: '吃饭', desc: '吃吃吃，肥死你。', bar: { type: 'icon', content: { name: 'ri-restaurant-2-line' } } },
			finishStep: { title: '吃饱了', desc: '饭已经全部被吃完了！', bar: { type: 'icon', content: { name: 'ri-restaurant-2-fill' } } }
		},
		{
			step: { title: '喝水', desc: '慢慢走路，多多喝水。', bar: { type: 'icon', content: { name: 'ri-cup-line' } } },
			finishStep: { title: '喝足了', desc: '水喝太多，从眼睛里溢出来了！', bar: { type: 'icon', content: { name: 'ri-cup-fill' } } }
		},
		{
			step: { title: '打豆豆', desc: '吃饭睡觉，打豆豆。', bar: { type: 'icon', content: { name: 'ri-emotion-sad-line' } } },
			finishStep: { title: '打爽了', desc: '豆豆已经被打趴下了。', bar: { type: 'icon', content: { name: 'ri-emotion-sad-fill' } } }
		},
		{
			step: { title: '睡觉', desc: '吃太饱，睡不着。', bar: { type: 'icon', content: { name: 'ri-zzz-line' } } },
			finishStep: { title: '睡着了', desc: '睡着了正在做梦呢！', bar: { type: 'icon', content: { name: 'ri-zzz-fill' } } }
		}
	];
	const steps7: StepsItemProps[] = [
		{ step: { title: '起床', desc: '起床搬砖了！', bar: { type: 'string', content: '1' } } },
		{ step: { title: '吃饭', desc: '吃吃吃，肥死你。', bar: { type: 'string', content: '吃' } } },
		{ step: { title: '喝水', desc: '慢慢走路，多多喝水。', bar: { type: 'string', content: '3' } } },
		{ step: { title: '打豆豆', desc: '吃饭睡觉，打豆豆。', bar: { type: 'string', content: '5' } } },
		{ step: { title: '睡觉', desc: '吃太饱，睡不着。', bar: { type: 'string', content: '😴' } } }
	];
	const steps8: StepsItemProps[] = [
		{ step: { title: '起床', bar: { type: 'image', content: '/assets/images/avatar_2.png' } } },
		{ step: { title: '吃饭', bar: { type: 'icon', content: { name: 'ri-restaurant-2-line' } } } },
		{ step: { title: '喝水', bar: { type: 'icon', content: { name: 'ri-cup-line' } } } },
		{ step: { title: '打豆豆', bar: { type: 'image', content: '/assets/images/avatar_1.jpg' } } },
		{ step: { title: '睡觉', bar: { type: 'icon', content: { name: 'ri-zzz-line' } } } }
	];
	const steps9: StepsItemProps[] = [
		{ step: { title: '起床', desc: '起床搬砖了！', bar: { type: 'icon', content: { name: 'ri-hotel-bed-line' } } } },
		{
			step: {
				title: '吃饭',
				desc: '吃吃吃，肥死你。',
				bar: { type: 'icon', content: { name: 'ri-restaurant-2-line' } },
				injComponent: injCom1
			}
		},
		{ step: { title: '喝水', desc: '慢慢走路，多多喝水。', bar: { type: 'icon', content: { name: 'ri-cup-line' } } } },
		{
			step: {
				title: '打豆豆',
				desc: '吃饭睡觉，打豆豆。',
				bar: { type: 'icon', content: { name: 'ri-emotion-sad-line' } },
				injComponent: injCom2
			}
		},
		{ step: { title: '睡觉', desc: '吃太饱，睡不着。', bar: { type: 'icon', content: { name: 'ri-zzz-line' } } } }
	];

	let current = $state(1);
</script>

<div class="mb-4 mt-8 px-4 text-2xl font-bold">横向排列</div>
<div class="mb-4 mt-8 px-4 text-lg font-bold">简单用法</div>
<Steps {steps} {current} />

<div class="mb-4 mt-8 px-4 text-lg font-bold">不同圆角</div>
<Steps {steps} {current} radius="none" />
<Steps {steps} {current} radius="full" />

<div class="mb-4 mt-8 px-4 text-lg font-bold">带图标</div>
<Steps steps={steps1} {current} />

<div class="mb-4 mt-8 px-4 text-lg font-bold">图标不同边框</div>
<Steps steps={steps1} {current} barBorder={false} />
<Steps steps={steps1} {current} barBorder={false} radius="full" />
<Steps steps={steps1} {current} radius="none" />
<Steps steps={steps1} {current} radius="xl" />
<Steps steps={steps1} {current} radius="full" />

<div class="mb-4 mt-8 px-4 text-lg font-bold">带完成步骤</div>
<Steps steps={steps2} {current} />

<div class="mb-4 mt-8 px-4 text-lg font-bold">带图标 && 完成步骤</div>
<Steps steps={steps3} {current} />

<div class="mb-4 mt-8 px-4 text-lg font-bold">步骤栏区域使用文字</div>
<Steps steps={steps7} {current} />

<div class="mb-4 mt-8 px-4 text-lg font-bold">步骤栏区域使用图片</div>
<Steps steps={steps8} {current} />
<Steps steps={steps8} radius="full" {current} />
<Divider />

<div class="mb-4 mt-4 px-4 text-2xl font-bold">纵向排列</div>
<div class="mb-4 mt-8 px-4 text-lg font-bold">不同圆角</div>
<div class="flex justify-around">
	<Steps {steps} {current} vertical />
	<Steps {steps} {current} radius="none" vertical />
	<Steps {steps} {current} radius="full" vertical />
</div>

<div class="mb-4 mt-8 px-4 text-lg font-bold">图标不同边框</div>
<div class="flex justify-around">
	<Steps steps={steps1} {current} vertical />
	<Steps steps={steps1} {current} vertical radius="full" barBorder={false} />
</div>
<Divider px="8" />
<div class="flex justify-around">
	<Steps steps={steps1} {current} vertical barBorder={false} radius="none" />
	<Steps steps={steps1} {current} vertical radius="none" />
</div>
<Divider px="8" />
<div class="flex justify-around">
	<Steps steps={steps1} {current} vertical radius="xl" />
	<Steps steps={steps1} {current} vertical radius="full" />
</div>

<div class="mb-4 mt-8 px-4 text-lg font-bold">带描述信息</div>
<Steps steps={steps4} {current} vertical />
<Divider px="8" />
<Steps steps={steps5} {current} vertical />

<div class="mb-4 mt-8 px-4 text-lg font-bold">带完成步骤</div>
<Steps steps={steps6} {current} vertical />

<div class="mb-4 mt-8 px-4 text-lg font-bold">步骤栏区域使用文字</div>
<Steps steps={steps7} {current} vertical />

<div class="mb-4 mt-8 px-4 text-lg font-bold">步骤栏区域使用图片</div>
<div class="flex justify-around">
	<Steps steps={steps8} {current} vertical />
	<Steps steps={steps8} {current} radius="full" vertical />
</div>

<div class="mb-4 mt-8 px-4 text-lg font-bold">内容区域注入元素</div>
<Steps steps={steps9} {current} vertical />

<div class="sticky bottom-0 z-10 flex bg-white/50 backdrop-blur-sm dark:bg-black/50">
	<div class="flex-1">
		<Button fill="lineTheme" disabled={current === 1} onclick={() => current > 1 && current--}>上一步</Button>
	</div>
	<div class="flex-1">
		<Button fill="lineTheme" disabled={current === steps.length} onclick={() => current < steps.length + 1 && current++}>下一步</Button>
	</div>
</div>

<!-- injCom1.svelte -->
<!-- <div class="text-primary dark:text-dark text-sm">
    <div>此处以组件形式注入一张图片</div>
    <div class="rounded-full overflow-hidden h-20 w-20">
        <img src="/assets/images/avatar_1.jpg" alt="" />
    </div>
</div> -->

<!-- injCom2.svelte -->
<!-- <script lang=""ts>
    import { Button, Icon, Avatar } from '$lib/index.js';
</script>

<div class="text-primary dark:text-dark text-sm">此处以组件形式注入一些内容</div>
<div class="flex items-center space-x-4">
    <Button size="full" heightIn="2" injClass="px-4">按钮</Button>
    <Avatar image="/assets/images/avatar_1.jpg" size="sm" />
    <Icon name="ri-money-cny-circle-line" theme />
    <Icon name="ri-fingerprint-line" theme />
</div> -->



================================================
FILE: packages/stdf/src/routes/steps/zh_CN/injCom1.svelte
================================================
<div class="text-primary dark:text-dark text-sm">
	<div>此处以组件形式注入一张图片</div>
	<div class="rounded-full overflow-hidden h-20 w-20">
		<img src="/assets/images/avatar_1.jpg" alt="" />
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/steps/zh_CN/injCom2.svelte
================================================
<script lang="ts">
	import { Button, Icon, Avatar } from '$lib/index.js';
</script>

<div class="text-sm text-primary dark:text-dark">此处以组件形式注入一些内容</div>
<div class="flex items-center space-x-4">
	<Button size="full" heightIn="2" injClass="px-4">按钮</Button>
	<Avatar image="/assets/images/avatar_1.jpg" size="sm" />
	<Icon name="ri-money-cny-circle-line" theme />
	<Icon name="ri-fingerprint-line" theme />
</div>



================================================
FILE: packages/stdf/src/routes/swiper/en_US/+page.svelte
================================================
<!-- Swiper Demo -->
<script lang="ts">
	import { Swiper } from '$lib/index.js';
	import type { SwiperImgProps } from '$lib/types/index.js';
	import Item from './Item_en.svelte';

	const data: SwiperImgProps[] = [
		{ type: 'img', url: '/assets/images/wall_1.jpg' },
		{ type: 'img', url: '/assets/images/wall_2.jpg' },
		{ type: 'img', url: '/assets/images/wall_3.jpg' },
		{ type: 'img', url: '/assets/images/wall_4.jpg' }
	];

	let indexClick = $state(-1);
	let indexChange = $state(0);
</script>

<div class="mx-4 mb-2 mt-10 text-lg font-bold">Basic Usage</div>
<Swiper {data} />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">Initial Index 2</div>
<Swiper {data} initActive={2} />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">8s Interval</div>
<Swiper {data} interval={8} />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">1500ms Duration</div>
<Swiper {data} duration={1500} />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">Disable Autoplay</div>
<Swiper {data} autoplay={false} />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">External Indicator</div>
<Swiper {data} indicatePosition="out" />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">Hide Indicator</div>
<Swiper {data} indicatePosition={null} />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">Right Aligned Indicator</div>
<Swiper {data} indicateAlign="right" />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">Dot Indicator</div>
<Swiper {data} indicateStyle="point" />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">Line Indicator</div>
<Swiper {data} indicateStyle="line" />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">Long Line Indicator</div>
<Swiper {data} indicateStyle="longLine" interval={8} />
<div class="mt-10"></div>
<Swiper {data} indicateStyle="longLine" interval={8} indicatePosition="out" />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">Square Indicator</div>
<Swiper {data} indicateRadius={false} />
<div class="mt-10"></div>
<Swiper {data} indicateStyle="point" indicateRadius={false} />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">
	Custom Indicator Background
	<p class="mb-2 text-xs font-thin">Inject Class</p>
</div>
<Swiper {data} indicateInjClass="from-black/0 to-extend0/50" />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">
	Custom Indicator Color
	<p class="mb-2 text-xs font-thin">Remove Background</p>
</div>
<Swiper {data} indicateInjClass="bg-none" indicateColor="bg-extend2" indicateActiveColor="bg-extend1" />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">Custom Aspect Ratio</div>
<Swiper {data} aspectRatio={[4, 1]} />

<div class="mx-4 mt-10 text-lg font-bold">
	Container Padding
	<p class="mb-2 text-xs font-thin">With Custom Colors and Radius</p>
</div>
<Swiper
	{data}
	px="6"
	py="6"
	indicateInjClass="bg-none"
	indicateColor="bg-black/5 dark:bg-white/10"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	interval={8}
	indicateStyle="longLine"
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="6"
	py="6"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="full"
	aspectRatio={[3, 1]}
/>

<div class="mx-4 mb-2 mt-10 text-lg font-bold">
	Inner Shadow
	<p class="mb-2 text-xs font-normal">Inject Class</p>
</div>
<Swiper
	{data}
	px="6"
	py="6"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="full"
	aspectRatio={[3, 1]}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
/>

<div class="mx-4 mb-2 mt-10 text-lg font-bold">Inactive Item X, Z Translation</div>
<Swiper
	{data}
	px="16"
	py="6"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	aspectRatio={[3, 1]}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	translateX={100}
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="4"
	py="8"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	translateZ={400}
	translateX={-200}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="12"
	py="8"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	translateZ={600}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
/>

<div class="mx-4 mb-2 mt-10 text-lg font-bold">Inactive Item X, Y, Z Rotation</div>
<Swiper
	{data}
	px="4"
	py="8"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	rotateX={90}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	duration={2000}
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="4"
	py="8"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	rotateY={90}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	duration={2000}
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="4"
	py="8"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	rotateZ={90}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	duration={2000}
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="4"
	py="8"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	rotateX={90}
	rotateY={90}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	duration={2000}
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="4"
	py="8"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	rotateX={90}
	rotateZ={90}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	duration={2000}
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="4"
	py="8"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	rotateY={90}
	rotateZ={90}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	duration={2000}
/>

<div class="mx-4 mb-2 mt-10 text-lg font-bold">Custom Inactive Item Style</div>
<Swiper
	{data}
	px="24"
	py="6"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	radius="xl"
	aspectRatio={[3, 1]}
	translateX={160}
	duration={2000}
	notActiveInjClass="grayscale"
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="24"
	py="6"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	radius="xl"
	aspectRatio={[3, 1]}
	translateX={160}
	duration={2000}
	notActiveInjClass="blur"
/>

<div class="mx-4 mb-2 mt-10 text-lg font-bold">Custom Container Width</div>
<div class="flex justify-center">
	<Swiper {data} containerWidth={(document.body.clientWidth / 4) * 3} />
</div>

<div class="mx-4 mb-2 mt-10 text-lg font-bold">Component as Content</div>
<Swiper
	data={[
		{ type: 'component', component: Item },
		{ type: 'img', url: '/assets/images/wall_1.jpg' }
	]}
/>

<div class="mx-4 mb-2 mt-10 text-lg font-bold">
	onchange Event
	<p class=" mb-2 text-xs font-normal">Current Index: {indexChange}</p>
</div>
<Swiper {data} onchange={(current) => (indexChange = current)} />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">
	onclick Event
	<p class="mb-2 text-xs font-normal">Clicked Index: {indexClick === -1 ? 'None' : indexClick}</p>
</div>
<Swiper {data} onclick={(current) => (indexClick = current)} />

<!-- Item_en.svelte -->
<!--
<script lang="ts">
	import { Button, Avatar } from 'stdf';
</script>

<div class="flex flex-col space-y-4 items-center">
	<div class="text-center">This container uses a single component as its content</div>
	<div><Avatar /></div>
	<div class="w-full"><Button>button</Button></div>
</div>
-->



================================================
FILE: packages/stdf/src/routes/swiper/en_US/Item_en.svelte
================================================
<script lang="ts">
	import { Button, Avatar } from '$lib/index.js';
</script>

<div class="flex flex-col items-center space-y-4">
	<div class="text-center">This container uses a single component as its content</div>
	<div><Avatar /></div>
	<div class="w-full"><Button>button</Button></div>
</div>



================================================
FILE: packages/stdf/src/routes/swiper/zh_CN/+page.svelte
================================================
<!-- Swiper Demo -->
<script lang="ts">
	import { Swiper } from '$lib/index.js';
	import type { SwiperImgProps } from '$lib/types/index.js';
	import Item from './Item.svelte';

	const data: SwiperImgProps[] = [
		{ type: 'img', url: '/assets/images/wall_1.jpg' },
		{ type: 'img', url: '/assets/images/wall_2.jpg' },
		{ type: 'img', url: '/assets/images/wall_3.jpg' },
		{ type: 'img', url: '/assets/images/wall_4.jpg' }
	];

	let indexClick = $state(-1);
	let indexChange = $state(0);
</script>

<div class="mx-4 mb-2 mt-10 text-lg font-bold">基础用法</div>
<Swiper {data} />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">初始索引为 2</div>
<Swiper {data} initActive={2} />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">间隔 8 秒</div>
<Swiper {data} interval={8} />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">过渡 1500 毫秒</div>
<Swiper {data} duration={1500} />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">关闭自动播放</div>
<Swiper {data} autoplay={false} />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">外部指示器</div>
<Swiper {data} indicatePosition="out" />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">关闭指示器</div>
<Swiper {data} indicatePosition={null} />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">指示器右对齐</div>
<Swiper {data} indicateAlign="right" />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">圆点指示器</div>
<Swiper {data} indicateStyle="point" />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">线性指示器</div>
<Swiper {data} indicateStyle="line" />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">长线指示器</div>
<Swiper {data} indicateStyle="longLine" interval={8} />
<div class="mt-10"></div>
<Swiper {data} indicateStyle="longLine" interval={8} indicatePosition="out" />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">方形指示器</div>
<Swiper {data} indicateRadius={false} />
<div class="mt-10"></div>
<Swiper {data} indicateStyle="point" indicateRadius={false} />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">
	指定指示器背景色
	<p class="mb-2 text-xs font-thin">注入 Class</p>
</div>
<Swiper {data} indicateInjClass="from-black/0 to-extend0/50" />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">
	指定指示器颜色
	<p class="mb-2 text-xs font-thin">同时去除背景色</p>
</div>
<Swiper {data} indicateInjClass="bg-none" indicateColor="bg-extend2" indicateActiveColor="bg-extend1" />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">指定容器宽高比</div>
<Swiper {data} aspectRatio={[4, 1]} />

<div class="mx-4 mt-10 text-lg font-bold">
	配置容器内边距
	<p class="mb-2 text-xs font-thin">同时指定指示器颜色、去除指示器背景色、配置容器内部圆角</p>
</div>
<Swiper
	{data}
	px="6"
	py="6"
	indicateInjClass="bg-none"
	indicateColor="bg-black/5 dark:bg-white/10"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	interval={8}
	indicateStyle="longLine"
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="6"
	py="6"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="full"
	aspectRatio={[3, 1]}
/>

<div class="mx-4 mb-2 mt-10 text-lg font-bold">
	容器内部增加投影
	<p class="mb-2 text-xs font-normal">注入 Class</p>
</div>
<Swiper
	{data}
	px="6"
	py="6"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="full"
	aspectRatio={[3, 1]}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
/>

<div class="mx-4 mb-2 mt-10 text-lg font-bold">未激活容器 X、Z 轴偏移</div>
<Swiper
	{data}
	px="16"
	py="6"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	aspectRatio={[3, 1]}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	translateX={100}
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="4"
	py="8"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	translateZ={400}
	translateX={-200}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="12"
	py="8"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	translateZ={600}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
/>

<div class="mx-4 mb-2 mt-10 text-lg font-bold">未激活容器 X、Y、Z 轴旋转</div>
<Swiper
	{data}
	px="4"
	py="8"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	rotateX={90}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	duration={2000}
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="4"
	py="8"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	rotateY={90}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	duration={2000}
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="4"
	py="8"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	rotateZ={90}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	duration={2000}
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="4"
	py="8"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	rotateX={90}
	rotateY={90}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	duration={2000}
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="4"
	py="8"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	rotateX={90}
	rotateZ={90}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	duration={2000}
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="4"
	py="8"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	radius="xl"
	rotateY={90}
	rotateZ={90}
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	duration={2000}
/>

<div class="mx-4 mb-2 mt-10 text-lg font-bold">未激活容器注入 Class</div>
<Swiper
	{data}
	px="24"
	py="6"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	radius="xl"
	aspectRatio={[3, 1]}
	translateX={160}
	duration={2000}
	notActiveInjClass="grayscale"
/>
<div class="mt-10"></div>
<Swiper
	{data}
	px="24"
	py="6"
	indicateInjClass="bg-none"
	indicateColor="bg-primary dark:bg-dark"
	indicateActiveColor="bg-primary dark:bg-dark"
	innerInjClass="shadow-md shadow-black/20 dark:shadow-white/20"
	radius="xl"
	aspectRatio={[3, 1]}
	translateX={160}
	duration={2000}
	notActiveInjClass="blur"
/>

<div class="mx-4 mb-2 mt-10 text-lg font-bold">指定容器宽度</div>
<div class="flex justify-center">
	<Swiper {data} containerWidth={(document.body.clientWidth / 4) * 3} />
</div>

<div class="mx-4 mb-2 mt-10 text-lg font-bold">容器内容使用组件</div>
<Swiper
	data={[
		{ type: 'component', component: Item },
		{ type: 'img', url: '/assets/images/wall_1.jpg' }
	]}
/>

<div class="mx-4 mb-2 mt-10 text-lg font-bold">
	监听 onchange 事件
	<p class=" mb-2 text-xs font-normal">当前激活索引值：{indexChange}</p>
</div>
<Swiper {data} onchange={(current) => (indexChange = current)} />

<div class="mx-4 mb-2 mt-10 text-lg font-bold">
	监听 onclick 事件
	<p class="mb-2 text-xs font-normal">点击索引值：{indexClick === -1 ? '未点击' : indexClick}</p>
</div>
<Swiper {data} onclick={(current) => (indexClick = current)} />

<!-- Item.svelte -->
<!--
<script lang=""ts>
	import { Button, Avatar } from 'stdf';
</script>

<div class="flex flex-col space-y-4 items-center">
	<div class="text-center">此容器使用单个组件作为内容</div>
	<div><Avatar /></div>
	<div class="w-full"><Button>按钮</Button></div>
</div>
-->



================================================
FILE: packages/stdf/src/routes/swiper/zh_CN/Item.svelte
================================================
<script lang="ts">
	import { Button, Avatar } from '$lib/index.js';
</script>

<div class="flex flex-col items-center space-y-4">
	<div class="text-center">此容器使用单个组件作为内容</div>
	<div><Avatar /></div>
	<div class="w-full"><Button>按钮</Button></div>
</div>



================================================
FILE: packages/stdf/src/routes/switch/en_US/+page.svelte
================================================
<!-- Switch Demo -->
<script lang="ts">
	import { Switch, Icon, Cell, Dialog } from '$lib/index.js';

	let checkAsync = $state(false);
	const switchClickFun = () => {
		setTimeout(() => {
			checkAsync = !checkAsync;
		}, 2000);
	};
	let cellCheck = $state(false);
	const cellAsyncFun = () => {
		setTimeout(() => {
			cellCheck = !cellCheck;
		}, 2000);
	};
	let loading = $state(false);
	let loadingCheck = $state(false);
	const loadingFun = () => {
		loading = true;
		setTimeout(() => {
			loadingCheck = !loadingCheck;
			loading = false;
		}, 3000);
	};
	let cellLoading = $state(false);
	let cellLoadingCheck = $state(false);
	const cellLoadingFun = () => {
		cellLoading = true;
		setTimeout(() => {
			cellLoadingCheck = !cellLoadingCheck;
			cellLoading = false;
		}, 3000);
	};
	let visible = $state(false);
	let confirmswitchActive = $state(false);
</script>

<div class="pb-8">
	<div class="flex flex-col space-y-8 px-4 py-8">
		<div>
			<div class="mb-4 font-bold">Different Radius</div>
			<div class="flex justify-between">
				<Switch />
				<Switch radius="none" />
				<Switch radius="full" />
			</div>
		</div>
		<div>
			<div class="mb-4 font-bold">Different Colors</div>
			<div class="flex justify-between">
				<Switch active injClass="bg-success dark:bg-success" />
				<Switch active injClass="bg-error dark:bg-error" />
				<Switch active injClass="bg-warning dark:bg-warning" />
				<Switch active injClass="bg-[#DC88F5] dark:bg-[#FFCA28]" />
			</div>
		</div>
		<div>
			<div class="mb-4 font-bold">With Text / State / Icon</div>
			<div class="flex justify-between">
				<Switch inside={['OF', 'ON']} />
				<Switch inside={['😭', '😄']} />
				<Switch inside="state" />
				<Switch>
					{#snippet falseChild()}
						<div>
							<Icon name="ri-moon-line" size={16} top={-1} />
						</div>
					{/snippet}
					{#snippet trueChild()}
						<div>
							<Icon name="ri-sun-line" size={16} top={-1} />
						</div>
					{/snippet}
				</Switch>
			</div>
		</div>
		<div>
			<div class="mb-4 font-bold">Disabled</div>
			<div class="flex justify-between">
				<Switch disabled />
				<Switch disabled active />
			</div>
		</div>
		<div>
			<div class="mb-4 font-bold">Async Control</div>
			<div class="flex justify-between">
				<div class="flex flex-col items-center space-y-2">
					<Switch async active={checkAsync} onclick={switchClickFun} />
					<div class="text-sm">Wait 2 seconds</div>
				</div>
				<div class="flex flex-col items-center space-y-2">
					<Switch async active={loadingCheck} loading={{ theme: true }} onclick={loadingFun} inside={loading ? 'loading' : null} />
					<div class="text-sm">Wait 3 seconds</div>
				</div>
			</div>
		</div>
	</div>

	<div class="mb-4 px-4 font-bold">Used in Cell</div>
	<Cell title="Switch" detail="Click anywhere in the row to trigger the switch" right={{ type: 'switch' }} />
	<Cell title="Switch with Text" right={{ type: 'switch', switch: { inside: ['😭', '😄'] } }} switchActive />
	<Cell title="Full Radius Switch" right={{ type: 'switch', switch: { radius: 'full' } }} />
	<Cell
		title="Async Control"
		detail="Switch triggered 2 seconds after click"
		right={{ type: 'switch', switch: { async: true } }}
		switchActive={cellCheck}
		onclick={cellAsyncFun}
	/>
	<Cell
		title="Async Loading"
		detail="Switch triggered 3 seconds after click"
		right={{ type: 'switch', switch: { async: true, inside: cellLoading ? 'loading' : null } }}
		switchActive={cellLoadingCheck}
		onclick={cellLoadingFun}
	/>
	<Cell title="Disabled Switch" right={{ type: 'switch', switch: { disabled: true } }} switchActive />

	<Cell
		title="Double Confirmation"
		right={{ type: 'switch', switch: { async: true } }}
		bind:switchActive={confirmswitchActive}
		onclick={() => (visible = true)}
	/>
	<Dialog
		bind:visible
		content={`Are you sure you want to ${confirmswitchActive ? 'turn off' : 'turn on'}?`}
		onprimary={() => {
			visible = false;
			confirmswitchActive = !confirmswitchActive;
		}}
	/>
</div>



================================================
FILE: packages/stdf/src/routes/switch/zh_CN/+page.svelte
================================================
<!-- Switch Demo -->
<script lang="ts">
	import { Switch, Icon, Cell, Dialog } from '$lib/index.js';

	let checkAsync = $state(false);
	const switchClickFun = () => {
		setTimeout(() => {
			checkAsync = !checkAsync;
		}, 2000);
	};
	let cellCheck = $state(false);
	const cellAsyncFun = () => {
		setTimeout(() => {
			cellCheck = !cellCheck;
		}, 2000);
	};
	let loading = $state(false);
	let loadingCheck = $state(false);
	const loadingFun = () => {
		loading = true;
		setTimeout(() => {
			loadingCheck = !loadingCheck;
			loading = false;
		}, 3000);
	};
	let cellLoading = $state(false);
	let cellLoadingCheck = $state(false);
	const cellLoadingFun = () => {
		cellLoading = true;
		setTimeout(() => {
			cellLoadingCheck = !cellLoadingCheck;
			cellLoading = false;
		}, 3000);
	};
	let visible = $state(false);
	let confirmswitchActive = $state(false);
</script>

<div class="pb-8">
	<div class="flex flex-col space-y-8 px-4 py-8">
		<div>
			<div class="mb-4 font-bold">不同圆角</div>
			<div class="flex justify-between">
				<Switch />
				<Switch radius="none" />
				<Switch radius="full" />
			</div>
		</div>
		<div>
			<div class="mb-4 font-bold">不同颜色</div>
			<div class="flex justify-between">
				<Switch active injClass="bg-success dark:bg-success" />
				<Switch active injClass="bg-error dark:bg-error" />
				<Switch active injClass="bg-warning dark:bg-warning" />
				<Switch active injClass="bg-[#DC88F5] dark:bg-[#FFCA28]" />
			</div>
		</div>
		<div>
			<div class="mb-4 font-bold">带文字 / 状态 / 图标</div>
			<div class="flex justify-between">
				<Switch inside={['关', '开']} />
				<Switch inside={['😭', '😄']} />
				<Switch inside="state" />
				<Switch>
					{#snippet falseChild()}
						<div>
							<Icon name="ri-moon-line" size={16} top={-1} />
						</div>
					{/snippet}
					{#snippet trueChild()}
						<div>
							<Icon name="ri-sun-line" size={16} top={-1} />
						</div>
					{/snippet}
				</Switch>
			</div>
		</div>
		<div>
			<div class="mb-4 font-bold">禁用</div>
			<div class="flex justify-between">
				<Switch disabled />
				<Switch disabled active />
			</div>
		</div>
		<div>
			<div class="mb-4 font-bold">异步控制</div>
			<div class="flex justify-between">
				<div class="flex flex-col items-center space-y-2">
					<Switch async active={checkAsync} onclick={switchClickFun} />
					<div class="text-sm">点击 2 秒后触发</div>
				</div>
				<div class="flex flex-col items-center space-y-2">
					<Switch async active={loadingCheck} loading={{ theme: true }} onclick={loadingFun} inside={loading ? 'loading' : null} />
					<div class="text-sm">点击 3 秒后触发</div>
				</div>
			</div>
		</div>
	</div>

	<div class="mb-4 px-4 font-bold">Cell 中使用</div>
	<Cell title="开关" detail="点击整行皆可触发开关" right={{ type: 'switch' }} />
	<Cell title="开关带文字" right={{ type: 'switch', switch: { inside: ['😭', '😄'] } }} switchActive />
	<Cell title="开关全圆角" right={{ type: 'switch', switch: { radius: 'full' } }} />
	<Cell
		title="异步控制"
		detail="点击 2 秒后触发开关"
		right={{ type: 'switch', switch: { async: true } }}
		switchActive={cellCheck}
		onclick={cellAsyncFun}
	/>
	<Cell
		title="异步加载"
		detail="点击 3 秒后触发开关"
		right={{ type: 'switch', switch: { async: true, inside: cellLoading ? 'loading' : null } }}
		switchActive={cellLoadingCheck}
		onclick={cellLoadingFun}
	/>
	<Cell title="禁用开关" right={{ type: 'switch', switch: { disabled: true } }} switchActive />

	<Cell
		title="二次确认"
		right={{ type: 'switch', switch: { async: true } }}
		bind:switchActive={confirmswitchActive}
		onclick={() => (visible = true)}
	/>
	<Dialog
		bind:visible
		content={`确定${confirmswitchActive ? '关闭' : '开启'}吗？`}
		onprimary={() => {
			visible = false;
			confirmswitchActive = !confirmswitchActive;
		}}
	/>
</div>



================================================
FILE: packages/stdf/src/routes/tabBar/en_US/+page.svelte
================================================
<!-- TabBar Demo -->
<script lang="ts">
	import { TabBar } from '$lib/index.js';
	import type { TabBarLabelProps } from '$lib/types/index.js';

	const labels: TabBarLabelProps[] = [
		{ text: 'Home', icon: { name: 'ri-home-3-line', size: 20 }, activeIcon: { name: 'ri-home-3-fill', size: 20 } },
		{ text: 'Discover', icon: { name: 'ri-compass-3-line', size: 20 }, activeIcon: { name: 'ri-compass-3-fill', size: 20 } },
		{ text: 'Message', icon: { name: 'ri-discuss-line', size: 20 }, activeIcon: { name: 'ri-discuss-fill', size: 20 } },
		{ text: 'Mine', icon: { name: 'ri-account-circle-line', size: 20 }, activeIcon: { name: 'ri-account-circle-fill', size: 20 } }
	];
	const labels1: TabBarLabelProps[] = [{ text: 'Home' }, { text: 'Discover' }, { text: 'Message' }, { text: 'Mine' }];
	const labels2: TabBarLabelProps[] = [
		{ icon: { name: 'ri-home-3-line', size: 26 }, activeIcon: { name: 'ri-home-3-fill', size: 26 } },
		{ icon: { name: 'ri-compass-3-line', size: 26 }, activeIcon: { name: 'ri-compass-3-fill', size: 26 } },
		{ icon: { name: 'ri-discuss-line', size: 26 }, activeIcon: { name: 'ri-discuss-fill', size: 26 } },
		{ icon: { name: 'ri-account-circle-line', size: 26 }, activeIcon: { name: 'ri-account-circle-fill', size: 26 } }
	];
	const labels3: TabBarLabelProps[] = [
		{ text: 'Home', icon: { name: 'ri-home-3-line', size: 20 } },
		{ text: 'Discover', icon: { name: 'ri-compass-3-line', size: 20 } },
		{ text: 'Message', icon: { name: 'ri-discuss-line', size: 20 } },
		{ text: 'Mine', icon: { name: 'ri-account-circle-line', size: 20 } }
	];
	const labels4: TabBarLabelProps[] = [
		{ text: 'Home', icon: { name: 'ri-home-3-line', size: 20 }, activeIcon: { name: 'ri-home-3-fill', size: 20 } },
		{ text: 'Message', icon: { name: 'ri-discuss-line', size: 20 }, activeIcon: { name: 'ri-discuss-fill', size: 20 } },
		{ text: 'Mine', icon: { name: 'ri-account-circle-line', size: 20 }, activeIcon: { name: 'ri-account-circle-fill', size: 20 } }
	];
	let active = $state(0);
</script>

<div class="mb-20 py-8">
	<div class="my-4 space-y-8">
		<div>
			<div class="mb-2 px-4 font-bold">Basic usage</div>
			<TabBar {labels} />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">Text only</div>
			<TabBar labels={labels1} />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">Icon only</div>
			<TabBar labels={labels2} />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">Belt line</div>
			<TabBar {labels} line lineW={8} />
			<div class="mt-2"></div>
			<TabBar {labels} line />
			<div class="mt-2"></div>
			<TabBar {labels} line lineW={2} />
			<div class="mt-2"></div>
			<TabBar {labels} line lineW={1} />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">ICONS change colors only</div>
			<TabBar labels={labels3} />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">Customize the outermost layer</div>
			<TabBar {labels} injClass="mx-2 rounded-full shadow-md dark:shadow-white/10" />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">customize Tab</div>
			<TabBar {labels} tabInjClass="text-[purple] dark:text-[yellow]" activeTabInjClass="!text-primary dark:!text-dark" />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">Only customize selected Tab</div>
			<TabBar {labels} activeTabInjClass="text-[purple] dark:text-[yellow]" />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">Custom line</div>
			<TabBar {labels} line activeInjClass="bg-[purple] dark:bg-[yellow]" />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">Care edition</div>
			<TabBar {labels} love />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">monitor onchange event</div>
			<div class="m-4">At present TabBar activated active: {active}</div>
			<TabBar {labels} onchange={(a) => (active = a)} />
		</div>
	</div>
</div>
<div class="fixed bottom-0 w-full">
	<TabBar labels={labels4} injClass="bg-white/50 dark:bg-black/50 backdrop-blur-sm" />
</div>



================================================
FILE: packages/stdf/src/routes/tabBar/zh_CN/+page.svelte
================================================
<!-- TabBar Demo -->
<script lang="ts">
	import { TabBar } from '$lib/index.js';
	import type { TabBarLabelProps } from '$lib/types/index.js';

	const labels: TabBarLabelProps[] = [
		{ text: '首页', icon: { name: 'ri-home-3-line', size: 20 }, activeIcon: { name: 'ri-home-3-fill', size: 20 } },
		{ text: '发现', icon: { name: 'ri-compass-3-line', size: 20 }, activeIcon: { name: 'ri-compass-3-fill', size: 20 } },
		{ text: '消息', icon: { name: 'ri-discuss-line', size: 20 }, activeIcon: { name: 'ri-discuss-fill', size: 20 } },
		{ text: '我的', icon: { name: 'ri-account-circle-line', size: 20 }, activeIcon: { name: 'ri-account-circle-fill', size: 20 } }
	];
	const labels1: TabBarLabelProps[] = [{ text: '首页' }, { text: '发现' }, { text: '消息' }, { text: '我的' }];
	const labels2: TabBarLabelProps[] = [
		{ icon: { name: 'ri-home-3-line', size: 26 }, activeIcon: { name: 'ri-home-3-fill', size: 26 } },
		{ icon: { name: 'ri-compass-3-line', size: 26 }, activeIcon: { name: 'ri-compass-3-fill', size: 26 } },
		{ icon: { name: 'ri-discuss-line', size: 26 }, activeIcon: { name: 'ri-discuss-fill', size: 26 } },
		{ icon: { name: 'ri-account-circle-line', size: 26 }, activeIcon: { name: 'ri-account-circle-fill', size: 26 } }
	];
	const labels3: TabBarLabelProps[] = [
		{ text: '首页', icon: { name: 'ri-home-3-line', size: 20 } },
		{ text: '发现', icon: { name: 'ri-compass-3-line', size: 20 } },
		{ text: '消息', icon: { name: 'ri-discuss-line', size: 20 } },
		{ text: '我的', icon: { name: 'ri-account-circle-line', size: 20 } }
	];
	const labels4: TabBarLabelProps[] = [
		{ text: '首页', icon: { name: 'ri-home-3-line', size: 20 }, activeIcon: { name: 'ri-home-3-fill', size: 20 } },
		{ text: '消息', icon: { name: 'ri-discuss-line', size: 20 }, activeIcon: { name: 'ri-discuss-fill', size: 20 } },
		{ text: '我的', icon: { name: 'ri-account-circle-line', size: 20 }, activeIcon: { name: 'ri-account-circle-fill', size: 20 } }
	];
	let active = $state(0);
</script>

<div class="mb-20 py-8">
	<div class="my-4 space-y-8">
		<div>
			<div class="mb-2 px-4 font-bold">基础用法</div>
			<TabBar {labels} />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">仅文字</div>
			<TabBar labels={labels1} />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">仅图标</div>
			<TabBar labels={labels2} />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">带线条</div>
			<TabBar {labels} line lineW={8} />
			<div class="mt-2"></div>
			<TabBar {labels} line />
			<div class="mt-2"></div>
			<TabBar {labels} line lineW={2} />
			<div class="mt-2"></div>
			<TabBar {labels} line lineW={1} />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">图标仅换颜色</div>
			<TabBar labels={labels3} />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">自定义最外层</div>
			<TabBar {labels} injClass="mx-2 rounded-full shadow-md dark:shadow-white/10" />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">自定义 Tab</div>
			<TabBar {labels} tabInjClass="text-[purple] dark:text-[yellow]" activeTabInjClass="!text-primary dark:!text-dark" />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">仅自定义选定 Tab</div>
			<TabBar {labels} activeTabInjClass="text-[purple] dark:text-[yellow]" />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">自定义线条</div>
			<TabBar {labels} line activeInjClass="bg-[purple] dark:bg-[yellow]" />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">关爱版</div>
			<TabBar {labels} love />
		</div>
		<div>
			<div class="mb-2 px-4 font-bold">监听 onchange 事件</div>
			<div class="m-4">当前 TabBar 激活的 active：{active}</div>
			<TabBar {labels} onchange={(a) => (active = a)} />
		</div>
	</div>
</div>
<div class="fixed bottom-0 w-full">
	<TabBar labels={labels4} injClass="bg-white/50 dark:bg-black/50 backdrop-blur-sm" />
</div>



================================================
FILE: packages/stdf/src/routes/tabs/en_US/+page.svelte
================================================
<!-- Tabs Demo -->
<script lang="ts">
	import { Tabs, Tab, TabContent, Divider } from '$lib/index.js';
	import type { TabLabelProps } from '$lib/types/index.js';
	import { fly } from 'svelte/transition';

	const labels: TabLabelProps[] = [{ text: 'aircraft' }, { text: 'steamer' }, { text: 'train' }, { text: 'car' }];
	const labels1: TabLabelProps[] = [
		{ icon: { name: 'ri-plane-line', theme: true, size: 20 } },
		{ icon: { name: 'ri-ship-2-line', theme: true, size: 20 } },
		{ icon: { name: 'ri-train-line', theme: true, size: 20 } },
		{ icon: { name: 'ri-car-line', theme: true, size: 20 } }
	];
	const labels2: TabLabelProps[] = [
		{ text: 'aircraft', icon: { name: 'ri-plane-line', theme: true, size: 16, top: -1 } },
		{ text: 'steamer', icon: { name: 'ri-ship-2-line', theme: true, size: 16, top: -1 } },
		{ text: 'train', icon: { name: 'ri-train-line', theme: true, size: 16, top: -1 } },
		{ text: 'car', icon: { name: 'ri-car-line', theme: true, size: 16, top: -1 } }
	];
	const overflowLabels: TabLabelProps[] = [
		{ text: 'aircraft' },
		{ text: 'steamer' },
		{ text: 'train' },
		{ text: 'car' },
		{ text: 'motorcycle' },
		{ text: 'bicycle' },
		{ text: 'hot air balloon' },
		{ text: 'rocket' },
		{ text: 'tractor' },
		{ text: 'subway' },
		{ text: 'bus' },
		{ text: 'skateboard' },
		{ text: 'flying saucer' }
	];
	let width = $state(0);
	let changeActive = $state(0);
	let active = $state(2);
	const clicktabFun = (a: number) => {
		active = a;
	};
	const tabsChangeFun = (a: number) => {
		changeActive = a;
	};
</script>

<div class="py-8">
	<div class="px-4 text-xl font-bold">use Tabs</div>
	<div class="my-4 space-y-4">
		<div class="px-4 font-bold">Basic usage</div>
		<Tabs tab={{ labels }}>
			<TabContent>I am a plane</TabContent>
			<TabContent>I am a ship</TabContent>
			<TabContent>I am a train</TabContent>
			<TabContent>I am a car</TabContent>
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">Accelerate the transition</div>
		<Tabs duration="fast" tab={{ labels }}>
			<TabContent>I am a plane</TabContent>
			<TabContent>I am a ship</TabContent>
			<TabContent>I am a train</TabContent>
			<TabContent>I am a car</TabContent>
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">Transition mitigation</div>
		<Tabs duration="slower" tab={{ labels }}>
			<TabContent>I am a plane</TabContent>
			<TabContent>I am a ship</TabContent>
			<TabContent>I am a train</TabContent>
			<TabContent>I am a car</TabContent>
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">Use linear style</div>
		<Tabs tab={{ labels, lineType: true }}>
			<TabContent>I am a plane</TabContent>
			<TabContent>I am a ship</TabContent>
			<TabContent>I am a train</TabContent>
			<TabContent>I am a car</TabContent>
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">The TAB is located at the bottom</div>
		<Tabs tab={{ labels }} position="b">
			<TabContent>I am a plane</TabContent>
			<TabContent>I am a ship</TabContent>
			<TabContent>I am a train</TabContent>
			<TabContent>I am a car</TabContent>
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">The TAB is located on the left</div>
		<Tabs tab={{ labels }} position="l">
			{#snippet children({ active })}
				<TabContent show={active === 0}>I am a plane</TabContent>
				<TabContent show={active === 1}>I am a ship</TabContent>
				<TabContent show={active === 2}>I am a train</TabContent>
				<TabContent show={active === 3}>I am a car</TabContent>
			{/snippet}
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">The TAB is located on the right</div>
		<Tabs tab={{ labels }} position="r">
			{#snippet children({ active })}
				<TabContent show={active === 0}>I am a plane</TabContent>
				<TabContent show={active === 1}>I am a ship</TabContent>
				<TabContent show={active === 2}>I am a train</TabContent>
				<TabContent show={active === 3}>I am a car</TabContent>
			{/snippet}
		</Tabs>
		<Divider />

		<div class="px-4 font-bold" bind:clientWidth={width}>Custom transition</div>
		<Tabs tab={{ labels }} transition={false}>
			{#snippet children({ active })}
				<div class="relative py-8">
					{#each labels as item, i}
						{#if active === i}
							<div class="absolute" in:fly={{ y: -80, x: (width / 4) * i, duration: 1000 }}>I am {item.text}</div>
						{/if}
					{/each}
				</div>
			{/snippet}
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">monitor change event</div>
		<Tabs tab={{ labels }} onchange={tabsChangeFun}>
			<TabContent>I am a plane</TabContent>
			<TabContent>I am a ship</TabContent>
			<TabContent>I am a train</TabContent>
			<TabContent>I am a car</TabContent>
		</Tabs>
		<div class="mt-4">At present Tabs activated active: {changeActive}</div>
		<Divider />

		<div class="px-4 font-bold">Overflow mode</div>
		<Tabs tab={{ labels: overflowLabels, overflow: true }}>
			{#each overflowLabels as item}
				<TabContent>I am {item.text}</TabContent>
			{/each}
		</Tabs>
		<Tabs tab={{ labels: overflowLabels, overflow: true, lineType: true }}>
			{#each overflowLabels as item}
				<TabContent>I am {item.text}</TabContent>
			{/each}
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">Overflow mode closes automatic scrolling</div>
		<Tabs tab={{ labels: overflowLabels, overflow: true, autoScroll: false }}>
			{#each overflowLabels as item}
				<TabContent>I am {item.text}</TabContent>
			{/each}
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">Overflow mode shows 2 items</div>
		<Tabs tab={{ labels: overflowLabels, overflow: true, showNum: 2 }}>
			{#each overflowLabels as item}
				<TabContent>I am {item.text}</TabContent>
			{/each}
		</Tabs>
	</div>
	<Divider />

	<div class="mt-8 px-4 text-xl font-bold">different Tab style</div>
	<div class="mt-4 flex flex-col space-y-2">
		<div class="px-4 font-bold">Different fillet</div>
		<Tab {labels} radius="none" />
		<Tab {labels} />
		<Tab {labels} radius="xl" />
		<Tab {labels} radius="full" />

		<div class="px-4 font-bold">Match text with ICONS</div>
		<Tab {labels} />
		<Tab labels={labels1} />
		<Tab labels={labels2} />

		<div class="px-4 font-bold">Care edition</div>
		<Tab {labels} love />

		<div class="px-4 font-bold">Linear style</div>
		<Tab {labels} lineType />
		<Tab labels={labels2} lineType />

		<div class="px-4 font-bold">customize Tab Outer style</div>
		<Tab {labels} injClass="bg-gradient-to-b from-[#e3c6ff] to-[#b6aeff]" />

		<div class="px-4 font-bold">customize Tab style</div>
		<Tab {labels} tabInjClass="underline text-primary decoration-primary dark:text-dark dark:decoration-dark" />

		<div class="px-4 font-bold">Custom selection Tab style</div>
		<Tab {labels} activeTabInjClass="text-primary dark:text-dark !text-base transition-all" />

		<div class="px-4 font-bold">Customize the indicator style</div>
		<Tab {labels} activeInjClass="bg-gradient-to-b from-[#CE9FFC] to-[#7367F0]" activeTabInjClass="text-white" />
		<Tab {labels} lineType activeInjClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0]" />

		<div class="px-4 font-bold">Different mx</div>
		<div class="mt-4 flex flex-col space-y-2">
			<Tab {labels} mx="12" />
			<Tab {labels} lineType mx="12" />
			<Tab {labels} mx="0" />
			<Tab {labels} lineType mx="0" />
		</div>
	</div>
	<Divider />

	<div class="my-8 px-4 text-xl font-bold">Use alone Tab</div>
	<div class="my-4">
		<Tab {labels} {active} onclickTab={clicktabFun} />
		<div class="mt-4">At present Tab clickable active:{active}</div>
	</div>
	<Divider />
</div>



================================================
FILE: packages/stdf/src/routes/tabs/zh_CN/+page.svelte
================================================
<!-- Tabs Demo -->
<script lang="ts">
	import { Tabs, Tab, TabContent, Divider } from '$lib/index.js';
	import type { TabLabelProps } from '$lib/types/index.js';
	import { fly } from 'svelte/transition';

	const labels: TabLabelProps[] = [{ text: '飞机' }, { text: '轮船' }, { text: '火车' }, { text: '汽车' }];
	const labels1: TabLabelProps[] = [
		{ icon: { name: 'ri-plane-line', theme: true, size: 20 } },
		{ icon: { name: 'ri-ship-2-line', theme: true, size: 20 } },
		{ icon: { name: 'ri-train-line', theme: true, size: 20 } },
		{ icon: { name: 'ri-car-line', theme: true, size: 20 } }
	];
	const labels2: TabLabelProps[] = [
		{ text: '飞机', icon: { name: 'ri-plane-line', theme: true, size: 16, top: -1 } },
		{ text: '轮船', icon: { name: 'ri-ship-2-line', theme: true, size: 16, top: -1 } },
		{ text: '火车', icon: { name: 'ri-train-line', theme: true, size: 16, top: -1 } },
		{ text: '汽车', icon: { name: 'ri-car-line', theme: true, size: 16, top: -1 } }
	];
	const overflowLabels: TabLabelProps[] = [
		{ text: '飞机' },
		{ text: '轮船' },
		{ text: '火车' },
		{ text: '汽车' },
		{ text: '摩托车' },
		{ text: '自行车' },
		{ text: '热气球' },
		{ text: '火箭' },
		{ text: '拖拉机' },
		{ text: '地铁' },
		{ text: '公交车' },
		{ text: '滑板' },
		{ text: '飞碟' }
	];
	let width = $state(0);
	let changeActive = $state(0);
	let active = $state(2);
	const clicktabFun = (a: number) => {
		active = a;
	};
	const tabsChangeFun = (a: number) => {
		changeActive = a;
	};
</script>

<div class="py-8">
	<div class="px-4 text-xl font-bold">使用 Tabs</div>
	<div class="my-4 space-y-4">
		<div class="px-4 font-bold">基础用法</div>
		<Tabs tab={{ labels }}>
			<TabContent>我是飞机</TabContent>
			<TabContent>我是轮船</TabContent>
			<TabContent>我是火车</TabContent>
			<TabContent>我是汽车</TabContent>
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">加快过渡</div>
		<Tabs duration="fast" tab={{ labels }}>
			<TabContent>我是飞机</TabContent>
			<TabContent>我是轮船</TabContent>
			<TabContent>我是火车</TabContent>
			<TabContent>我是汽车</TabContent>
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">减缓过渡</div>
		<Tabs duration="slower" tab={{ labels }}>
			<TabContent>我是飞机</TabContent>
			<TabContent>我是轮船</TabContent>
			<TabContent>我是火车</TabContent>
			<TabContent>我是汽车</TabContent>
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">使用线性风格</div>
		<Tabs tab={{ labels, lineType: true }}>
			<TabContent>我是飞机</TabContent>
			<TabContent>我是轮船</TabContent>
			<TabContent>我是火车</TabContent>
			<TabContent>我是汽车</TabContent>
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">选项卡位于底部</div>
		<Tabs tab={{ labels }} position="b">
			<TabContent>我是飞机</TabContent>
			<TabContent>我是轮船</TabContent>
			<TabContent>我是火车</TabContent>
			<TabContent>我是汽车</TabContent>
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">选项卡位于左侧</div>
		<Tabs tab={{ labels }} position="l">
			{#snippet children({ active })}
				<TabContent show={active === 0}>我是飞机</TabContent>
				<TabContent show={active === 1}>我是轮船</TabContent>
				<TabContent show={active === 2}>我是火车</TabContent>
				<TabContent show={active === 3}>我是汽车</TabContent>
			{/snippet}
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">选项卡位于右侧</div>
		<Tabs tab={{ labels }} position="r">
			{#snippet children({ active })}
				<TabContent show={active === 0}>我是飞机</TabContent>
				<TabContent show={active === 1}>我是轮船</TabContent>
				<TabContent show={active === 2}>我是火车</TabContent>
				<TabContent show={active === 3}>我是汽车</TabContent>
			{/snippet}
		</Tabs>
		<Divider />

		<div class="px-4 font-bold" bind:clientWidth={width}>自定义过渡</div>
		<Tabs tab={{ labels }} transition={false}>
			{#snippet children({ active })}
				<div class="relative py-8">
					{#each labels as item, i}
						{#if active === i}
							<div class="absolute" in:fly={{ y: -80, x: (width / 4) * i, duration: 1000 }}>我是{item.text}</div>
						{/if}
					{/each}
				</div>
			{/snippet}
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">监听 change 事件</div>
		<Tabs tab={{ labels }} onchange={tabsChangeFun}>
			<TabContent>我是飞机</TabContent>
			<TabContent>我是轮船</TabContent>
			<TabContent>我是火车</TabContent>
			<TabContent>我是汽车</TabContent>
		</Tabs>
		<div class="mt-4">当前 Tabs 激活的 active：{changeActive}</div>
		<Divider />

		<div class="px-4 font-bold">溢出模式</div>
		<Tabs tab={{ labels: overflowLabels, overflow: true }}>
			{#each overflowLabels as item}
				<TabContent>我是{item.text}</TabContent>
			{/each}
		</Tabs>
		<Tabs tab={{ labels: overflowLabels, overflow: true, lineType: true }}>
			{#each overflowLabels as item}
				<TabContent>我是{item.text}</TabContent>
			{/each}
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">溢出模式关闭自动滚动</div>
		<Tabs tab={{ labels: overflowLabels, overflow: true, autoScroll: false }}>
			{#each overflowLabels as item}
				<TabContent>我是{item.text}</TabContent>
			{/each}
		</Tabs>
		<Divider />

		<div class="px-4 font-bold">溢出模式完整显示 2 项</div>
		<Tabs tab={{ labels: overflowLabels, overflow: true, showNum: 2 }}>
			{#each overflowLabels as item}
				<TabContent>我是{item.text}</TabContent>
			{/each}
		</Tabs>
	</div>
	<Divider />

	<div class="mt-8 px-4 text-xl font-bold">不同的 Tab 风格</div>
	<div class="mt-4 flex flex-col space-y-2">
		<div class="px-4 font-bold">不同圆角</div>
		<Tab {labels} radius="none" />
		<Tab {labels} />
		<Tab {labels} radius="xl" />
		<Tab {labels} radius="full" />

		<div class="px-4 font-bold">文字与图标搭配</div>
		<Tab {labels} />
		<Tab labels={labels1} />
		<Tab labels={labels2} />

		<div class="px-4 font-bold">关爱版</div>
		<Tab {labels} love />

		<div class="px-4 font-bold">线性风格</div>
		<Tab {labels} lineType />
		<Tab labels={labels2} lineType />

		<div class="px-4 font-bold">自定义 Tab 外层风格</div>
		<Tab {labels} injClass="bg-gradient-to-b from-[#e3c6ff] to-[#b6aeff]" />

		<div class="px-4 font-bold">自定义 Tab 风格</div>
		<Tab {labels} tabInjClass="underline text-primary decoration-primary dark:text-dark dark:decoration-dark" />

		<div class="px-4 font-bold">自定义选定 Tab 风格</div>
		<Tab {labels} activeTabInjClass="text-primary dark:text-dark !text-base transition-all" />

		<div class="px-4 font-bold">自定义指示器风格</div>
		<Tab {labels} activeInjClass="bg-gradient-to-b from-[#CE9FFC] to-[#7367F0]" activeTabInjClass="text-white" />
		<Tab {labels} lineType activeInjClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0]" />

		<div class="px-4 font-bold">不同的左右间距</div>
		<div class="mt-4 flex flex-col space-y-2">
			<Tab {labels} mx="12" />
			<Tab {labels} lineType mx="12" />
			<Tab {labels} mx="0" />
			<Tab {labels} lineType mx="0" />
		</div>
	</div>
	<Divider />

	<div class="my-8 px-4 text-xl font-bold">单独使用 Tab</div>
	<div class="my-4">
		<Tab {labels} {active} onclickTab={clicktabFun} />
		<div class="mt-4">当前 Tab 点击的 active：{active}</div>
	</div>
	<Divider />
</div>



================================================
FILE: packages/stdf/src/routes/timePicker/en_US/+page.svelte
================================================
<!-- TimePickerDemo Demo -->
<script lang="ts">
	import { Cell, TimePicker } from '$lib/index.js';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);
	let visible15 = $state(false);
	let visible16 = $state(false);
	let visible17 = $state(false);
	let visible18 = $state(false);
	let visible19 = $state(false);
	let visible20 = $state(false);
	let visible21 = $state(false);
	let visible22 = $state(false);

	let defaultTimeStr = $state('');
	let customFormatStr = $state('');
	let monthFirstStr = $state('');
	let timeObj = $state({});
	let timeObjStr = $derived(JSON.stringify(timeObj));
</script>

<div class="py-4">
	<div class="px-4">
		{#if defaultTimeStr !== ''}
			Currently selected:
			<span class="mr-2 text-primary dark:text-dark">{defaultTimeStr}</span>
		{:else}
			<div>Please select a time</div>
		{/if}
	</div>
	<Cell title="Basic Usage" subTitle="Default to current time, can select 10 years before and after" onclick={() => (visible1 = true)} />
	<TimePicker bind:visible={visible1} onconfirm={(time) => (defaultTimeStr = time)} />

	<Cell title="Year Month Day only" onclick={() => (visible2 = true)} />
	<TimePicker bind:visible={visible2} type="YYYYMMDD" />

	<Cell title="Hour Minute Second only" onclick={() => (visible3 = true)} />
	<TimePicker bind:visible={visible3} type="hhmmss" />

	<Cell title="Year Month Day Hour only" onclick={() => (visible4 = true)} />
	<TimePicker bind:visible={visible4} type="YYYYMMDDhh" />

	<Cell title="Hide Tips" onclick={() => (visible5 = true)} />
	<TimePicker bind:visible={visible5} showTips={false} />

	<Cell title="Different visible rows for each column" onclick={() => (visible6 = true)} />
	<TimePicker
		bind:visible={visible6}
		yearProps={{ showRow: 3 }}
		hourProps={{ showRow: 7 }}
		minuteProps={{ showRow: 7 }}
		secondProps={{ showRow: 7 }}
	/>

	<Cell title="Different widths for each column" onclick={() => (visible8 = true)} />
	<TimePicker bind:visible={visible8} yearProps={{ flex: 3 }} dayProps={{ flex: 2 }} />

	<Cell title="Year data right-aligned, day data left-aligned" onclick={() => (visible22 = true)} />
	<TimePicker bind:visible={visible22} type="YYYYMMDD" yearProps={{ align: 'right' }} dayProps={{ align: 'left' }} />

	<Cell title="Limit year range" onclick={() => (visible9 = true)} />
	<TimePicker bind:visible={visible9} yearRange={[2022, 2025]} />

	<Cell title="Limit month range" onclick={() => (visible10 = true)} />
	<TimePicker bind:visible={visible10} monthRange={[2, 5]} />

	<Cell title="Limit hour, minute, second range" onclick={() => (visible11 = true)} />
	<TimePicker bind:visible={visible11} hourRange={[2, 5]} minuteRange={[25, 45]} secondRange={[5, 10]} />

	<Cell title="Minute step of 5" onclick={() => (visible12 = true)} />
	<TimePicker bind:visible={visible12} minuteStep={5} />

	<Cell title="Second step of 10" onclick={() => (visible13 = true)} />
	<TimePicker bind:visible={visible13} secondStep={10} />

	<div class="px-4">
		{#if customFormatStr !== ''}
			Currently selected:
			<span class="mr-2 text-primary dark:text-dark">{customFormatStr}</span>
		{:else}
			<div>Please select a time</div>
		{/if}
	</div>
	<Cell
		title="Custom return time format"
		subTitle="Output format: X year X month X day X hour X minute X second"
		onclick={() => (visible15 = true)}
	/>
	<TimePicker
		bind:visible={visible15}
		outFormat="YYYY year MM month DD day hh hour mm minute ss second"
		onconfirm={(timeStr) => (customFormatStr = timeStr)}
	/>

	<div class="px-4">
		{#if monthFirstStr !== ''}
			Currently selected:
			<span class="mr-2 text-primary dark:text-dark">{monthFirstStr}</span>
		{:else}
			<div>Please select a time</div>
		{/if}
	</div>
	<Cell title="Return time with month first" onclick={() => (visible16 = true)} />
	<TimePicker bind:visible={visible16} type="YYYYMMDD" outFormat="MM/DD/YYYY" onconfirm={(timeStr) => (monthFirstStr = timeStr)} />

	<div class="px-4 text-xs">
		Currently selected:<br />
		<span class="mr-2 break-words text-primary dark:text-dark">{timeObjStr}</span>
	</div>
	<Cell title="Return time object" onclick={() => (visible17 = true)} />
	<TimePicker bind:visible={visible17} onconfirm={(_, obj) => (timeObj = obj)} />

	<Cell title="Rounded corners at the top" onclick={() => (visible14 = true)} />
	<TimePicker bind:visible={visible14} popup={{ radius: 'xl' }} />

	<Cell title="Custom title" onclick={() => (visible18 = true)} />
	<TimePicker bind:visible={visible18} title="Please select a time" />

	<Cell title="Specify initial selected year" onclick={() => (visible19 = true)} />
	<TimePicker bind:visible={visible19} initYear="2020" />

	<Cell title="Specify initial selected month" onclick={() => (visible20 = true)} />
	<TimePicker bind:visible={visible20} initMonth="05" />

	<Cell title="Specify initial selected hour, minute, second" onclick={() => (visible21 = true)} />
	<TimePicker bind:visible={visible21} initHour="05" initMinute="05" initSecond="05" />
</div>



================================================
FILE: packages/stdf/src/routes/timePicker/zh_CN/+page.svelte
================================================
<!-- TimePickerDemo Demo -->
<script lang="ts">
	import { Cell, TimePicker } from '$lib/index.js';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);
	let visible15 = $state(false);
	let visible16 = $state(false);
	let visible17 = $state(false);
	let visible18 = $state(false);
	let visible19 = $state(false);
	let visible20 = $state(false);
	let visible21 = $state(false);
	let visible22 = $state(false);

	let defaultTimeStr = $state('');
	let customFormatStr = $state('');
	let monthFirstStr = $state('');
	let timeObj = $state({});
	let timeObjStr = $derived(JSON.stringify(timeObj));
</script>

<div class="py-4">
	<div class="px-4">
		{#if defaultTimeStr !== ''}
			当前选定了：
			<span class="mr-2 text-primary dark:text-dark">{defaultTimeStr}</span>
		{:else}
			<div>请选定时间</div>
		{/if}
	</div>
	<Cell title="基础用法" subTitle="默认选定当前时间，可选前后十年" onclick={() => (visible1 = true)} />
	<TimePicker bind:visible={visible1} onconfirm={(time) => (defaultTimeStr = time)} />

	<Cell title="只用年月日" onclick={() => (visible2 = true)} />
	<TimePicker bind:visible={visible2} type="YYYYMMDD" />

	<Cell title="只用时分秒" onclick={() => (visible3 = true)} />
	<TimePicker bind:visible={visible3} type="hhmmss" />

	<Cell title="只用年月日时" onclick={() => (visible4 = true)} />
	<TimePicker bind:visible={visible4} type="YYYYMMDDhh" />

	<Cell title="不显示提示" onclick={() => (visible5 = true)} />
	<TimePicker bind:visible={visible5} showTips={false} />

	<Cell title="不同列不同可见行" onclick={() => (visible6 = true)} />
	<TimePicker
		bind:visible={visible6}
		yearProps={{ showRow: 3 }}
		hourProps={{ showRow: 7 }}
		minuteProps={{ showRow: 7 }}
		secondProps={{ showRow: 7 }}
	/>

	<Cell title="不同列不同宽度" onclick={() => (visible8 = true)} />
	<TimePicker bind:visible={visible8} yearProps={{ flex: 3 }} dayProps={{ flex: 2 }} />

	<Cell title="年数据右对齐，日数据左对齐" onclick={() => (visible22 = true)} />
	<TimePicker bind:visible={visible22} type="YYYYMMDD" yearProps={{ align: 'right' }} dayProps={{ align: 'left' }} />

	<Cell title="限定年份区间" onclick={() => (visible9 = true)} />
	<TimePicker bind:visible={visible9} yearRange={[2022, 2025]} />

	<Cell title="限定月份区间" onclick={() => (visible10 = true)} />
	<TimePicker bind:visible={visible10} monthRange={[2, 5]} />

	<Cell title="限定时分秒区间" onclick={() => (visible11 = true)} />
	<TimePicker bind:visible={visible11} hourRange={[2, 5]} minuteRange={[25, 45]} secondRange={[5, 10]} />

	<Cell title="分钟步长为 5" onclick={() => (visible12 = true)} />
	<TimePicker bind:visible={visible12} minuteStep={5} />

	<Cell title="秒步长为 10" onclick={() => (visible13 = true)} />
	<TimePicker bind:visible={visible13} secondStep={10} />

	<div class="px-4">
		{#if customFormatStr !== ''}
			当前选定了：
			<span class="mr-2 text-primary dark:text-dark">{customFormatStr}</span>
		{:else}
			<div>请选定时间</div>
		{/if}
	</div>
	<Cell title="自定义返回时间格式" subTitle="输出格式为 X 年 X 月 X 日 X 时 X 分 X 秒" onclick={() => (visible15 = true)} />
	<TimePicker
		bind:visible={visible15}
		outFormat="YYYY 年 MM 月 DD 日 hh 时 mm 分 ss 秒"
		onconfirm={(timeStr) => (customFormatStr = timeStr)}
	/>

	<div class="px-4">
		{#if monthFirstStr !== ''}
			当前选定了：
			<span class="mr-2 text-primary dark:text-dark">{monthFirstStr}</span>
		{:else}
			<div>请选定时间</div>
		{/if}
	</div>
	<Cell title="返回时间月份在前" onclick={() => (visible16 = true)} />
	<TimePicker bind:visible={visible16} type="YYYYMMDD" outFormat="MM/DD/YYYY" onconfirm={(timeStr) => (monthFirstStr = timeStr)} />

	<div class="px-4 text-xs">
		当前选定了：<br />
		<span class="mr-2 break-words text-primary dark:text-dark">{timeObjStr}</span>
	</div>
	<Cell title="返回时间对象" onclick={() => (visible17 = true)} />
	<TimePicker bind:visible={visible17} onconfirm={(_, obj) => (timeObj = obj)} />

	<Cell title="顶部来点圆角" onclick={() => (visible14 = true)} />
	<TimePicker bind:visible={visible14} popup={{ radius: 'xl' }} />

	<Cell title="自定义标题" onclick={() => (visible18 = true)} />
	<TimePicker bind:visible={visible18} title="请选择时间" />

	<Cell title="指定初始选定年份" onclick={() => (visible19 = true)} />
	<TimePicker bind:visible={visible19} initYear="2020" />

	<Cell title="指定初始选定月份" onclick={() => (visible20 = true)} />
	<TimePicker bind:visible={visible20} initMonth="05" />

	<Cell title="指定初始选定时分秒" onclick={() => (visible21 = true)} />
	<TimePicker bind:visible={visible21} initHour="05" initMinute="05" initSecond="05" />
</div>



================================================
FILE: packages/stdf/src/routes/toast/en_US/+page.svelte
================================================
<!-- Toast Demo -->
<script lang="ts">
	import { Toast, Cell, Button, Loading } from '$lib/index.js';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);
	let visible15 = $state(false);
	let visible16 = $state(false);
	let visible17 = $state(false);
	let visible18 = $state(false);
	let visible19 = $state(false);
	let visible20 = $state(false);
	let visible21 = $state(false);
	let visible22 = $state(false);
	let visible23 = $state(false);
	let visible24 = $state(false);
	let visible25 = $state(false);
	let visible26 = $state(false);
	let visible27 = $state(false);
	let visible28 = $state(false);
	let visible29 = $state(false);
	let visible30 = $state(false);
	let visible31 = $state(false);
	let visible32 = $state(false);

	let time = $state(4);
	let timer: ReturnType<typeof setInterval>;
	const useSnippetFun = () => {
		visible25 = true;
		timer = setInterval(() => {
			time--;
			if (time <= 0) {
				clearInterval(timer!);
				visible25 = false;
				time = 3;
			}
		}, 1000);
	};
</script>

<div class="py-4">
	<Cell title="Basic usage" onclick={() => (visible1 = true)} />
	<Toast bind:visible={visible1} message="Light hint" />

	<Cell title="Long text prompt" onclick={() => (visible2 = true)} />
	<Toast
		bind:visible={visible2}
		message="When the character count is too long, it is generally not recommended to display too much content here!"
	/>

	<Cell title="Do not block clicks" onclick={() => (visible3 = true)} />
	<Toast bind:visible={visible3} clickable message="The content below the mask can also be clicked" />

	<Cell title="Fixed display time" onclick={() => (visible4 = true)} />
	<Toast bind:visible={visible4} duration={6000} message="It turns off automatically after 6 seconds" />

	<Cell title="Non-automatic closing" onclick={() => (visible5 = true)} />
	<Toast
		bind:visible={visible5}
		duration={0}
		clickable
		message="This prompt will not automatically close, please click the button to close"
	/>

	<Cell title="Success message" onclick={() => (visible6 = true)} />
	<Toast bind:visible={visible6} type="success" message="Success message" />

	<Cell title="Failure prompt" onclick={() => (visible7 = true)} />
	<Toast bind:visible={visible7} type="error" message="Failure prompt" />

	<Cell title="Warning prompt" onclick={() => (visible8 = true)} />
	<Toast bind:visible={visible8} type="warning" message="Warning prompt" />

	<Cell title="Information prompt" onclick={() => (visible9 = true)} />
	<Toast bind:visible={visible9} type="info" message="Information prompt" />

	<Cell title="Load prompt" onclick={() => (visible30 = true)} />
	<Toast bind:visible={visible30} type="loading" message="Under load..." />

	<Cell title="Theme color loading prompt" onclick={() => (visible31 = true)} />
	<Toast bind:visible={visible31} type="loading" loading={{ theme: true }} message="Under load..." />

	<Cell title="Loading prompt for # 1_3" onclick={() => (visible32 = true)} />
	<Toast bind:visible={visible32} type="loading" loading={{ type: '1_3' }} message="Under load..." />

	<Cell title="Custom type" onclick={() => (visible27 = true)} />
	<Toast bind:visible={visible27} type="icon" icon={{ name: 'ri-thumb-up-fill' }} message="You are so good!" />

	<Cell title="The mask is opaque" onclick={() => (visible10 = true)} />
	<Toast bind:visible={visible10} mask={{ opacity: '0.3' }} message="Mask transparency is 0.3" />

	<Cell title="Reverse color mask" onclick={() => (visible11 = true)} />
	<Toast bind:visible={visible11} mask={{ inverse: true, opacity: '0.5' }} message="Reverse color mask" />

	<Cell title="Mask blur" onclick={() => (visible12 = true)} />
	<Toast bind:visible={visible12} mask={{ opacity: '0', backdropBlur: 'sm' }} message="The content below the mask is blurry" />

	<Cell title="Faster transition" onclick={() => (visible13 = true)} />
	<Toast bind:visible={visible13} transitionParams={{ duration: 150 }} message="The transition time is 150ms" />

	<Cell title="Slow transition" onclick={() => (visible14 = true)} />
	<Toast bind:visible={visible14} transitionParams={{ duration: 1000 }} message="The transition time is 1s" />

	<Cell title="Fade in" onclick={() => (visible15 = true)} />
	<Toast bind:visible={visible15} transitionType="fade" message="Fade in presentation" />

	<Cell title="Move down" onclick={() => (visible16 = true)} />
	<Toast bind:visible={visible16} transitionType="fly" transitionParams={{ y: -150 }} message="Move down into presentation" />

	<Cell title="Move in to the right" onclick={() => (visible17 = true)} />
	<Toast bind:visible={visible17} transitionType="fly" transitionParams={{ x: -150 }} message="Move right into presentation" />

	<Cell title="expansion" onclick={() => (visible18 = true)} />
	<Toast bind:visible={visible18} transitionType="slide" message="Unfold and present" />

	<Cell title="blur" onclick={() => (visible19 = true)} />
	<Toast bind:visible={visible19} transitionType="blur" transitionParams={{ duration: 1000 }} message="Fuzzy rendering" />

	<Cell title="No transition" onclick={() => (visible20 = true)} />
	<Toast bind:visible={visible20} transitionType={null} message="Direct presentation without transition" />

	<Cell title="Exit zoom animation" onclick={() => (visible28 = true)} />
	<Toast bind:visible={visible28} outDuration={300} message="The zoom animation time on exit is 300ms" />

	<Cell title="Exit Move out animation" onclick={() => (visible29 = true)} />
	<Toast
		bind:visible={visible29}
		outDuration={300}
		transitionType="fly"
		transitionParams={{ y: -150 }}
		message="When exiting, move out animation time is 300ms"
	/>

	<Cell title="Delayed occurrence" onclick={() => (visible21 = true)} />
	<Toast bind:visible={visible21} transitionParams={{ delay: 1000 }} message="Click for 1 second and then display" />

	<Cell title="top" onclick={() => (visible22 = true)} />
	<Toast bind:visible={visible22} position="top" message="Tips at the top" />

	<Cell title="bottom" onclick={() => (visible23 = true)} />
	<Toast bind:visible={visible23} position="bottom" message="Tips at the bottom" />

	<Cell title="Top increase distance" onclick={() => (visible24 = true)} />
	<Toast bind:visible={visible24} position="top" py="40" message="The tip is at the top and the distance is increased" />

	<Cell title="use Snippet" onclick={useSnippetFun} />
	<Toast bind:visible={visible25} duration={0}>
		<div class="flex flex-col space-y-4">
			<div>Customize the prompt content</div>
			<Loading inverse />
			<div>Close in {time} seconds</div>
		</div>
	</Toast>

	<Cell title="Different styles of rounded corners" onclick={() => (visible26 = true)} />
	<Toast bind:visible={visible26} radius="xl" message="Rounded corners were added" />
</div>

<div class="sticky bottom-0 z-10 flex bg-white/50 backdrop-blur-sm dark:bg-black/50">
	<div class="flex-1">
		<Button fill="lineTheme" onclick={() => (visible5 = false)}>Manual shutdown</Button>
	</div>
</div>



================================================
FILE: packages/stdf/src/routes/toast/zh_CN/+page.svelte
================================================
<!-- Toast Demo -->
<script lang="ts">
	import { Toast, Cell, Button, Loading } from '$lib/index.js';

	let visible1 = $state(false);
	let visible2 = $state(false);
	let visible3 = $state(false);
	let visible4 = $state(false);
	let visible5 = $state(false);
	let visible6 = $state(false);
	let visible7 = $state(false);
	let visible8 = $state(false);
	let visible9 = $state(false);
	let visible10 = $state(false);
	let visible11 = $state(false);
	let visible12 = $state(false);
	let visible13 = $state(false);
	let visible14 = $state(false);
	let visible15 = $state(false);
	let visible16 = $state(false);
	let visible17 = $state(false);
	let visible18 = $state(false);
	let visible19 = $state(false);
	let visible20 = $state(false);
	let visible21 = $state(false);
	let visible22 = $state(false);
	let visible23 = $state(false);
	let visible24 = $state(false);
	let visible25 = $state(false);
	let visible26 = $state(false);
	let visible27 = $state(false);
	let visible28 = $state(false);
	let visible29 = $state(false);
	let visible30 = $state(false);
	let visible31 = $state(false);
	let visible32 = $state(false);

	let time = $state(4);
	let timer: ReturnType<typeof setInterval>;
	const useSnippetFun = () => {
		visible25 = true;
		timer = setInterval(() => {
			time--;
			if (time <= 0) {
				clearInterval(timer!);
				visible25 = false;
				time = 3;
			}
		}, 1000);
	};
</script>

<div class="py-4">
	<Cell title="基础用法" onclick={() => (visible1 = true)} />
	<Toast bind:visible={visible1} message="轻提示" />

	<Cell title="长文本提示" onclick={() => (visible2 = true)} />
	<Toast bind:visible={visible2} message="当字符数过长时换行，一般不建议在这里显示太多的内容！" />

	<Cell title="不阻止点击" onclick={() => (visible3 = true)} />
	<Toast bind:visible={visible3} clickable message="遮罩下层内容还可以点击" />

	<Cell title="固定显示时间" onclick={() => (visible4 = true)} />
	<Toast bind:visible={visible4} duration={6000} message="6 秒后自动关闭" />

	<Cell title="不自动关闭" onclick={() => (visible5 = true)} />
	<Toast bind:visible={visible5} duration={0} clickable message="此提示不会自动关闭，请点击按钮关闭" />

	<Cell title="成功提示" onclick={() => (visible6 = true)} />
	<Toast bind:visible={visible6} type="success" message="成功提示" />

	<Cell title="失败提示" onclick={() => (visible7 = true)} />
	<Toast bind:visible={visible7} type="error" message="失败提示" />

	<Cell title="警告提示" onclick={() => (visible8 = true)} />
	<Toast bind:visible={visible8} type="warning" message="警告提示" />

	<Cell title="信息提示" onclick={() => (visible9 = true)} />
	<Toast bind:visible={visible9} type="info" message="信息提示" />

	<Cell title="加载提示" onclick={() => (visible30 = true)} />
	<Toast bind:visible={visible30} type="loading" message="加载中..." />

	<Cell title="主题色加载提示" onclick={() => (visible31 = true)} />
	<Toast bind:visible={visible31} type="loading" loading={{ theme: true }} message="加载中..." />

	<Cell title="1_3 号加载提示" onclick={() => (visible32 = true)} />
	<Toast bind:visible={visible32} type="loading" loading={{ type: '1_3' }} message="加载中..." />

	<Cell title="自定义类型" onclick={() => (visible27 = true)} />
	<Toast bind:visible={visible27} type="icon" icon={{ name: 'ri-thumb-up-fill' }} message="你真棒！" />

	<Cell title="遮罩不透明" onclick={() => (visible10 = true)} />
	<Toast bind:visible={visible10} mask={{ opacity: '0.3' }} message="遮罩透明度为 0.3" />

	<Cell title="反色遮罩" onclick={() => (visible11 = true)} />
	<Toast bind:visible={visible11} mask={{ inverse: true, opacity: '0.5' }} message="反色遮罩" />

	<Cell title="遮罩模糊" onclick={() => (visible12 = true)} />
	<Toast bind:visible={visible12} mask={{ opacity: '0', backdropBlur: 'sm' }} message="遮罩下层内容模糊" />

	<Cell title="过渡较快" onclick={() => (visible13 = true)} />
	<Toast bind:visible={visible13} transitionParams={{ duration: 150 }} message="过渡时间为 150ms" />

	<Cell title="过渡较慢" onclick={() => (visible14 = true)} />
	<Toast bind:visible={visible14} transitionParams={{ duration: 1000 }} message="过渡时间为 1s" />

	<Cell title="淡入" onclick={() => (visible15 = true)} />
	<Toast bind:visible={visible15} transitionType="fade" message="淡入呈现" />

	<Cell title="向下移入" onclick={() => (visible16 = true)} />
	<Toast bind:visible={visible16} transitionType="fly" transitionParams={{ y: -150 }} message="向下移入呈现" />

	<Cell title="向右移入" onclick={() => (visible17 = true)} />
	<Toast bind:visible={visible17} transitionType="fly" transitionParams={{ x: -150 }} message="向右移入呈现" />

	<Cell title="展开" onclick={() => (visible18 = true)} />
	<Toast bind:visible={visible18} transitionType="slide" message="展开呈现" />

	<Cell title="模糊" onclick={() => (visible19 = true)} />
	<Toast bind:visible={visible19} transitionType="blur" transitionParams={{ duration: 1000 }} message="模糊呈现" />

	<Cell title="无过渡" onclick={() => (visible20 = true)} />
	<Toast bind:visible={visible20} transitionType={null} message="无过渡直接呈现" />

	<Cell title="退出缩放动画" onclick={() => (visible28 = true)} />
	<Toast bind:visible={visible28} outDuration={300} message="退出时缩放动画时间为 300ms" />

	<Cell title="退出移出动画" onclick={() => (visible29 = true)} />
	<Toast
		bind:visible={visible29}
		outDuration={300}
		transitionType="fly"
		transitionParams={{ y: -150 }}
		message="退出时移出动画时间为 300ms"
	/>

	<Cell title="延时出现" onclick={() => (visible21 = true)} />
	<Toast bind:visible={visible21} transitionParams={{ delay: 1000 }} message="点击 1s 之后呈现" />

	<Cell title="顶部" onclick={() => (visible22 = true)} />
	<Toast bind:visible={visible22} position="top" message="提示位于顶部" />

	<Cell title="底部" onclick={() => (visible23 = true)} />
	<Toast bind:visible={visible23} position="bottom" message="提示位于底部" />

	<Cell title="顶部增加距离" onclick={() => (visible24 = true)} />
	<Toast bind:visible={visible24} position="top" py="40" message="提示位于顶部且增加了距离" />

	<Cell title="使用 Snippet" onclick={useSnippetFun} />
	<Toast bind:visible={visible25} duration={0}>
		<div class="flex flex-col space-y-4">
			<div>自定义提示内容</div>
			<Loading inverse />
			<div>{time} 秒后关闭</div>
		</div>
	</Toast>

	<Cell title="不同圆角风格" onclick={() => (visible26 = true)} />
	<Toast bind:visible={visible26} radius="xl" message="加大了圆角" />
</div>

<div class="sticky bottom-0 z-10 flex bg-white/50 backdrop-blur-sm dark:bg-black/50">
	<div class="flex-1">
		<Button fill="lineTheme" onclick={() => (visible5 = false)}>手动关闭</Button>
	</div>
</div>



================================================
FILE: packages/stdf/static/404.html
================================================
<!doctype html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>Single Page Apps for GitHub Pages</title>
		<script type="text/javascript">
			// Single Page Apps for GitHub Pages
			// MIT License
			// https://github.com/rafgraph/spa-github-pages
			// This script takes the current url and converts the path and query
			// string into just a query string, and then redirects the browser
			// to the new url with only a query string and hash fragment,
			// e.g. https://www.foo.tld/one/two?a=b&c=d#qwe, becomes
			// https://www.foo.tld/?/one/two&a=b~and~c=d#qwe
			// Note: this 404.html file must be at least 512 bytes for it to work
			// with Internet Explorer (it is currently > 512 bytes)

			// If you're creating a Project Pages site and NOT using a custom domain,
			// then set pathSegmentsToKeep to 1 (enterprise users may need to set it to > 1).
			// This way the code will only replace the route part of the path, and not
			// the real directory in which the app resides, for example:
			// https://username.github.io/repo-name/one/two?a=b&c=d#qwe becomes
			// https://username.github.io/repo-name/?/one/two&a=b~and~c=d#qwe
			// Otherwise, leave pathSegmentsToKeep as 0.
			var pathSegmentsToKeep = 0;

			var l = window.location;
			l.replace(
				l.protocol +
					'//' +
					l.hostname +
					(l.port ? ':' + l.port : '') +
					l.pathname
						.split('/')
						.slice(0, 1 + pathSegmentsToKeep)
						.join('/') +
					'/?/' +
					l.pathname.slice(1).split('/').slice(pathSegmentsToKeep).join('/').replace(/&/g, '~and~') +
					(l.search ? '&' + l.search.slice(1).replace(/&/g, '~and~') : '') +
					l.hash,
			);
		</script>
	</head>
	<body></body>
</html>



================================================
FILE: packages/stdf/static/.nojekyll
================================================





================================================
FILE: packages/stdf/static/fonts/Trueno.otf
================================================
[Non-text file]


================================================
FILE: packages/stdf/.github/workflows/releases-demo.yml
================================================
# 将 Demo 静态内容部署到 GitHub Pages 的简易工作流程
name: RELEASES DEMO

on:
  push:
    branches: 'main'

jobs:
  build_site:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: 'latest'

      - name: Install dependencies
        run: bun i

      - name: build
        env:
          BASE_PATH: '/demo-stdf'
        run: |
          bun run build

      - name: Upload Artifacts
        uses: actions/upload-pages-artifact@v3
        with:
          path: 'build/'

  deploy:
    needs: build_site
    runs-on: ubuntu-latest

    permissions:
      pages: write
      id-token: write

    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}

    steps:
      - name: Deploy
        id: deployment
        uses: actions/deploy-pages@v4



================================================
FILE: packages/vscode-extension/README.md
================================================
[简体中文](https://github.com/any-tdf/stdf/blob/main/packages/vscode-extension/README_CN.md)

# Introduction

A VS Code extension that provides convenience when developing with [STDF](https://stdf.design).

# Installation

Search for `STDF for VS Code` in the VS Code extensions marketplace and click install, or install [STDF for VS Code](https://marketplace.visualstudio.com/items?itemName=STDF.stdf-vscode-extension) from the marketplace.

# Features

When hovering over the name of an STDF component, the following information will be displayed:

- The API of this component.
- The example/API/guide of this component on the STDF official website.
- The source code of this component on GitHub/Gitee.

![TIP](https://stdf.design/assets/vscode/tip.png)

or

![TIP](https://stdf.design/assets/vscode/tip2.png)

# Configuration

The default API display is in Simplified Chinese. You can enable English API in the VS Code settings.

![SETTING](https://stdf.design/assets/vscode/setting.png)

# License

This project is licensed under the [MIT License](https://github.com/any-tdf/stdf/blob/main/LICENSE).



================================================
FILE: packages/vscode-extension/CHANGELOG.md
================================================
> No change log version, it means that it is just updated with the STDF version and the plug-in itself is not updated.

## 0.0.30

- Support STDF v1.x.

## 0.0.28

- Support STDF next.

## 0.0.24

- Update icon.

## 0.0.18

- Fixed the problem that STDF cannot be queried for the latest version, such as offline use.

## 0.0.17

- Fixed the latest version detection problem.

## 0.0.9

- Format source code.
- Display the current version and the latest version of STDF.

## 0.0.8

- Optimized GitHub Actions configuration.

## 0.0.7

- Added direct link to the corresponding component content on the STDF official website at the bottom of the tooltip.
- Added direct link to the source code of the corresponding component on GitHub/Gitee at the bottom of the tooltip.

## 0.0.6

- Add README.

## 0.0.1

- Init version.



================================================
FILE: packages/vscode-extension/CHANGELOG_CN.md
================================================
> 没有写更新日志的版本，表示只是跟随 STDF 版本更新，未对插件本身进行更新。

## 0.0.30

- 支持 STDF v1.x。

## 0.0.28

- 支持 STDF next。

## 0.0.24

- 更新图标。

## 0.0.18

- 修复无法查询 STDF 最新版本问题，如离线使用。

## 0.0.17

- 修复最新版本检测问题。

## 0.0.9

- 格式化源码。
- 显示 STDF 当前版本与最新版本。

## 0.0.8

- 优化 GitHub Actions 配置。

## 0.0.7

- 悬浮窗底部增加直接跳转 STDF 官网对应组件内容。
- 悬浮窗底部增加直接跳转 STDF 对应组件源码（GitHub/Gitee）。

## 0.0.6

- 增加 README。

## 0.0.1

- 初始版本。



================================================
FILE: packages/vscode-extension/package.json
================================================
{
	"name": "stdf-vscode-extension",
	"displayName": "STDF for VS Code",
	"description": "A VS Code extension to facilitate STDF development",
	"version": "0.0.34",
	"publisher": "STDF",
	"icon": "./src/assets/stdf-vscode-extension.png",
	"main": "./src/extension.js",
	"type": "module",
	"engines": {
		"vscode": "^1.27.0"
	},
	"scripts": {
		"files": "node scripts/files.js",
		"package": "vsce package",
		"publish": "vsce publish"
	},
	"categories": [
		"Programming Languages"
	],
	"activationEvents": [
		"onLanguage:svelte"
	],
	"sponsor": {
		"url": "https://stdf.design?fund"
	},
	"keywords": [
		"svelte",
		"stdf",
		"component",
		"api",
		"javascript"
	],
	"contributes": {
		"commands": [],
		"configuration": {
			"type": "object",
			"title": "STDF",
			"properties": {
				"STDF.English": {
					"type": "boolean",
					"default": false,
					"description": "Whether to enable English or not in stdf-vscode-extension"
				}
			}
		}
	},
	"devDependencies": {
		"vscode": "^1.1.37"
	},
	"repository": {
		"type": "git",
		"url": "https://github.com/any-tdf/stdf/tree/main/packages/vscode-extension"
	},
	"bugs": {
		"url": "https://github.com/any-tdf/stdf/issues?q=is:issue+is:open+vscode"
	},
	"homepage": "https://github.com/any-tdf/stdf/tree/main/packages/vscode-extension/README.md",
	"LICENSE": "https://github.com/any-tdf/stdf/blob/main/LICENSE"
}



================================================
FILE: packages/vscode-extension/README_CN.md
================================================
[English](https://github.com/any-tdf/stdf/blob/main/packages/vscode-extension/README.md)

# 介绍

一个 VS Code 插件，用于在使用 [STDF](https://stdf.design) 开发时提供一些便利。

# 安装

在 VS Code 插件中搜索 `STDF for VS Code` 点击安装，或到 VS Code 插件市场安装 [STDF for VS Code](https://marketplace.visualstudio.com/items?itemName=STDF.stdf-vscode-extension)。

# 功能

光标悬浮于 STDF 组件名称上时悬浮显示。

- 此组件 API。
- 直接打开 STDF 官网此组件的示例/API/指南。
- 直接打开 STDF 此组件源码（GitHub/Gitee）。

![TIP](https://stdf.design/assets/vscode/tip.png)

或者

![TIP](https://stdf.design/assets/vscode/tip2.png)

# 配置

默认显示的 API 为简体中文，可到 VS Code 的设置页开启英文 API。

![SETTING](https://stdf.design/assets/vscode/setting.png)

# 许可证

本项目基于 [MIT 许可证](https://github.com/any-tdf/stdf/blob/main/LICENSE)。



================================================
FILE: packages/vscode-extension/scripts/files.js
================================================
import fs from 'node:fs';

// 创建 src/docs/components 目录
// Create src/docs/components directory
const createDoc = () => {
	fs.mkdirSync('src/docs');
	fs.mkdirSync('src/docs/components');
	console.log('🎉 src/docs/components create success!');
};

// 将 ../../docs/mds/components/**/api.md 和 ../../docs/mds/components/**/api_en.md 文件复制到 src/docs/components/**/ 目录下
// Copy ../../docs/mds/components/**/api.md and ../../docs/mds/components/**/api_en.md files to src/docs/components/**/ directory
const copyDoc = () => {
	const components = fs.readdirSync('../../docs/mds/components');
	// 如果 components 有 .DS_Store 文件，删除
	// If components has .DS_Store file, delete
	if (components.includes('.DS_Store')) {
		components.splice(components.indexOf('.DS_Store'), 1);
	}

	for (const component of components) {
		const files = fs.readdirSync(`../../docs/mds/components/${component}`);
		fs.mkdirSync(`src/docs/components/${component}`);
		for (const file of files) {
			if (file === 'api.md' || file === 'api_en.md') {
				fs.copyFileSync(`../../docs/mds/components/${component}/${file}`, `src/docs/components/${component}/${file}`);
			}
		}
	}
	console.log(`🎉 Total copy ${components.length}*2 files!`);
};

// 复制 ../../docs/site/src/data/menuList.ts 文件到 src 目录下
// Copy ../../docs/site/src/data/menuList.ts file to src directory
const copyMenuList = () => {
	// 读取 ../../docs/site/src/data/menuList.ts 文件
	const menuList = fs.readFileSync('../../docs/site/src/data/menuList.ts', 'utf-8');
	console.log(menuList);
	// 将其中的部分内容替换为另一个文件中的内容
	// Replace the content of the file with the content of another file
	const newMenuList = menuList.replace(
		`export type MenuListChild = {
	title: string;
	title_zh: string;
	title_en: string;
	nav: string;
	tip: string;
	tip_en: string;
	alias: string;
};
export type MenuList = { class: string; class_en: string; childs: MenuListChild[] };

export const menuList: MenuList[] = [`,
		'export default ['
	);
	fs.writeFileSync('./src/menuList.js', newMenuList);
	console.log('🎉 menuList copy success!');
};

// 复制 ../../LICENSE 文件到 ./ 目录下
// Copy ../../LICENSE file to ./ directory
const copyLicense = () => {
	fs.copyFileSync('../../LICENSE', './LICENSE');
	console.log('🎉 LICENSE copy success!');
};

createDoc();
copyDoc();
copyMenuList();
copyLicense();



================================================
FILE: packages/vscode-extension/src/extension.js
================================================
import vscode from 'vscode';
import path from 'node:path';
import { exec } from 'node:child_process';

// 组件列表
// components list
import menuList from './menuList';
const componentList = ArrChildFun(menuList);

async function activate() {
	// 如果没有设置，返回 undefined
	// If not set, return undefined
	const result = vscode.workspace.getConfiguration().get('STDF');
	// 获取插件语言
	// Get plugin language
	const isZh = !result.English;

	// 读取当前工程的 package.json 文件
	// Read the package.json file of the current project
	const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
	const packageJson = workspaceFolder
		? await import(path.join(workspaceFolder.uri.fsPath, 'package.json'), { assert: { type: 'json' } })
		: null;

	// 判断当前工程是否引入了 stdf 组件库
	// Determine whether the current project has introduced the stdf component library
	const isImportStdf = !!(packageJson?.dependencies?.stdf || packageJson?.devDependencies?.stdf);

	// 如果 isImportStdf 为 true 时，读取 stdf 组件库的版本号做为当前版本号
	// If isImportStdf is true, read the version number of the stdf component library as the current version number
	let currentVersion = isImportStdf ? packageJson.dependencies?.stdf || packageJson.devDependencies?.stdf : '';
	// 如果 currentVersion 开头为 ^，则去掉 ^
	// If currentVersion starts with ^, remove ^
	if (currentVersion.startsWith('^')) {
		currentVersion = currentVersion.slice(1);
	}

	// stdf 组件库的最新版本号
	// The latest version number of the stdf component library
	const latestVersion = (await getLatestVersion('stdf')) || (isZh ? '获取失败' : 'Failed to get');

	// 当前文件是 .svelte 文件时且 isImportStdf 为 true 时，才注册悬浮提示
	// When the current file is a .svelte file and isImportStdf is true, register the hover prompt
	if (vscode.window.activeTextEditor.document.languageId === 'svelte' && isImportStdf) {
		vscode.languages.registerHoverProvider('svelte', {
			provideHover: async (document, position) => {
				// 获取当前悬浮的单词
				// Get the word currently hovering
				const word = document.getText(document.getWordRangeAtPosition(position));
				// 将单词首字母小写
				// Lowercase the first letter of the word
				const wordLower = word.charAt(0).toLowerCase() + word.slice(1);
				// 如果单词为 components 数组中的一项，则显示提示信息，内容为 ./doc/components/${wordLower}/api.md 文件的内容
				// If the word is an item in the components array, display the prompt information, and the content is the content of the ./doc/components/${wordLower}/api.md file
				if (componentList.includes(word)) {
					// 组合当前 STDF 版本和最新版本
					// Combine the current STDF version and the latest version
					const versionContent = `STDF ${isZh ? '当前' : 'Current'}：${currentVersion} &nbsp; ${
						isZh ? '最新' : 'Latest'
					}：${latestVersion} &nbsp; [${isZh ? '查看更新日志' : 'See changelog'}](https://stdf.design/guide/changelog)`;

					// 获取对应组件的 api.md 文件的路径
					// Get the path of the api.md file of the corresponding component
					const apiPath = path.join(__dirname, `./docs/components/${wordLower}/api${isZh ? '' : '_en'}.md`);

					// 读取 api.md 文件的内容
					// Read the contents of the api.md file
					const fs = await import('node:fs/promises');
					const apiContent = await fs.readFile(apiPath, 'utf-8');
					// 在 apiContent 后面添加示例、API、指南、组件源码的链接
					// Add links to examples, API, guides, and component source code after apiContent
					const baseUrl = 'https://stdf.design/components?nav=';
					const baseUrlCode = 'https://github.com/any-tdf/stdf/blob/main/packages/stdf/components/';
					const baseUrlCodeGitee = 'https://gitee.com/dufu1991/stdf/blob/main/packages/stdf/components/';
					const addContent = `**[${isZh ? '示例' : 'Demo'}](${baseUrl}${wordLower}&tab=0&lang=${
						isZh ? 'zh_CN' : 'en_US'
					}) &nbsp; [API](${baseUrl}${wordLower}&tab=1&lang=${isZh ? 'zh_CN' : 'en_US'}) &nbsp; [${
						isZh ? '指南' : 'Guide'
					}](${baseUrl}${wordLower}&tab=2&lang=${isZh ? 'zh_CN' : 'en_US'}) &nbsp; [${
						isZh ? '更新日志' : 'Changelog'
					}](${baseUrl}${wordLower}&tab=4&lang=${isZh ? 'zh_CN' : 'en_US'}) &nbsp; [${
						isZh ? '源码 (GitHub)' : 'Source code(GitHub)'
					}](${baseUrlCode}${wordLower}/${word}.svelte) &nbsp; [${
						isZh ? '源码 (Gitee)' : 'Source code(Gitee)'
					}](${baseUrlCodeGitee}${wordLower}/${word}.svelte)**`;
					const allContent = `${versionContent}

---

${apiContent}

---

${addContent}


---`;

					// 返回提示信息
					// Return prompt information
					return new vscode.Hover(allContent);
				}
			},
		});
	}
}

//数组处理
//Array processing
function ArrChildFun(arr) {
	const newArr = [];
	for (let e = 0; e < arr.length; e++) {
		newArr.push(...arr[e].childs);
	}
	//再将 newArr 内的 title_en 组成一维数组
	//Then the title_en in newArr is composed of one-dimensional array
	const newArr2 = [];
	for (let e = 0; e < newArr.length; e++) {
		newArr2.push(newArr[e].title_en);
	}
	return newArr2;
}

// 获取指定 npm 包的最新版本号
// Get the latest version number of the specified npm package
async function getLatestVersion(packageName) {
	return new Promise(resolve => {
		exec(`npm show ${packageName} version`, (error, stdout, stderr) => {
			if (error || stderr) {
				resolve(null);
			} else {
				resolve(stdout.trim());
			}
		});
	});
}

function deactivate() {}

module.exports = {
	activate,
	deactivate,
};




================================================
FILE: .github/CONTRIBUTING.md
================================================
[简体中文](https://stdf.design/guide/contribution?lang=zh_CN)

## Introduction

Thank you for using STDF.

Below are guidelines for submitting feedback or code to STDF. Before submitting an issue or PR to STDF, please take a few minutes to read the following.

## Issue Guidelines

- When encountering an issue, please first confirm whether the issue has already been recorded in the issue or has been fixed.
- When submitting an issue, please describe the issue briefly in language and add the environment and replication steps when the issue occurs.

## Local Development

Before local development, please make sure that [Git](https://git-scm.com) and [Node.js](https://nodejs.org/en) or [Bun](https://bun.sh) are installed in your development environment.

Debugging STDF requires an engineering environment. For this purpose, a simple Demo project is provided. STDF itself is not limited by the Node version, and the Demo uses Vite for development, so please ensure that your Node.js version >= 14.18+, refer to the [Vite official website](https://cn.vitejs.dev/guide/#scaffolding-your-first-vite-project).

Before submitting a PR after you have made code modifications, please ensure that you have formatted the code and passed the code formatting check. You can install relevant editor plugins or use the command line for code formatting.

Recommended installations:

- [pnpm](https://pnpm.io): Package management tool, no need to install when using Bun.
- [Svelte for VS Code](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) or [Svelte](https://plugins.jetbrains.com/plugin/12375-svelte): Svelte development plugin.
- [Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) or [WebStorm integration](https://www.jetbrains.com/help/webstorm/tailwind-css.html): Tailwind CSS development plugin.
- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) or [WebStorm integration](https://www.jetbrains.com/help/webstorm/eslint.html): Code formatting check plugin.
- [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) or [WebStorm integration](https://www.jetbrains.com/help/webstorm/prettier.html): Code formatting plugin.

> Because the rollup-plugin-stdf-icon packages that the demo depends on are locally built, please build this packages first.

<!-- :::code-groups -->
<!-- pnpm -->

```sh
## 1. Clone the STDF repository and enter
git clone git@github.com:any-tdf/stdf.git
cd stdf

## 2. Build the rollup-plugin-stdf-icon package
cd packages/rollup-plugin-stdf-icon
## Install dependencies
pnpm i
## Build package
pnpm build

## 3. Use the Demo project to debug STDF
cd demo
## Install dependencies
pnpm i
## Start Demo
pnpm dev
```

<!-- :: -->
<!-- npm -->

```sh
## 1. Clone the STDF repository and enter
git clone git@github.com:any-tdf/stdf.git
cd stdf

## 2. Build the rollup-plugin-stdf-icon package
cd packages/rollup-plugin-stdf-icon
## Install dependencies
npm i
## Build package
npm run build

## 3. Use the Demo project to debug STDF
cd demo
## Install dependencies
npm i
## Start Demo
npm run dev
```

<!-- :: -->
<!-- bun -->

```sh
## 1. Clone the STDF repository and enter
git clone git@github.com:any-tdf/stdf.git
cd stdf

## 2. Build the rollup-plugin-stdf-icon package
cd packages/rollup-plugin-stdf-icon
## Install dependencies
bun i
## Build package
bun build

## 3. Use the Demo project to debug STDF
cd demo
## Install dependencies
bun i
## Start Demo
bun dev
```

<!-- :: -->
<!-- yarn -->

```sh
## 1. Clone the STDF repository and enter
git clone git@github.com:any-tdf/stdf.git
cd stdf

## 2. Build the rollup-plugin-stdf-icon package
cd packages/rollup-plugin-stdf-icon
## Install dependencies
yarn
## Build package
yarn build

## 3. Use the Demo project to debug STDF
cd demo
## Install dependencies
yarn
## Start Demo
yarn dev
```

<!-- ::: -->

After the startup is successful, you can open `http://localhost:8888` in the browser to view the effect. Please switch the developer tools of the browser to the mobile mode.

You can modify the component source code under the `packages/stdf/components` directory and view the modification effect in real-time. Note that both VS Code and WebStorm support directly jumping to the component source code when calling the component.

If you don't want to develop locally, you can choose to use StackBlitz to debug online. Just open [STDF Demo](https://stackblitz.com/github/any-tdf/demo-stdf?startScript=dev_en) to start online debugging.

## Submitting PR

If you are submitting a Pull Request on GitHub for the first time, you can read the following two articles to learn:

- [First Contributions](https://github.com/firstcontributions/first-contributions/blob/main/translations/README.zh-cn.md)
- [How to contribute code elegantly on GitHub](https://segmentfault.com/a/1190000000736629)

### Process

- Please fork a copy of [STDF](https://github.com/any-tdf/stdf) to your own repository. If you have already forked, please synchronize the latest code from the main repository.
- Clone your repository to your local machine.
- Modify the component source code and verify it in the Demo.
- 「Optional」Supplement the Chinese and English documentation for this modification, which is located in the `doc/components` directory. Depending on the specific modification content, you may need to modify the api, FAQ, guide, version, and other documents. For modifications to version, please add tags. Please refer to the [STDF Version tag](https://github.com/any-tdf/stdf/blob/main/doc/components/button/version.md?plain=1) for specific details.
- Go to the root directory of the repository and execute `pnpm i` or `npm i` or `bun i` to install dependencies.
- Use your editor to format the modified code or execute `pnpm run format` or `npm run format` in the command line to format the code.
- Execute `pnpm run lint` or `npm run lint` to check the code formatting.
- Commit the modified content to your repository and then submit a Pull Request to the main repository.
- The Pull Request will be merged into the main repository after it passes the review and a new version will be released subsequently.

### Notes

When submitting a Pull Request, please note:

- Keep your PR small enough, generally one PR only solves a single component file, solves a single problem, or adds a single function, to facilitate review.
- When adding or modifying existing components, remember to verify it in the Demo to ensure the stability of the code.
- Please add a suitable description in the PR. If there is a related issue, please indicate it.



================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: ['https://stdf.design?fund']



================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
Before submitting a pull request, please read the [contributing guide](https://stdf.design/guide/contribution).

在提交 pull request 之前，请阅读 [贡献指南](https://stdf.design/guide/contribution)。



================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: 🐞 Bug Report
description: Report an issue with STDF
title: '[Bug]: '
labels: ['bug']
body:
    - type: markdown
      attributes:
          value: |
              Thank you for taking the time to fill out this bug report! If you have a usage question or are unsure if it's really a bug, please make sure:

              - You are using the latest version of the code.
              - You have checked the open and closed issues to see if your issue has already been reported.
              - If there is a similar issue in the issues list, please provide additional information in the corresponding issue.
              - Your description of the problem is concise and clear, not just from your own perspective.

    - type: dropdown
      id: module
      attributes:
          label: Module
          description: Which module does this bug belong to?
          options:
              - stdf (STDF component)
              - create (create-stdf scaffolding)
              - vscode (STDF VS Code plugin)
              - icon (rollup-plugin-stdf-icon plugin)
              - md (rollup-plugin-md-ts plugin)
              - demo (STDF demo)
              - doc (STDF site and documentation)
              - other (other)
      validations:
          required: true

    - type: input
      id: version
      attributes:
          label: Version
          description: If it is stdf/create/icon/vscode/md, please indicate the version in which this bug occurred.
      validations:
          required: false

    - type: textarea
      id: bug-description
      attributes:
          label: Bug Description
          description: Please describe the bug clearly and concisely.
          placeholder: When...
      validations:
          required: true

    - type: textarea
      id: reproduction
      attributes:
          label: Reproduction
          description: You can use text/images/short videos to explain how to reproduce the issue, but please provide a series of information about the environment where the problem occurs, such as device model and version, operating system and version, browser, etc. You can also use [StackBlitz](https://stackblitz.com) or [CodePen](https://codepen.io) or other online IDEs to quickly create a project to demonstrate the bug. In short, make it easy for others to understand how to reproduce the bug.
          placeholder: On iPhone 13 Pro with iOS 16...
      validations:
          required: true

    - type: textarea
      id: idea
      attributes:
          label: Your Idea
          description: If you have a solution or idea for this bug, you can describe it here.
          placeholder: I think...
      validations:
          required: false



================================================
FILE: .github/ISSUE_TEMPLATE/bug_report_CN.yml
================================================
name: 🐞 缺陷报告
description: 报告 STDF 问题
title: '[Bug]: '
labels: ['bug']
body:
    - type: markdown
      attributes:
          value: |
              感谢您抽出时间填写这份错误报告！如果您有使用问题，或者不确定是否真的是一个错误，请确保：

              - 你使用的是最新版代码。
              - 你已经查看过开启与关闭状态的 issues ，其中并没有你发现的此问题。
              - 如果 issues 中已有相同问题，你需要补充，请尽量在对应的 issue 中补充讨论。
              - 你对问题的表述简洁清晰，不只在你的情景角度能理解。

    - type: dropdown
      id: module
      attributes:
          label: 模块
          description: 此缺陷属于哪个模块？
          options:
              - stdf (STDF 组件)
              - create (create-stdf 脚手架)
              - vscode (STDF VS Code 插件)
              - icon (rollup-plugin-stdf-icon 插件)
              - md (rollup-plugin-md-ts 插件)
              - demo (STDF demo)
              - doc (STDF 站点与文档)
              - other (其他)
      validations:
          required: true

    - type: input
      id: version
      attributes:
          label: 版本
          description: 如果是选择的是 stdf、create、icon、vscode、md，请注明此缺陷出现的版本。
      validations:
          required: false

    - type: textarea
      id: bug-description
      attributes:
          label: 描述缺陷
          description: 请清晰简明地描述清楚该缺陷内容。
          placeholder: 当...
      validations:
          required: true

    - type: textarea
      id: reproduction
      attributes:
          label: 复现
          description: 你可以使用文字/图片/简短视频说清楚如何复现此问题，但请尽量说清设备型号与版本、操作系统与版本、浏览器等一系列出现问题的环境。也可以使用 [StackBlitz](https://stackblitz.com) 或者 [CodePen](https://codepen.io) 或其他在线 IDE 快速创建一个工程展示此缺陷。总之让别人能快速明白此缺陷的复现情况。
          placeholder: 在 iPhone 13 Pro 的 iOS 16...
      validations:
          required: true

    - type: textarea
      id: idea
      attributes:
          label: 你的想法
          description: 如果你对该缺陷有解决方案或思路，可以在这里描述。
          placeholder: 我认为...
      validations:
          required: false



================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.yml
================================================
name: 👏 Feature Request
description: Submit a request for a new feature
title: '[Feature]: '
labels: ['enhancement']
body:
    - type: markdown
      attributes:
          value: |
              Thank you for taking the time to fill out this feature request! If you have a new idea or are unsure if it can be implemented, please make sure:

              - You have checked the latest version of the code and confirmed that the feature does not exist.
              - You have checked the open and closed issues to see if the feature you want to add has been described.
              - If there is a similar feature request in the issues list, please provide additional information in the corresponding issue.
              - Your description of the new feature is concise and clear, not just from your own perspective.

    - type: dropdown
      id: module
      attributes:
          label: Module
          description: Which module does this new feature belong to?
          options:
              - stdf (STDF component)
              - create (create-stdf scaffolding)
              - vscode (STDF VS Code plugin)
              - icon (rollup-plugin-stdf-icon plugin)
              - md (rollup-plugin-md-ts plugin)
              - demo (STDF demo)
              - doc (STDF site and documentation)
              - other (other)
      validations:
          required: true

    - type: textarea
      id: description
      attributes:
          label: Feature Description
          description: Please describe the new feature clearly and concisely.
          placeholder: When...
      validations:
          required: true

    - type: textarea
      id: example
      attributes:
          label: Example
          description: You can provide some similar implementations in other projects to help others understand your idea.
          placeholder: In...
      validations:
          required: false

    - type: textarea
      id: idea
      attributes:
          label: Your Idea
          description: If you have any implementation ideas or thoughts about the new feature, you can describe them here.
          placeholder: I think...
      validations:
          required: false



================================================
FILE: .github/ISSUE_TEMPLATE/feature_request_CN.yml
================================================
name: 👏 功能新增
description: 提交一个新功能的需求
title: '[Feature]: '
labels: ['enhancement']
body:
    - type: markdown
      attributes:
          value: |
              感谢您抽出时间填写这份新功能请求报告！如果您有新的想法，或者不确定是否能实现，请确保：

              - 你已经查看最新版代码无此功能。
              - 你已经查看过开启与关闭状态的 issues ，其中并没有你想增加的功能描述。
              - 如果 issues 中已有相同新功能，你需要补充，请尽量在对应的 issue 中补充讨论。
              - 你对新功能的表述简洁清晰，不只在你的情景角度能理解。

    - type: dropdown
      id: module
      attributes:
          label: 模块
          description: 此新功能属于哪个模块？
          options:
              - stdf (STDF 组件)
              - create (create-stdf 脚手架)
              - vscode (STDF VS Code 插件)
              - icon (rollup-plugin-stdf-icon 插件)
              - md (rollup-plugin-md-ts 插件)
              - demo (STDF demo)
              - doc (STDF 站点与文档)
              - other (其他)
      validations:
          required: true

    - type: textarea
      id: description
      attributes:
          label: 新功能描述
          description: 请清晰简明地描述清楚该新功能内容。
          placeholder: 当...
      validations:
          required: true

    - type: textarea
      id: example
      attributes:
          label: 示例
          description: 你可以给出一些在其他项目中类似的实现，方便大家理解你的想法。
          placeholder: 在...
      validations:
          required: false

    - type: textarea
      id: idea
      attributes:
          label: 你的想法
          description: 如果你对新功能有实现思路或任何想法，可以在这里描述。
          placeholder: 我认为...
      validations:
          required: false



================================================
FILE: .github/workflows/publish-create.yml
================================================
# 当分支 main 有 push 事件并且此次 push 包含了 packages/create-stdf/package.json 文件时，执行以下任务

name: PUBLISH CREATE

on:
    push:
        branches:
            - main
        paths:
            - 'packages/create-stdf/package.json'

jobs:
    publish:
        runs-on: ubuntu-latest
        permissions:
            id-token: write
            contents: write

        steps:
            - name: Checkout
              uses: actions/checkout@v4

            - name: Setup Node.js environment
              uses: actions/setup-node@v3
              with:
                  node-version: 20.x

            # 将 LICENSE 复制到 packages/create-stdf 目录下
            # cd packages/create-stdf 目录下
            # 安装依赖 npm install
            # 打包 npm run build
            # 执行 npm run update
            # 发布 create-stdf 到 npm
            - name: Publish
              run: |
                  cp LICENSE packages/create-stdf/LICENSE
                  cd packages/create-stdf
                  npm install
                  npm run build
                  npm run update
                  npm config set //registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN
                  npm publish --provenance
              env:
                  CI: true
                  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}



================================================
FILE: .github/workflows/publish-icon-0.x.yml
================================================
# 当分支 0.x 有 push 事件并且此次 push 包含了 packages/rollup-plugin-stdf-icon/package.json 文件时，执行以下任务

name: PUBLISH ICON 0.x

on:
    push:
        branches:
            - 0.x
        paths:
            - 'packages/rollup-plugin-stdf-icon/package.json'

jobs:
    publish:
        runs-on: ubuntu-latest
        permissions:
            id-token: write
            contents: write

        steps:
            - name: Checkout
              uses: actions/checkout@v4

            - name: Setup Node.js environment
              uses: actions/setup-node@v3
              with:
                  node-version: 20.x

            # 将 LICENSE 复制到 packages/rollup-plugin-stdf-icon 目录下
            # cd packages/rollup-plugin-stdf-icon 目录下
            # 安装依赖 npm install
            # 打包 npm run build
            # 发布 rollup-plugin-stdf-icon 到 npm
            - name: Publish
              run: |
                  cp LICENSE packages/rollup-plugin-stdf-icon/LICENSE
                  cd packages/rollup-plugin-stdf-icon
                  npm install
                  npm run build 
                  npm config set //registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN
                  npm publish --provenance
              env:
                  CI: true
                  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}



================================================
FILE: .github/workflows/publish-icon.yml
================================================
# 当分支 main 有 push 事件并且此次 push 包含了 packages/rollup-plugin-stdf-icon/package.json 文件时，执行以下任务

name: PUBLISH ICON

on:
    push:
        branches:
            - main
        paths:
            - 'packages/rollup-plugin-stdf-icon/package.json'

jobs:
    publish:
        runs-on: ubuntu-latest
        permissions:
            id-token: write
            contents: write

        steps:
            - name: Checkout
              uses: actions/checkout@v4

            - name: Setup Node.js environment
              uses: actions/setup-node@v3
              with:
                  node-version: 20.x

            # 将 LICENSE 复制到 packages/rollup-plugin-stdf-icon 目录下
            # cd packages/rollup-plugin-stdf-icon 目录下
            # 安装依赖 npm install
            # 打包 npm run build
            # 发布 rollup-plugin-stdf-icon 到 npm
            - name: Publish
              run: |
                  cp LICENSE packages/rollup-plugin-stdf-icon/LICENSE
                  cd packages/rollup-plugin-stdf-icon
                  npm install
                  npm run build 
                  npm config set //registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN
                  npm publish --provenance
              env:
                  CI: true
                  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}



================================================
FILE: .github/workflows/publish-md-0.x.yml
================================================
# 当分支 0.x 有 push 事件并且此次 push 包含了 packages/rollup-plugin-md-ts/package.json 文件时，执行以下任务

name: PUBLISH MD 0.x

on:
    push:
        branches:
            - 0.x
        paths:
            - 'packages/rollup-plugin-md-ts/package.json'

jobs:
    publish:
        runs-on: ubuntu-latest
        permissions:
            id-token: write
            contents: write

        steps:
            - name: Checkout
              uses: actions/checkout@v4

            - name: Setup Node.js environment
              uses: actions/setup-node@v3
              with:
                  node-version: 20.x

            # 将 LICENSE 复制到 packages/rollup-plugin-md-ts 目录下
            # cd packages/rollup-plugin-md-ts 目录下
            # 安装依赖 npm install
            # 打包 npm run build
            # 发布 rollup-plugin-md-ts 到 npm
            - name: Publish
              run: |
                  cp LICENSE packages/rollup-plugin-md-ts/LICENSE
                  cd packages/rollup-plugin-md-ts
                  npm install
                  npm run build 
                  npm config set //registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN
                  npm publish --tag=0.x --provenance
              env:
                  CI: true
                  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}



================================================
FILE: .github/workflows/publish-md.yml
================================================
# 当分支 main 有 push 事件并且此次 push 包含了 packages/rollup-plugin-md-ts/package.json 文件时，执行以下任务

name: PUBLISH MD

on:
    push:
        branches:
            - main
        paths:
            - 'packages/rollup-plugin-md-ts/package.json'

jobs:
    publish:
        runs-on: ubuntu-latest
        permissions:
            id-token: write
            contents: write

        steps:
            - name: Checkout
              uses: actions/checkout@v4

            - name: Setup Node.js environment
              uses: actions/setup-node@v3
              with:
                  node-version: 20.x

            # 将 LICENSE 复制到 packages/rollup-plugin-md-ts 目录下
            # cd packages/rollup-plugin-md-ts 目录下
            # 安装依赖 npm install
            # 打包 npm run build
            # 发布 rollup-plugin-md-ts 到 npm
            - name: Publish
              run: |
                  cp LICENSE packages/rollup-plugin-md-ts/LICENSE
                  cd packages/rollup-plugin-md-ts
                  npm install
                  npm run build 
                  npm config set //registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN
                  npm publish --provenance
              env:
                  CI: true
                  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}



================================================
FILE: .github/workflows/publish-stdf-0.x.yml
================================================
# 当分支 0.x 有 push 事件并且此次 push 包含了 packages/stdf/package.json 文件时，执行以下任务

name: PUBLISH STDF 0.x

on:
    push:
        branches:
            - 0.x
        paths:
            - 'packages/stdf/package.json'

jobs:
    publish:
        runs-on: ubuntu-latest
        permissions:
            id-token: write
            contents: write

        steps:
            - name: Checkout
              uses: actions/checkout@v4

            - name: Setup Node.js environment
              uses: actions/setup-node@v3
              with:
                  node-version: 20.x

            # 将 README.md 和 LICENSE 复制到 packages/stdf 目录下
            - name: Copy Files
              run: |
                  cp README.md packages/stdf/README.md
                  cp LICENSE packages/stdf/LICENSE

            # cd packages/stdf 目录下
            # 发布 stdf 到 npm
            - name: Publish
              run: |
                  cd packages/stdf
                  npm config set //registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN
                  npm publish --tag=0.x --provenance
              env:
                  CI: true
                  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}



================================================
FILE: .github/workflows/publish-stdf.yml
================================================
# 当分支 main 有 push 事件并且此次 push 包含了 packages/stdf/package.json 文件时，执行以下任务

name: PUBLISH STDF

on:
    push:
        branches:
            - main
        paths:
            - 'packages/stdf/package.json'

jobs:
    publish:
        runs-on: ubuntu-latest
        permissions:
            id-token: write
            contents: write

        steps:
            - name: Checkout
              uses: actions/checkout@v4

            - name: Setup Node.js environment
              uses: actions/setup-node@v3
              with:
                  node-version: 20.x

            # 将 README.md 和 LICENSE 复制到 packages/stdf 目录下
            - name: Copy Files
              run: |
                  cp README.md packages/stdf/README.md
                  cp LICENSE packages/stdf/LICENSE

            # 打包 packages/rollup-plugin-stdf-icon 并构建
            - name: Build rollup-plugin-stdf-icon
              run: |
                  cd packages/rollup-plugin-stdf-icon
                  npm install
                  npm run build
                  cd ../../

            # cd packages/stdf 目录下
            # 发布 stdf 到 npm
            - name: Publish
              run: |
                  cd packages/stdf
                  npm install
                  npm run package
                  npm config set //registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN
                  npm publish --provenance
              env:
                  CI: true
                  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}



================================================
FILE: .github/workflows/publish-vscode-0.x.yml
================================================
# 当分支 0.x 有 push 事件并且此次 push 包含了 packages/vscode-extension/package.json 文件时，执行以下任务

name: PUBLISH VSCODE 0.x

on:
    push:
        branches:
            - 0.x
        paths:
            - 'packages/vscode-extension/package.json'

jobs:
    publish:
        runs-on: ubuntu-latest

        steps:
            - name: Checkout
              uses: actions/checkout@v4

            - name: Setup Node.js environment
              uses: actions/setup-node@v3
              with:
                  node-version: 20.x

            # cd 到 packages/vscode-extension 目录
            # 执行 files
            # 安装依赖
            - name: Publish
              run: |
                  cd packages/vscode-extension
                  npm run files
                  npm install
                  npm install -g @vscode/vsce
                  vsce publish -p ${{ secrets.VSCE_TOKEN }}



================================================
FILE: .github/workflows/publish-vscode.yml
================================================
# 当分支 main 有 push 事件并且此次 push 包含了 packages/vscode-extension/package.json 文件时，执行以下任务

name: PUBLISH VSCODE

on:
    push:
        branches:
            - main
        paths:
            - 'packages/vscode-extension/package.json'

jobs:
    publish:
        runs-on: ubuntu-latest

        steps:
            - name: Checkout
              uses: actions/checkout@v4

            - name: Setup Node.js environment
              uses: actions/setup-node@v3
              with:
                  node-version: 20.x

            # cd 到 packages/vscode-extension 目录
            # 执行 files
            # 安装依赖
            - name: Publish
              run: |
                  cd packages/vscode-extension
                  npm run files
                  npm install
                  npm install -g @vscode/vsce
                  vsce publish -p ${{ secrets.VSCE_TOKEN }}



================================================
FILE: .github/workflows/releases-0.x.yml
================================================
# 当分支 0.x 有 push 事件，并且此次 push 包含了 packages/stdf/package.json 文件时，执行以下任务

name: RELEASES 0.x

on:
    push:
        branches:
            - 0.x
        paths:
            - 'packages/stdf/package.json'

jobs:
    releases:
        runs-on: ubuntu-latest

        steps:
            - name: Checkout
              uses: actions/checkout@v4

            # 1. 读取 packages/stdf/package.json 中的 version 字段，作为 Releases tag 和 Releases title
            - name: Get version
              id: version
              run: |
                  echo version=$(cat packages/stdf/package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g' | tr -d '[[:space:]]') >> $GITHUB_OUTPUT

            # 2. 读取 doc/guide/changelog.md 的第一行内容中 ‘##’ 与 ‘<font’ 之间的内容，再去除空格
            - name: Get md_version
              id: md_version
              run: |
                  echo md_version=$(cat doc/guide/changelog.md | head -1 | sed 's/## //g' | sed 's/<font.*>//g' | tr -d '[[:space:]]') >> $GITHUB_OUTPUT

            # 3. 读取 doc/guide/changelog_en.md 的第一行内容中 ‘##’ 与 ‘<font’ 之间的内容，再去除空格
            - name: Get md_version_en
              id: md_version_en
              run: |
                  echo md_version_en=$(cat doc/guide/changelog_en.md | head -1 | sed 's/## //g' | sed 's/<font.*>//g' | tr -d '[[:space:]]') >> $GITHUB_OUTPUT

            # 4. 比较 Get version 与 Get md_version 和 Get md_version_en 三者的输出内容，如果不相同则此次不需要发布 Release，退出
            - name: Check version
              run: |
                  if [[ ${{ steps.version.outputs.version }} != ${{ steps.md_version.outputs.md_version }} ]]; then
                      echo "This is not a tag push. Skipping."
                      exit 78
                  fi
                  if [[ ${{ steps.version.outputs.version }} != ${{ steps.md_version_en.outputs.md_version_en }} ]]; then
                      echo "This is not a tag push. Skipping."
                      exit 78
                  fi

            # 5. 读取 doc/guide/changelog.md 中前两个二级标题之间的内容，包含换行和空格
            - name: Get changelog
              id: changelog
              run: |
                  echo 'changelog<<EOF' >> $GITHUB_OUTPUT
                  sed -n '1,/##/{/##/!p;}' doc/guide/changelog.md | sed '/^$/d' >> $GITHUB_OUTPUT
                  echo 'EOF' >> $GITHUB_OUTPUT

            # 6. 读取 doc/guide/changelog_en.md 中第一个二级标题与第二个二级标题之间的内容，包含换行和空格
            - name: Get changelog_en
              id: changelog_en
              run: |
                  echo 'changelog_en<<EOF' >> $GITHUB_OUTPUT
                  sed -n '1,/##/{/##/!p;}' doc/guide/changelog_en.md | sed '/^$/d' >> $GITHUB_OUTPUT
                  echo 'EOF' >> $GITHUB_OUTPUT

            # 7. 作为 latest release 发布本次 Release，body 为 changelog 和 changelog_en 的合并内容，中间使用 --- 分隔
            - name: Release
              uses: actions/create-release@v1
              env:
                  GITHUB_TOKEN: ${{ secrets.STDF_GITHUB_TOKEN }}
              with:
                  tag_name: v${{ steps.version.outputs.version }}
                  release_name: v${{ steps.version.outputs.version }}
                  body: |
                      ${{ steps.changelog.outputs.changelog }}
                      ---
                      ${{ steps.changelog_en.outputs.changelog_en }}
                  draft: false
                  prerelease: false



================================================
FILE: .github/workflows/releases-site.yml
================================================
# 将静态内容部署到 GitHub Pages 的简易工作流程
name: RELEASES SITE

on:
    # 仅在推送到默认分支且 docs 文件夹有变动时触发工作流
    push:
        branches:
            - main
        paths:
            - 'docs/**'
    # 这个选项可以使你手动在 Action tab 页面触发工作流
    workflow_dispatch:

# 设置 GITHUB_TOKEN 的权限，以允许部署到 GitHub Pages。
permissions:
    contents: read
    pages: write
    id-token: write

# 允许一个并发的部署
concurrency:
    group: 'pages'
    cancel-in-progress: true

jobs:
    # 单次部署的工作描述
    deploy:
        environment:
            name: github-pages
            url: ${{ steps.deployment.outputs.page_url }}
        runs-on: ubuntu-latest
        steps:
            - name: Checkout
              uses: actions/checkout@v4

            - name: Set up Bun
              uses: oven-sh/setup-bun@v2
              with:
                  bun-version: 'latest'

            - name: Build rollup-plugin-stdf-icon & stdf & rollup-plugin-md-ts
              run: |
                  cd packages/rollup-plugin-stdf-icon
                  bun i
                  bun run build
                  cd ../stdf
                  bun i
                  bun run package
                  cd ../rollup-plugin-md-ts
                  bun i
                  bun run build
                  cd ../../

            - name: Install dependencies and build
              run: |
                  cd docs/site
                  bun i
                  bun run build

            - name: Setup Pages
              uses: actions/configure-pages@v4

            - name: Upload artifact
              uses: actions/upload-pages-artifact@v3
              with:
                  path: './docs/site/build'

            - name: Deploy to GitHub Pages
              id: deployment
              uses: actions/deploy-pages@v4



================================================
FILE: .github/workflows/releases-stdf.yml
================================================
# 当分支 main 有 push 事件，并且此次 push 包含了 packages/stdf/package.json 文件时，执行以下任务

name: RELEASES STDF

on:
    workflow_dispatch:
    push:
        branches:
            - main
        paths:
            - 'packages/stdf/package.json'

jobs:
    releases:
        runs-on: ubuntu-latest

        steps:
            - name: Checkout
              uses: actions/checkout@v4

            # 1. 读取 packages/stdf/package.json 中的 version 字段，作为 Releases tag 和 Releases title
            - name: Get version
              id: version
              run: |
                  echo version=$(cat packages/stdf/package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g' | tr -d '[[:space:]]') >> $GITHUB_OUTPUT

            # 2. 读取 docs/mds/guide/changelog.md 的第一行内容中‘##’与‘<font’之间的内容，再去除空格
            - name: Get md_version
              id: md_version
              run: |
                  echo md_version=$(cat docs/mds/guide/changelog.md | head -1 | sed 's/## //g' | sed 's/<font.*>//g' | tr -d '[[:space:]]') >> $GITHUB_OUTPUT

            # 3. 读取 docs/mds/guide/changelog_en.md 的第一行内容中‘##’与‘<font’之间的内容，再去除空格
            - name: Get md_version_en
              id: md_version_en
              run: |
                  echo md_version_en=$(cat docs/mds/guide/changelog_en.md | head -1 | sed 's/## //g' | sed 's/<font.*>//g' | tr -d '[[:space:]]') >> $GITHUB_OUTPUT

            # 4. 比较 Get version 与 Get md_version 和 Get md_version_en 三者的输出内容，如果不相同则此次不需要发布 Release，退出
            - name: Check version
              run: |
                  if [[ ${{ steps.version.outputs.version }} != ${{ steps.md_version.outputs.md_version }} ]]; then
                      echo "This is not a tag push. Skipping."
                      exit 78
                  fi
                  if [[ ${{ steps.version.outputs.version }} != ${{ steps.md_version_en.outputs.md_version_en }} ]]; then
                      echo "This is not a tag push. Skipping."
                      exit 78
                  fi

            # 5. 读取 docs/mds/guide/changelog.md 中前两个二级标题之间的内容，包含换行和空格
            - name: Get changelog
              id: changelog
              run: |
                  echo 'changelog<<EOF' >> $GITHUB_OUTPUT
                  sed -n '1,/##/{/##/!p;}' docs/mds/guide/changelog.md | sed '/^$/d' >> $GITHUB_OUTPUT
                  echo 'EOF' >> $GITHUB_OUTPUT

            # 6. 读取 docs/mds/guide/changelog_en.md 中第一个二级标题与第二个二级标题之间的内容，包含换行和空格
            - name: Get changelog_en
              id: changelog_en
              run: |
                  echo 'changelog_en<<EOF' >> $GITHUB_OUTPUT
                  sed -n '1,/##/{/##/!p;}' docs/mds/guide/changelog_en.md | sed '/^$/d' >> $GITHUB_OUTPUT
                  echo 'EOF' >> $GITHUB_OUTPUT

            # 7. 作为 latest release 发布本次 Release，body 为 changelog 和 changelog_en 的合并内容，中间使用 --- 分隔
            - name: Release
              uses: actions/create-release@v1
              env:
                  GITHUB_TOKEN: ${{ secrets.STDF_GITHUB_TOKEN }}
              with:
                  tag_name: v${{ steps.version.outputs.version }}
                  release_name: v${{ steps.version.outputs.version }}
                  body: |
                      ${{ steps.changelog.outputs.changelog }}
                      ---
                      ${{ steps.changelog_en.outputs.changelog_en }}
                  draft: false
                  prerelease: false



================================================
FILE: .github/workflows/sync-demo-0.x.yml
================================================
# 当分支 0.x 有 push 事件，并且此次 push 包含了 demo 目录下的文件时触发，使用 GitHub Actions 执行

name: SYNC DEMO 0.x

on:
    workflow_dispatch:
    push:
        branches:
            - 0.x
        paths:
            - 'demo/**'
jobs:
    sync:
        runs-on: ubuntu-latest
        steps:
            - name: Checkout
              uses: actions/checkout@v4

            # clone 仓库 github.com/any-tdf/stdf
            - name: Clone stdf
              uses: actions/checkout@v4
              with:
                  repository: any-tdf/stdf
                  token: ${{ secrets.STDF_GITHUB_TOKEN }}
                  path: stdf

            # 切换到 0.x 分支
            - name: Checkout 0.x
              run: |
                  git checkout 0.x

            # 读取 packages/stdf/package.json 中的 version 字段，作为 stdf 的最新版本
            - name: Get version
              id: version
              run: |
                  echo version=$(cat packages/stdf/package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g' | tr -d '[[:space:]]') >> $GITHUB_OUTPUT

            # 读取 packages/rollup-plugin-stdf-icon/package.json 中的 version 字段，作为 rollup-plugin-stdf-icon 的最新版本
            - name: Get rollup-plugin-stdf-icon version
              id: rollup-plugin-stdf-icon-version
              run: |
                  echo rollup-plugin-stdf-icon-version=$(cat packages/rollup-plugin-stdf-icon/package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g' | tr -d '[[:space:]]') >> $GITHUB_OUTPUT

            # 将 stdf/LICENSE 复制到 stdf/demo 目录下
            # cd 到 stdf/demo 文件内，初始化本地仓库
            # 将 demo/package.json 内的 "svelte" 前面增加一行 "stdf": "^${{ steps.version.outputs.version }}",
            # 将 demo/package.json 内的 file:../packages/rollup-plugin-stdf-icon 替换为 ^${{ steps.rollup-plugin-stdf-icon-version.outputs.rollup-plugin-stdf-icon-version }}
            # 将 demo/src/routes/+layout.svelte 内的 "'../../../packages/stdf/components'"  替换为 "'stdf'"
            # 将 demo/src/routes/+layout.svelte 内的 "'../../../packages/stdf/lang/zh_CN'"  替换为 "'stdf/lang/zh_CN'"
            # 将 demo/src/routes/+layout.svelte 内的 "'../../../packages/stdf/lang/en_US'"  替换为 "'stdf/lang/en_US'"
            # 将 demo/src/routes/+page.svelte 内的 "'../../../packages/stdf/components'"  替换为 "'stdf/lang/en_US'"
            # 将 demo/src/routes/en_US/**/*.svelte 内的 "'../../../../../packages/stdf/components'"  替换为 "'stdf'"
            # 将 demo/src/routes/zh_CN/**/*.svelte 内的 "'../../../../../packages/stdf/components'"  替换为 "'stdf'"
            # 将 demo/src/routes/components/ThemeSwitch.svelte 内的 "'../../../../packages/stdf/theme'" 替换为 "'stdf/theme'"
            # 讲 demo/src/data/themes/index.js 内的 "'../../../../packages/stdf/theme'" 替换为 "'stdf/theme'"
            # 将 demo/tailwind.config.js 内的 "'../packages/stdf/**/*.svelte'"  替换为 "./node_modules/stdf/**/*.svelte'"，注意其中特殊符号的转义
            # 将 demo 目录下的所有文件提交到本地仓库，提交信息为 Github Actions auto commit: update demo from stdf.
            - name: Init stdf demo
              run: |
                  cp stdf/LICENSE stdf/demo/LICENSE
                  cd stdf/demo
                  git init
                  git config --global user.name 'GitHub Actions'
                  git config --global user.email 'GitHub Actions'
                  sed -i 's/"svelte"/"stdf": "^${{ steps.version.outputs.version }}",\n"svelte"/' package.json
                  sed -i 's/"svelte"/\t\t"svelte"/' package.json
                  sed -i 's#file:../packages/rollup-plugin-stdf-icon#^${{ steps.rollup-plugin-stdf-icon-version.outputs.rollup-plugin-stdf-icon-version }}#' package.json
                  sed -i 's#../../../packages/stdf/components#stdf#' src/routes/+layout.svelte
                  sed -i 's#../../../packages/stdf/lang/zh_CN#stdf/lang/zh_CN#' src/routes/+layout.svelte
                  sed -i 's#../../../packages/stdf/lang/en_US#stdf/lang/en_US#' src/routes/+layout.svelte
                  sed -i 's#../../../packages/stdf/components#stdf#' src/routes/+page.svelte
                  sed -i 's#../../../../../packages/stdf/components#stdf#' src/routes/en_US/**/*.svelte
                  sed -i 's#../../../../../packages/stdf/components#stdf#' src/routes/zh_CN/**/*.svelte
                  sed -i 's#../../../../packages/stdf/theme#stdf/theme#' src/routes/components/ThemeSwitch.svelte
                  sed -i 's#../../../../packages/stdf/theme#stdf/theme#' src/data/themes/index.js
                  sed -i 's|'\''../packages/stdf/\*\*/\*.svelte'\''|'\''.\/node_modules\/stdf\/\*\*\/\*.svelte'\''|g' tailwind.config.js
                  git add .
                  git commit -m "Github Actions auto commit: update demo from stdf."

            # 将修改内容推送到 git@github.com:any-tdf/0.x-demo-stdf.git 的 0.x 分支
            - name: Push to 0.x-demo-stdf
              uses: ad-m/github-push-action@master
              with:
                  github_token: ${{ secrets.STDF_GITHUB_TOKEN }}
                  branch: 0.x
                  force: true
                  directory: stdf/demo
                  repository: any-tdf/0.x-demo-stdf



================================================
FILE: .github/workflows/sync-demo.yml
================================================
# 当分支 main 分支有 push 事件，并且此次 push 包含了 packages/stdf 目录下的文件时触发，使用 GitHub Actions 执行

name: SYNC DEMO

on:
    push:
        branches:
            - main
        paths:
            - 'packages/stdf/**'

jobs:
    sync:
        runs-on: ubuntu-latest
        steps:
            - name: Checkout
              uses: actions/checkout@v4

            # clone 仓库 github.com/any-tdf/stdf
            - name: Clone stdf
              uses: actions/checkout@v4
              with:
                  repository: any-tdf/stdf
                  token: ${{ secrets.STDF_GITHUB_TOKEN }}
                  path: stdf

            # 读取 packages/rollup-plugin-stdf-icon 中的 package.json 文件，获取 version 的值并存储到 version 变量中
            - name: Read Icon version
              run: |
                  version=$(cat packages/rollup-plugin-stdf-icon/package.json | grep -E '"version":' | awk -F'"' '{print $4}')
                  echo "version: $version"
                  echo "version=${version}" >> $GITHUB_ENV
            # 初始化 stdf demo 仓库
            # 将 stdf/LICENSE 复制到 stdf/packages/stdf/LICENSE
            # 将 stdf/README.md 复制到 stdf/packages/stdf/README.md
            # 将上一步获取的 version 字段前面增加 ^ 号，将 packages/stdf/package.json 中的 file:../rollup-plugin-stdf-icon 替换为 ^version
            - name: Init stdf demo
              run: |
                  cp stdf/LICENSE stdf/packages/stdf/LICENSE
                  cp stdf/README.md stdf/packages/stdf/README.md
                  sed -i "s|file:../rollup-plugin-stdf-icon|^${version}|g" stdf/packages/stdf/package.json
                  cd stdf/packages/stdf
                  git init
                  git config --global user.name 'GitHub Actions'
                  git config --global user.email 'GitHub Actions'

                  git add .
                  git commit -m "Github Actions auto commit: update demo from stdf."

            # 将修改内容推送到 git@github.com:any-tdf/demo-stdf.git 的 main 分支
            - name: Push to demo-stdf
              uses: ad-m/github-push-action@master
              with:
                  github_token: ${{ secrets.STDF_GITHUB_TOKEN }}
                  branch: main
                  force: true
                  directory: stdf/packages/stdf
                  repository: any-tdf/demo-stdf



================================================
FILE: .github/workflows/sync-gitee.yml
================================================
# 每天 3 点自动将 GitHub 仓库同步到 Gitee

name: SYNC GITEE

on:
  schedule:
    - cron: '0 3 * * *'

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - name: Black list
        uses: Yikun/hub-mirror-action@master
        with:
          src: github/any-tdf
          dst: gitee/dufu1991
          dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
          dst_token: ${{ secrets.GITEE_TOKEN }}
          static_list: 'stdf'


