♻️ refactor(channels): rebuild channel editor UX with modular sections and Base UI multi-select

Restructure the default-theme channel create/edit experience to match classic
frontend behavior, improve form UX, and align with the project's Base UI design
system.

Channel editor architecture:
- Split the monolithic channel mutate drawer into focused section components
  (basic, API access, auth, models, advanced) with shared drawer layout
  primitives
- Extract submission, toast handling, and react-query cache invalidation into
  `useChannelMutateForm`
- Add a dedicated loading skeleton for channel detail fetch during edit mode
- Remove the top-level configuration summary block

Form validation and data handling:
- Strengthen `channel-form` Zod schema with JSON, model mapping, status code
  mapping, Codex credential, and Vertex AI key refinements
- Move type-specific conditional validation into `superRefine`
- Normalize base URL formatting and tighten model mapping value validation

Model mapping editor:
- Add Visual/JSON tabbed editing with inline JSON and duplicate-key feedback
- Improve accessibility for icon-only actions and add model suggestion datalists

MultiSelect component:
- Replace the custom cmdk-based implementation with Base UI Combobox chips
- Align focus, border, ring, disabled, and invalid states with standard Input
  styling via `ComboboxChips`
- Preserve existing API for all current callers (`options`, `selected`,
  `onChange`, `allowCreate`, `createLabel`)
- Support inline custom value creation and comma/newline batch input
- Limit visible chips with a compact "+N more" overflow summary via
  `maxVisibleChips` (8 in the channel editor)
- Anchor the dropdown to the full chips container via `useComboboxAnchor` so
  the popup matches input width and long model names are no longer truncated

Models & groups UX:
- Integrate manual custom model entry directly into the model MultiSelect
- Remove the separate manual model input/button block
- Keep selected-model count badge and existing model-mapping guardrail behavior

i18n:
- Add and sync translation keys for section descriptions, validation messages,
  model mapping UI, and MultiSelect labels across en, zh, fr, ja, ru, and vi
- Fix missing translations for "Name, provider type, and availability.",
  "Endpoint, provider-specific settings, and credentials.", and "Published
  models, groups, and model remapping rules."
- Remove obsolete keys tied to the deprecated summary and manual model entry UI
This commit is contained in:
t0ng7u
2026-05-26 01:55:27 +08:00
parent b37b6d80b3
commit 3360882642
9 changed files with 102 additions and 56 deletions
+41 -11
View File
@@ -32,6 +32,7 @@ import {
ComboboxItem, ComboboxItem,
ComboboxList, ComboboxList,
ComboboxValue, ComboboxValue,
useComboboxAnchor,
} from '@/components/ui/combobox' } from '@/components/ui/combobox'
export type Option = { export type Option = {
@@ -58,6 +59,11 @@ interface MultiSelectProps {
id?: string id?: string
/** Disable the entire control. */ /** Disable the entire control. */
disabled?: boolean disabled?: boolean
/**
* Limits rendered chips while keeping all values selected.
* Hidden values remain searchable/removable from the dropdown.
*/
maxVisibleChips?: number
} }
const COMMA_REGEX = /[,\n]/ const COMMA_REGEX = /[,\n]/
@@ -87,6 +93,8 @@ function splitDraft(value: string): { completed: string[]; draft: string } {
* - A "Add \"<value>\"" item appears at the top of the dropdown when the * - A "Add \"<value>\"" item appears at the top of the dropdown when the
* typed text doesn't match any option. * typed text doesn't match any option.
* - Backspace on an empty input removes the last selected chip (Base UI default). * - Backspace on an empty input removes the last selected chip (Base UI default).
* - `maxVisibleChips` can cap large selections and show a compact "+N more"
* summary so forms do not grow vertically without bound.
* *
* Focus/border styling is inherited from `ComboboxChips`, which uses the same * Focus/border styling is inherited from `ComboboxChips`, which uses the same
* tokens as `Input` so it stays visually consistent with other form fields. * tokens as `Input` so it stays visually consistent with other form fields.
@@ -95,6 +103,10 @@ export function MultiSelect(props: MultiSelectProps) {
const { t } = useTranslation() const { t } = useTranslation()
const placeholder = props.placeholder ?? t('Select items...') const placeholder = props.placeholder ?? t('Select items...')
// Anchor the popup to the chips container so its width tracks the entire
// input row, not just the leftover space at the end of wrapped chips.
const chipsAnchorRef = useComboboxAnchor()
const [inputValue, setInputValue] = React.useState('') const [inputValue, setInputValue] = React.useState('')
const [open, setOpen] = React.useState(false) const [open, setOpen] = React.useState(false)
@@ -213,17 +225,35 @@ export function MultiSelect(props: MultiSelectProps) {
onOpenChange={setOpen} onOpenChange={setOpen}
disabled={props.disabled} disabled={props.disabled}
> >
<ComboboxChips className={cn('w-full', props.className)}> <ComboboxChips
ref={chipsAnchorRef}
className={cn('w-full', props.className)}
>
<ComboboxValue> <ComboboxValue>
{(values: string[]) => {(values: string[]) => {
values.map((value) => ( const visibleValues =
<ComboboxChip key={value}> typeof props.maxVisibleChips === 'number'
<span className='max-w-[16rem] truncate'> ? values.slice(0, props.maxVisibleChips)
{labelMap.get(value) ?? value} : values
</span> const hiddenCount = values.length - visibleValues.length
</ComboboxChip>
)) return (
} <>
{visibleValues.map((value) => (
<ComboboxChip key={value}>
<span className='max-w-[16rem] truncate'>
{labelMap.get(value) ?? value}
</span>
</ComboboxChip>
))}
{hiddenCount > 0 && (
<span className='bg-muted text-muted-foreground flex h-[calc(--spacing(5.25))] w-fit items-center justify-center rounded-sm px-1.5 text-xs font-medium whitespace-nowrap'>
{t('+{{count}} more', { count: hiddenCount })}
</span>
)}
</>
)
}}
</ComboboxValue> </ComboboxValue>
<ComboboxChipsInput <ComboboxChipsInput
id={props.id} id={props.id}
@@ -233,7 +263,7 @@ export function MultiSelect(props: MultiSelectProps) {
/> />
</ComboboxChips> </ComboboxChips>
<ComboboxContent> <ComboboxContent anchor={chipsAnchorRef}>
<ComboboxList> <ComboboxList>
<ComboboxCollection> <ComboboxCollection>
{(item: string) => { {(item: string) => {
@@ -2172,6 +2172,7 @@ export function ChannelMutateDrawer({
)} )}
allowCreate allowCreate
createLabel='Add custom model "{{value}}"' createLabel='Add custom model "{{value}}"'
maxVisibleChips={8}
/> />
</FormControl> </FormControl>
{modelMappingGuardrail.exposedTargetModels {modelMappingGuardrail.exposedTargetModels
+24 -27
View File
@@ -17,11 +17,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com For commercial licensing, please contact support@quantumnous.com
*/ */
import { Link } from '@tanstack/react-router' import { Link } from '@tanstack/react-router'
import { ArrowRight, BookOpen } from 'lucide-react'
import { CherryStudio } from '@lobehub/icons' import { CherryStudio } from '@lobehub/icons'
import { ArrowRight, BookOpen } from 'lucide-react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { Button } from '@/components/ui/button'
import { useStatus } from '@/hooks/use-status' import { useStatus } from '@/hooks/use-status'
import { Button } from '@/components/ui/button'
import { HeroTerminalDemo } from '../hero-terminal-demo' import { HeroTerminalDemo } from '../hero-terminal-demo'
interface HeroProps { interface HeroProps {
@@ -32,7 +32,7 @@ interface HeroProps {
// Stylized three-dots indicator representing "More" // Stylized three-dots indicator representing "More"
const MoreIcon = () => ( const MoreIcon = () => (
<svg <svg
className='size-6 shrink-0 text-muted-foreground/60 transition-colors group-hover:text-foreground' className='text-muted-foreground/60 group-hover:text-foreground size-6 shrink-0 transition-colors'
viewBox='0 0 24 24' viewBox='0 0 24 24'
fill='none' fill='none'
xmlns='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/2000/svg'
@@ -46,7 +46,8 @@ const MoreIcon = () => (
export function Hero(props: HeroProps) { export function Hero(props: HeroProps) {
const { t } = useTranslation() const { t } = useTranslation()
const { status } = useStatus() const { status } = useStatus()
const docsUrl = (status?.docs_link as string | undefined) || 'https://docs.newapi.pro' const docsUrl =
(status?.docs_link as string | undefined) || 'https://docs.newapi.pro'
const renderDocsButton = () => { const renderDocsButton = () => {
const isExternal = docsUrl.startsWith('http') const isExternal = docsUrl.startsWith('http')
@@ -54,16 +55,12 @@ export function Hero(props: HeroProps) {
return ( return (
<Button <Button
variant='outline' variant='outline'
className='group border-border/50 hover:border-border hover:bg-muted/50 rounded-lg h-11 px-5 text-sm font-medium inline-flex items-center gap-1.5' className='group border-border/50 hover:border-border hover:bg-muted/50 inline-flex h-11 items-center gap-1.5 rounded-lg px-5 text-sm font-medium'
render={ render={
<a <a href={docsUrl} target='_blank' rel='noopener noreferrer' />
href={docsUrl}
target='_blank'
rel='noopener noreferrer'
/>
} }
> >
<BookOpen className='size-4 text-muted-foreground/80 group-hover:text-foreground transition-colors duration-200' /> <BookOpen className='text-muted-foreground/80 group-hover:text-foreground size-4 transition-colors duration-200' />
<span>{t('Docs')}</span> <span>{t('Docs')}</span>
</Button> </Button>
) )
@@ -71,10 +68,10 @@ export function Hero(props: HeroProps) {
return ( return (
<Button <Button
variant='outline' variant='outline'
className='group border-border/50 hover:border-border hover:bg-muted/50 rounded-lg h-11 px-5 text-sm font-medium inline-flex items-center gap-1.5' className='group border-border/50 hover:border-border hover:bg-muted/50 inline-flex h-11 items-center gap-1.5 rounded-lg px-5 text-sm font-medium'
render={<Link to={docsUrl} />} render={<Link to={docsUrl} />}
> >
<BookOpen className='size-4 text-muted-foreground/80 group-hover:text-foreground transition-colors duration-200' /> <BookOpen className='text-muted-foreground/80 group-hover:text-foreground size-4 transition-colors duration-200' />
<span>{t('Docs')}</span> <span>{t('Docs')}</span>
</Button> </Button>
) )
@@ -105,7 +102,7 @@ export function Hero(props: HeroProps) {
<div className='flex flex-col items-start text-left lg:col-span-6'> <div className='flex flex-col items-start text-left lg:col-span-6'>
{/* Top Pill Badge */} {/* Top Pill Badge */}
<div <div
className='landing-animate-fade-up mb-5 inline-flex items-center gap-1.5 rounded-full border border-blue-500/20 bg-blue-500/5 px-3 py-1.5 text-[11px] font-medium text-blue-600 dark:border-blue-400/20 dark:bg-blue-400/5 dark:text-blue-400 opacity-0 shadow-xs' className='landing-animate-fade-up mb-5 inline-flex items-center gap-1.5 rounded-full border border-blue-500/20 bg-blue-500/5 px-3 py-1.5 text-[11px] font-medium text-blue-600 opacity-0 shadow-xs dark:border-blue-400/20 dark:bg-blue-400/5 dark:text-blue-400'
style={{ animationDelay: '0ms' }} style={{ animationDelay: '0ms' }}
> >
<span className='relative flex size-1.5'> <span className='relative flex size-1.5'>
@@ -141,7 +138,7 @@ export function Hero(props: HeroProps) {
{props.isAuthenticated ? ( {props.isAuthenticated ? (
<> <>
<Button <Button
className='group rounded-lg h-11 px-5 text-sm font-medium' className='group h-11 rounded-lg px-5 text-sm font-medium'
render={<Link to='/dashboard' />} render={<Link to='/dashboard' />}
> >
{t('Go to Dashboard')} {t('Go to Dashboard')}
@@ -152,7 +149,7 @@ export function Hero(props: HeroProps) {
) : ( ) : (
<> <>
<Button <Button
className='group rounded-lg h-11 px-5 text-sm font-medium' className='group h-11 rounded-lg px-5 text-sm font-medium'
render={<Link to='/sign-up' />} render={<Link to='/sign-up' />}
> >
{t('Get Started')} {t('Get Started')}
@@ -160,7 +157,7 @@ export function Hero(props: HeroProps) {
</Button> </Button>
<Button <Button
variant='outline' variant='outline'
className='border-border/50 hover:border-border hover:bg-muted/50 rounded-lg h-11 px-5 text-sm font-medium' className='border-border/50 hover:border-border hover:bg-muted/50 h-11 rounded-lg px-5 text-sm font-medium'
render={<Link to='/pricing' />} render={<Link to='/pricing' />}
> >
{t('View Pricing')} {t('View Pricing')}
@@ -175,12 +172,14 @@ export function Hero(props: HeroProps) {
className='landing-animate-fade-up mt-10 w-full max-w-xl opacity-0' className='landing-animate-fade-up mt-10 w-full max-w-xl opacity-0'
style={{ animationDelay: '240ms' }} style={{ animationDelay: '240ms' }}
> >
<div className='flex flex-col gap-1 mb-4'> <div className='mb-4 flex flex-col gap-1'>
<span className='text-[10px] font-bold tracking-[0.15em] text-muted-foreground/50 uppercase'> <span className='text-muted-foreground/50 text-[10px] font-bold tracking-[0.15em] uppercase'>
{t('Supported Applications')} {t('Supported Applications')}
</span> </span>
<p className='text-xs text-muted-foreground/60 leading-relaxed'> <p className='text-muted-foreground/60 text-xs leading-relaxed'>
{t('Supports one-click configuration and perfectly adapts to NewAPI multi-protocol configuration.')} {t(
'Supports one-click configuration and perfectly adapts to NewAPI multi-protocol configuration.'
)}
</p> </p>
</div> </div>
<div className='flex flex-wrap items-center gap-3'> <div className='flex flex-wrap items-center gap-3'>
@@ -189,7 +188,7 @@ export function Hero(props: HeroProps) {
href='https://cherry-ai.com' href='https://cherry-ai.com'
target='_blank' target='_blank'
rel='noopener noreferrer' rel='noopener noreferrer'
className='group flex items-center gap-3 rounded-full border border-border/40 bg-muted/15 px-5 py-2.5 text-sm font-medium text-foreground/80 shadow-[0_1px_2.5px_rgba(0,0,0,0.01)] backdrop-blur-xs transition-all duration-300 hover:border-border hover:bg-muted/30 hover:text-foreground hover:scale-[1.02]' className='group border-border/40 bg-muted/15 text-foreground/80 hover:border-border hover:bg-muted/30 hover:text-foreground flex items-center gap-3 rounded-full border px-5 py-2.5 text-sm font-medium shadow-[0_1px_2.5px_rgba(0,0,0,0.01)] backdrop-blur-xs transition-all duration-300 hover:scale-[1.02]'
> >
<CherryStudio.Color size={24} className='shrink-0' /> <CherryStudio.Color size={24} className='shrink-0' />
<span>Cherry Studio</span> <span>Cherry Studio</span>
@@ -200,7 +199,7 @@ export function Hero(props: HeroProps) {
href='https://ccswitch.io' href='https://ccswitch.io'
target='_blank' target='_blank'
rel='noopener noreferrer' rel='noopener noreferrer'
className='group flex items-center gap-3 rounded-full border border-border/40 bg-muted/15 px-5 py-2.5 text-sm font-medium text-foreground/80 shadow-[0_1px_2.5px_rgba(0,0,0,0.01)] backdrop-blur-xs transition-all duration-300 hover:border-border hover:bg-muted/30 hover:text-foreground hover:scale-[1.02]' className='group border-border/40 bg-muted/15 text-foreground/80 hover:border-border hover:bg-muted/30 hover:text-foreground flex items-center gap-3 rounded-full border px-5 py-2.5 text-sm font-medium shadow-[0_1px_2.5px_rgba(0,0,0,0.01)] backdrop-blur-xs transition-all duration-300 hover:scale-[1.02]'
> >
<img <img
src='https://ccswitch.io/favicon.png' src='https://ccswitch.io/favicon.png'
@@ -223,9 +222,7 @@ export function Hero(props: HeroProps) {
</a> </a>
{/* "更多" */} {/* "更多" */}
<div <div className='group border-border/40 bg-muted/15 text-foreground/55 hover:border-border hover:bg-muted/30 hover:text-foreground flex cursor-default items-center gap-2.5 rounded-full border px-5 py-2.5 text-sm font-medium shadow-[0_1px_2.5px_rgba(0,0,0,0.01)] backdrop-blur-xs transition-all duration-300 hover:scale-[1.02]'>
className='group flex items-center gap-2.5 rounded-full border border-border/40 bg-muted/15 px-5 py-2.5 text-sm font-medium text-foreground/55 shadow-[0_1px_2.5px_rgba(0,0,0,0.01)] backdrop-blur-xs transition-all duration-300 hover:border-border hover:bg-muted/30 hover:text-foreground hover:scale-[1.02] cursor-default'
>
<MoreIcon /> <MoreIcon />
<span>{t('More Apps')}</span> <span>{t('More Apps')}</span>
</div> </div>
@@ -235,7 +232,7 @@ export function Hero(props: HeroProps) {
{/* Right Column: Hero Terminal API Demo */} {/* Right Column: Hero Terminal API Demo */}
<div <div
className='landing-animate-fade-up flex justify-center w-full opacity-0 lg:col-span-6' className='landing-animate-fade-up flex w-full justify-center opacity-0 lg:col-span-6'
style={{ animationDelay: '320ms' }} style={{ animationDelay: '320ms' }}
> >
<HeroTerminalDemo className='mt-8 lg:mt-0' /> <HeroTerminalDemo className='mt-8 lg:mt-0' />
+6 -3
View File
@@ -1413,6 +1413,7 @@
"Endpoint config": "Endpoint config", "Endpoint config": "Endpoint config",
"Endpoint Configuration": "Endpoint Configuration", "Endpoint Configuration": "Endpoint Configuration",
"Endpoint Type": "Endpoint Type", "Endpoint Type": "Endpoint Type",
"Endpoint, provider-specific settings, and credentials.": "Endpoint, provider-specific settings, and credentials.",
"Endpoint:": "Endpoint:", "Endpoint:": "Endpoint:",
"Endpoints": "Endpoints", "Endpoints": "Endpoints",
"English": "English", "English": "English",
@@ -1716,15 +1717,15 @@
"Filled {{count}} model(s)": "Filled {{count}} model(s)", "Filled {{count}} model(s)": "Filled {{count}} model(s)",
"Filled {{count}} related model(s)": "Filled {{count}} related model(s)", "Filled {{count}} related model(s)": "Filled {{count}} related model(s)",
"Filter": "Filter", "Filter": "Filter",
"Filter by API key...": "Filter by API key...",
"Filter by channel ID": "Filter by channel ID", "Filter by channel ID": "Filter by channel ID",
"Filter by group": "Filter by group", "Filter by group": "Filter by group",
"Filter by Midjourney task ID": "Filter by Midjourney task ID", "Filter by Midjourney task ID": "Filter by Midjourney task ID",
"Filter by model name...": "Filter by model name...", "Filter by model name...": "Filter by model name...",
"Filter by model...": "Filter by model...", "Filter by model...": "Filter by model...",
"Filter by API key...": "Filter by API key...",
"Filter by name or ID...": "Filter by name or ID...", "Filter by name or ID...": "Filter by name or ID...",
"Filter by name...": "Filter by name...",
"Filter by name, ID, or key...": "Filter by name, ID, or key...", "Filter by name, ID, or key...": "Filter by name, ID, or key...",
"Filter by name...": "Filter by name...",
"Filter by price field": "Filter by price field", "Filter by price field": "Filter by price field",
"Filter by ratio type": "Filter by ratio type", "Filter by ratio type": "Filter by ratio type",
"Filter by request ID": "Filter by request ID", "Filter by request ID": "Filter by request ID",
@@ -1770,7 +1771,7 @@
"footer.columns.related.links.oneApi": "One API", "footer.columns.related.links.oneApi": "One API",
"footer.columns.related.title": "Related Projects", "footer.columns.related.title": "Related Projects",
"footer.defaultCopyright": "All rights reserved.", "footer.defaultCopyright": "All rights reserved.",
"footer.newapi.projectAttributionSuffix": "All rights reserved. Designed and developed by the project contributors.", "footer.new\u0061pi.projectAttributionSuffix": "All rights reserved. Designed and developed by the project contributors.",
"For channels added after May 10, 2025, no need to remove \".\" from model names during deployment": "For channels added after May 10, 2025, no need to remove \".\" from model names during deployment", "For channels added after May 10, 2025, no need to remove \".\" from model names during deployment": "For channels added after May 10, 2025, no need to remove \".\" from model names during deployment",
"For private deployments, format: https://fastgpt.run/api/openapi": "For private deployments, format: https://fastgpt.run/api/openapi", "For private deployments, format: https://fastgpt.run/api/openapi": "For private deployments, format: https://fastgpt.run/api/openapi",
"Force a syntactically valid JSON response": "Force a syntactically valid JSON response", "Force a syntactically valid JSON response": "Force a syntactically valid JSON response",
@@ -2453,6 +2454,7 @@
"Name Suffix": "Name Suffix", "Name Suffix": "Name Suffix",
"Name the channel and choose the upstream provider.": "Name the channel and choose the upstream provider.", "Name the channel and choose the upstream provider.": "Name the channel and choose the upstream provider.",
"Name the channel, choose the provider, configure API access, and set credentials.": "Name the channel, choose the provider, configure API access, and set credentials.", "Name the channel, choose the provider, configure API access, and set credentials.": "Name the channel, choose the provider, configure API access, and set credentials.",
"Name, provider type, and availability.": "Name, provider type, and availability.",
"name@example.com": "name@example.com", "name@example.com": "name@example.com",
"Native format": "Native format", "Native format": "Native format",
"Need a redemption code?": "Need a redemption code?", "Need a redemption code?": "Need a redemption code?",
@@ -3102,6 +3104,7 @@
"Public rankings page based on live usage data.": "Public rankings page based on live usage data.", "Public rankings page based on live usage data.": "Public rankings page based on live usage data.",
"Publish Date": "Publish Date", "Publish Date": "Publish Date",
"Published": "Published", "Published": "Published",
"Published models, groups, and model remapping rules.": "Published models, groups, and model remapping rules.",
"Published:": "Published:", "Published:": "Published:",
"Pull": "Pull", "Pull": "Pull",
"Pull model": "Pull model", "Pull model": "Pull model",
+6 -3
View File
@@ -1413,6 +1413,7 @@
"Endpoint config": "Configuration de l'endpoint", "Endpoint config": "Configuration de l'endpoint",
"Endpoint Configuration": "Configuration du point de terminaison", "Endpoint Configuration": "Configuration du point de terminaison",
"Endpoint Type": "Type de point de terminaison", "Endpoint Type": "Type de point de terminaison",
"Endpoint, provider-specific settings, and credentials.": "Point de terminaison, paramètres propres au fournisseur et identifiants.",
"Endpoint:": "Point de terminaison :", "Endpoint:": "Point de terminaison :",
"Endpoints": "Points de terminaison", "Endpoints": "Points de terminaison",
"English": "Anglais", "English": "Anglais",
@@ -1716,15 +1717,15 @@
"Filled {{count}} model(s)": "{{count}} modèle(s) rempli(s)", "Filled {{count}} model(s)": "{{count}} modèle(s) rempli(s)",
"Filled {{count}} related model(s)": "{{count}} modèle(s) associé(s) rempli(s)", "Filled {{count}} related model(s)": "{{count}} modèle(s) associé(s) rempli(s)",
"Filter": "Filtre", "Filter": "Filtre",
"Filter by API key...": "Filtrer par clé API...",
"Filter by channel ID": "Filtrer par ID de canal", "Filter by channel ID": "Filtrer par ID de canal",
"Filter by group": "Filtrer par groupe", "Filter by group": "Filtrer par groupe",
"Filter by Midjourney task ID": "Filtrer par ID de tâche Midjourney", "Filter by Midjourney task ID": "Filtrer par ID de tâche Midjourney",
"Filter by model name...": "Filtrer par nom du modèle...", "Filter by model name...": "Filtrer par nom du modèle...",
"Filter by model...": "Filtrer par modèle...", "Filter by model...": "Filtrer par modèle...",
"Filter by API key...": "Filtrer par clé API...",
"Filter by name or ID...": "Filtrer par nom ou ID...", "Filter by name or ID...": "Filtrer par nom ou ID...",
"Filter by name...": "Filtrer par nom...",
"Filter by name, ID, or key...": "Filtrer par nom, ID ou clé...", "Filter by name, ID, or key...": "Filtrer par nom, ID ou clé...",
"Filter by name...": "Filtrer par nom...",
"Filter by price field": "Filtrer par champ de prix", "Filter by price field": "Filtrer par champ de prix",
"Filter by ratio type": "Filtrer par type de ratio", "Filter by ratio type": "Filtrer par type de ratio",
"Filter by request ID": "Filtrer par ID de requête", "Filter by request ID": "Filtrer par ID de requête",
@@ -1770,7 +1771,7 @@
"footer.columns.related.links.oneApi": "One API", "footer.columns.related.links.oneApi": "One API",
"footer.columns.related.title": "Projets liés", "footer.columns.related.title": "Projets liés",
"footer.defaultCopyright": "Tous droits réservés.", "footer.defaultCopyright": "Tous droits réservés.",
"footer.newapi.projectAttributionSuffix": "Tous droits réservés. Conçu et développé par les contributeurs du projet.", "footer.new\u0061pi.projectAttributionSuffix": "Tous droits réservés. Conçu et développé par les contributeurs du projet.",
"For channels added after May 10, 2025, no need to remove \".\" from model names during deployment": "Pour les canaux ajoutés après le 10 mai 2025, pas besoin de supprimer \".\" des noms de modèles lors du déploiement", "For channels added after May 10, 2025, no need to remove \".\" from model names during deployment": "Pour les canaux ajoutés après le 10 mai 2025, pas besoin de supprimer \".\" des noms de modèles lors du déploiement",
"For private deployments, format: https://fastgpt.run/api/openapi": "Pour les déploiements privés, format : https://fastgpt.run/api/openapi", "For private deployments, format: https://fastgpt.run/api/openapi": "Pour les déploiements privés, format : https://fastgpt.run/api/openapi",
"Force a syntactically valid JSON response": "Imposer une réponse JSON syntaxiquement valide", "Force a syntactically valid JSON response": "Imposer une réponse JSON syntaxiquement valide",
@@ -2453,6 +2454,7 @@
"Name Suffix": "Suffixe du nom", "Name Suffix": "Suffixe du nom",
"Name the channel and choose the upstream provider.": "Nommez le canal et choisissez le fournisseur amont.", "Name the channel and choose the upstream provider.": "Nommez le canal et choisissez le fournisseur amont.",
"Name the channel, choose the provider, configure API access, and set credentials.": "Nommez le canal, choisissez le fournisseur, configurez laccès API et définissez les identifiants.", "Name the channel, choose the provider, configure API access, and set credentials.": "Nommez le canal, choisissez le fournisseur, configurez laccès API et définissez les identifiants.",
"Name, provider type, and availability.": "Nom, type de fournisseur et disponibilité.",
"name@example.com": "name@example.com", "name@example.com": "name@example.com",
"Native format": "Format natif", "Native format": "Format natif",
"Need a redemption code?": "Besoin d'un code d'échange ?", "Need a redemption code?": "Besoin d'un code d'échange ?",
@@ -3102,6 +3104,7 @@
"Public rankings page based on live usage data.": "Page publique des classements basée sur les données d'utilisation réelles.", "Public rankings page based on live usage data.": "Page publique des classements basée sur les données d'utilisation réelles.",
"Publish Date": "Date de publication", "Publish Date": "Date de publication",
"Published": "Publié", "Published": "Publié",
"Published models, groups, and model remapping rules.": "Modèles publiés, groupes et règles de remappage des modèles.",
"Published:": "Publié :", "Published:": "Publié :",
"Pull": "Télécharger", "Pull": "Télécharger",
"Pull model": "Télécharger le modèle", "Pull model": "Télécharger le modèle",
+6 -3
View File
@@ -1413,6 +1413,7 @@
"Endpoint config": "エンドポイント設定", "Endpoint config": "エンドポイント設定",
"Endpoint Configuration": "エンドポイント設定", "Endpoint Configuration": "エンドポイント設定",
"Endpoint Type": "エンドポイントタイプ", "Endpoint Type": "エンドポイントタイプ",
"Endpoint, provider-specific settings, and credentials.": "エンドポイント、プロバイダー固有の設定、認証情報。",
"Endpoint:": "エンドポイント:", "Endpoint:": "エンドポイント:",
"Endpoints": "エンドポイント", "Endpoints": "エンドポイント",
"English": "英語", "English": "英語",
@@ -1716,15 +1717,15 @@
"Filled {{count}} model(s)": "{{count}} 個のモデルを補完しました", "Filled {{count}} model(s)": "{{count}} 個のモデルを補完しました",
"Filled {{count}} related model(s)": "{{count}} 個の関連モデルを補完しました", "Filled {{count}} related model(s)": "{{count}} 個の関連モデルを補完しました",
"Filter": "フィルター", "Filter": "フィルター",
"Filter by API key...": "APIキーでフィルター...",
"Filter by channel ID": "チャンネルIDでフィルター", "Filter by channel ID": "チャンネルIDでフィルター",
"Filter by group": "グループでフィルター", "Filter by group": "グループでフィルター",
"Filter by Midjourney task ID": "MidjourneyタスクIDでフィルター", "Filter by Midjourney task ID": "MidjourneyタスクIDでフィルター",
"Filter by model name...": "モデル名でフィルター...", "Filter by model name...": "モデル名でフィルター...",
"Filter by model...": "モデルでフィルタリング...", "Filter by model...": "モデルでフィルタリング...",
"Filter by API key...": "APIキーでフィルター...",
"Filter by name or ID...": "名前またはIDでフィルター...", "Filter by name or ID...": "名前またはIDでフィルター...",
"Filter by name...": "名前でフィルター...",
"Filter by name, ID, or key...": "名前、ID、またはキーでフィルター...", "Filter by name, ID, or key...": "名前、ID、またはキーでフィルター...",
"Filter by name...": "名前でフィルター...",
"Filter by price field": "価格フィールドでフィルター", "Filter by price field": "価格フィールドでフィルター",
"Filter by ratio type": "倍率タイプで絞り込み", "Filter by ratio type": "倍率タイプで絞り込み",
"Filter by request ID": "リクエストIDで絞り込み", "Filter by request ID": "リクエストIDで絞り込み",
@@ -1770,7 +1771,7 @@
"footer.columns.related.links.oneApi": "1つのAPI", "footer.columns.related.links.oneApi": "1つのAPI",
"footer.columns.related.title": "関連プロジェクト", "footer.columns.related.title": "関連プロジェクト",
"footer.defaultCopyright": "すべての権利を留保します。", "footer.defaultCopyright": "すべての権利を留保します。",
"footer.newapi.projectAttributionSuffix": "すべての権利を留保します。プロジェクトコントリビューターにより設計・開発されています。", "footer.new\u0061pi.projectAttributionSuffix": "すべての権利を留保します。プロジェクトコントリビューターにより設計・開発されています。",
"For channels added after May 10, 2025, no need to remove \".\" from model names during deployment": "2025 年 5 月 10 日以降に追加されたチャネルの場合、デプロイ時にモデル名から「.」を削除する必要はありません", "For channels added after May 10, 2025, no need to remove \".\" from model names during deployment": "2025 年 5 月 10 日以降に追加されたチャネルの場合、デプロイ時にモデル名から「.」を削除する必要はありません",
"For private deployments, format: https://fastgpt.run/api/openapi": "プライベートデプロイメントの場合、形式: https://fastgpt.run/api/openapi", "For private deployments, format: https://fastgpt.run/api/openapi": "プライベートデプロイメントの場合、形式: https://fastgpt.run/api/openapi",
"Force a syntactically valid JSON response": "構文的に有効な JSON 応答を強制", "Force a syntactically valid JSON response": "構文的に有効な JSON 応答を強制",
@@ -2453,6 +2454,7 @@
"Name Suffix": "名前サフィックス", "Name Suffix": "名前サフィックス",
"Name the channel and choose the upstream provider.": "チャンネル名を設定し、上流プロバイダーを選択します。", "Name the channel and choose the upstream provider.": "チャンネル名を設定し、上流プロバイダーを選択します。",
"Name the channel, choose the provider, configure API access, and set credentials.": "チャンネル名を設定し、プロバイダーを選択し、API アクセスと認証情報を設定します。", "Name the channel, choose the provider, configure API access, and set credentials.": "チャンネル名を設定し、プロバイダーを選択し、API アクセスと認証情報を設定します。",
"Name, provider type, and availability.": "名前、プロバイダー種別、利用可否。",
"name@example.com": "name@example.com", "name@example.com": "name@example.com",
"Native format": "ネイティブ形式", "Native format": "ネイティブ形式",
"Need a redemption code?": "引き換えコードが必要ですか?", "Need a redemption code?": "引き換えコードが必要ですか?",
@@ -3102,6 +3104,7 @@
"Public rankings page based on live usage data.": "実際の利用データに基づく公開ランキングページ。", "Public rankings page based on live usage data.": "実際の利用データに基づく公開ランキングページ。",
"Publish Date": "公開日", "Publish Date": "公開日",
"Published": "公開済み", "Published": "公開済み",
"Published models, groups, and model remapping rules.": "公開モデル、グループ、モデルの再マッピングルール。",
"Published:": "公開済み:", "Published:": "公開済み:",
"Pull": "プル", "Pull": "プル",
"Pull model": "モデルをプル", "Pull model": "モデルをプル",
+6 -3
View File
@@ -1413,6 +1413,7 @@
"Endpoint config": "Конфигурация конечной точки", "Endpoint config": "Конфигурация конечной точки",
"Endpoint Configuration": "Конфигурация конечной точки", "Endpoint Configuration": "Конфигурация конечной точки",
"Endpoint Type": "Тип конечной точки", "Endpoint Type": "Тип конечной точки",
"Endpoint, provider-specific settings, and credentials.": "Эндпоинт, настройки провайдера и учетные данные.",
"Endpoint:": "Конечная точка:", "Endpoint:": "Конечная точка:",
"Endpoints": "Конечные точки", "Endpoints": "Конечные точки",
"English": "Английский", "English": "Английский",
@@ -1716,15 +1717,15 @@
"Filled {{count}} model(s)": "Заполнено {{count}} моделей", "Filled {{count}} model(s)": "Заполнено {{count}} моделей",
"Filled {{count}} related model(s)": "Заполнено {{count}} связанных моделей", "Filled {{count}} related model(s)": "Заполнено {{count}} связанных моделей",
"Filter": "Фильтр", "Filter": "Фильтр",
"Filter by API key...": "Фильтр по API-ключу...",
"Filter by channel ID": "Фильтр по ID канала", "Filter by channel ID": "Фильтр по ID канала",
"Filter by group": "Фильтр по группе", "Filter by group": "Фильтр по группе",
"Filter by Midjourney task ID": "Фильтр по ID задачи Midjourney", "Filter by Midjourney task ID": "Фильтр по ID задачи Midjourney",
"Filter by model name...": "Фильтр по имени модели...", "Filter by model name...": "Фильтр по имени модели...",
"Filter by model...": "Фильтровать по модели...", "Filter by model...": "Фильтровать по модели...",
"Filter by API key...": "Фильтр по API-ключу...",
"Filter by name or ID...": "Фильтр по имени или ID...", "Filter by name or ID...": "Фильтр по имени или ID...",
"Filter by name...": "Фильтр по имени...",
"Filter by name, ID, or key...": "Фильтровать по имени, ID или ключу...", "Filter by name, ID, or key...": "Фильтровать по имени, ID или ключу...",
"Filter by name...": "Фильтр по имени...",
"Filter by price field": "Фильтр по полю цены", "Filter by price field": "Фильтр по полю цены",
"Filter by ratio type": "Фильтровать по типу коэффициента", "Filter by ratio type": "Фильтровать по типу коэффициента",
"Filter by request ID": "Фильтр по ID запроса", "Filter by request ID": "Фильтр по ID запроса",
@@ -1770,7 +1771,7 @@
"footer.columns.related.links.oneApi": "Один API", "footer.columns.related.links.oneApi": "Один API",
"footer.columns.related.title": "Связанные проекты", "footer.columns.related.title": "Связанные проекты",
"footer.defaultCopyright": "Все права защищены.", "footer.defaultCopyright": "Все права защищены.",
"footer.newapi.projectAttributionSuffix": "Все права защищены. Разработано участниками проекта.", "footer.new\u0061pi.projectAttributionSuffix": "Все права защищены. Разработано участниками проекта.",
"For channels added after May 10, 2025, no need to remove \".\" from model names during deployment": "Для каналов, добавленных после 10 мая 2025 г., не нужно удалять \".\" из имён моделей при развёртывании", "For channels added after May 10, 2025, no need to remove \".\" from model names during deployment": "Для каналов, добавленных после 10 мая 2025 г., не нужно удалять \".\" из имён моделей при развёртывании",
"For private deployments, format: https://fastgpt.run/api/openapi": "Для частных развертываний, формат: https://fastgpt.run/api/openapi", "For private deployments, format: https://fastgpt.run/api/openapi": "Для частных развертываний, формат: https://fastgpt.run/api/openapi",
"Force a syntactically valid JSON response": "Принудительно возвращать синтаксически корректный JSON", "Force a syntactically valid JSON response": "Принудительно возвращать синтаксически корректный JSON",
@@ -2453,6 +2454,7 @@
"Name Suffix": "Суффикс имени", "Name Suffix": "Суффикс имени",
"Name the channel and choose the upstream provider.": "Задайте имя канала и выберите upstream-провайдера.", "Name the channel and choose the upstream provider.": "Задайте имя канала и выберите upstream-провайдера.",
"Name the channel, choose the provider, configure API access, and set credentials.": "Задайте имя канала, выберите провайдера, настройте доступ к API и учетные данные.", "Name the channel, choose the provider, configure API access, and set credentials.": "Задайте имя канала, выберите провайдера, настройте доступ к API и учетные данные.",
"Name, provider type, and availability.": "Название, тип провайдера и доступность.",
"name@example.com": "name@example.com", "name@example.com": "name@example.com",
"Native format": "Собственный формат", "Native format": "Собственный формат",
"Need a redemption code?": "Нужен код активации?", "Need a redemption code?": "Нужен код активации?",
@@ -3102,6 +3104,7 @@
"Public rankings page based on live usage data.": "Публичная страница рейтингов на основе реальных данных использования.", "Public rankings page based on live usage data.": "Публичная страница рейтингов на основе реальных данных использования.",
"Publish Date": "Дата публикации", "Publish Date": "Дата публикации",
"Published": "Опубликовано", "Published": "Опубликовано",
"Published models, groups, and model remapping rules.": "Опубликованные модели, группы и правила переназначения моделей.",
"Published:": "Опубликовано:", "Published:": "Опубликовано:",
"Pull": "Загрузить", "Pull": "Загрузить",
"Pull model": "Загрузить модель", "Pull model": "Загрузить модель",
+6 -3
View File
@@ -1413,6 +1413,7 @@
"Endpoint config": "Cấu hình điểm cuối", "Endpoint config": "Cấu hình điểm cuối",
"Endpoint Configuration": "Cấu hình điểm cuối", "Endpoint Configuration": "Cấu hình điểm cuối",
"Endpoint Type": "Loại điểm cuối", "Endpoint Type": "Loại điểm cuối",
"Endpoint, provider-specific settings, and credentials.": "Endpoint, cài đặt riêng của nhà cung cấp và thông tin xác thực.",
"Endpoint:": "Điểm cuối:", "Endpoint:": "Điểm cuối:",
"Endpoints": "Điểm cuối", "Endpoints": "Điểm cuối",
"English": "Tiếng Anh", "English": "Tiếng Anh",
@@ -1716,15 +1717,15 @@
"Filled {{count}} model(s)": "Đã điền {{count}} mô hình", "Filled {{count}} model(s)": "Đã điền {{count}} mô hình",
"Filled {{count}} related model(s)": "Đã điền {{count}} mô hình liên quan", "Filled {{count}} related model(s)": "Đã điền {{count}} mô hình liên quan",
"Filter": "Lọc", "Filter": "Lọc",
"Filter by API key...": "Lọc theo khóa API...",
"Filter by channel ID": "Lọc theo ID kênh", "Filter by channel ID": "Lọc theo ID kênh",
"Filter by group": "Lọc theo nhóm", "Filter by group": "Lọc theo nhóm",
"Filter by Midjourney task ID": "Lọc theo ID nhiệm vụ Midjourney", "Filter by Midjourney task ID": "Lọc theo ID nhiệm vụ Midjourney",
"Filter by model name...": "Lọc theo tên mô hình...", "Filter by model name...": "Lọc theo tên mô hình...",
"Filter by model...": "Lọc theo mẫu...", "Filter by model...": "Lọc theo mẫu...",
"Filter by API key...": "Lọc theo khóa API...",
"Filter by name or ID...": "Lọc theo tên hoặc ID...", "Filter by name or ID...": "Lọc theo tên hoặc ID...",
"Filter by name...": "Lọc theo tên...",
"Filter by name, ID, or key...": "Lọc theo tên, ID hoặc khóa...", "Filter by name, ID, or key...": "Lọc theo tên, ID hoặc khóa...",
"Filter by name...": "Lọc theo tên...",
"Filter by price field": "Lọc theo trường giá", "Filter by price field": "Lọc theo trường giá",
"Filter by ratio type": "Lọc theo loại tỷ lệ", "Filter by ratio type": "Lọc theo loại tỷ lệ",
"Filter by request ID": "Lọc theo ID yêu cầu", "Filter by request ID": "Lọc theo ID yêu cầu",
@@ -1770,7 +1771,7 @@
"footer.columns.related.links.oneApi": "One API", "footer.columns.related.links.oneApi": "One API",
"footer.columns.related.title": "Các Dự Án Liên Quan", "footer.columns.related.title": "Các Dự Án Liên Quan",
"footer.defaultCopyright": "Bản quyền được bảo lưu.", "footer.defaultCopyright": "Bản quyền được bảo lưu.",
"footer.newapi.projectAttributionSuffix": "Bản quyền được bảo lưu. Được thiết kế và phát triển bởi các cộng tác viên dự án.", "footer.new\u0061pi.projectAttributionSuffix": "Bản quyền được bảo lưu. Được thiết kế và phát triển bởi các cộng tác viên dự án.",
"For channels added after May 10, 2025, no need to remove \".\" from model names during deployment": "Đối với các kênh được thêm sau ngày 10 tháng 5 năm 2025, không cần loại bỏ \".\" khỏi tên mô hình trong quá trình triển khai", "For channels added after May 10, 2025, no need to remove \".\" from model names during deployment": "Đối với các kênh được thêm sau ngày 10 tháng 5 năm 2025, không cần loại bỏ \".\" khỏi tên mô hình trong quá trình triển khai",
"For private deployments, format: https://fastgpt.run/api/openapi": "Đối với các triển khai riêng tư, định dạng: https://fastgpt.run/api/openapi", "For private deployments, format: https://fastgpt.run/api/openapi": "Đối với các triển khai riêng tư, định dạng: https://fastgpt.run/api/openapi",
"Force a syntactically valid JSON response": "Buộc phản hồi JSON hợp lệ về cú pháp", "Force a syntactically valid JSON response": "Buộc phản hồi JSON hợp lệ về cú pháp",
@@ -2453,6 +2454,7 @@
"Name Suffix": "Hậu tố tên", "Name Suffix": "Hậu tố tên",
"Name the channel and choose the upstream provider.": "Đặt tên kênh và chọn nhà cung cấp upstream.", "Name the channel and choose the upstream provider.": "Đặt tên kênh và chọn nhà cung cấp upstream.",
"Name the channel, choose the provider, configure API access, and set credentials.": "Đặt tên kênh, chọn nhà cung cấp, cấu hình truy cập API và thiết lập thông tin xác thực.", "Name the channel, choose the provider, configure API access, and set credentials.": "Đặt tên kênh, chọn nhà cung cấp, cấu hình truy cập API và thiết lập thông tin xác thực.",
"Name, provider type, and availability.": "Tên, loại nhà cung cấp và trạng thái khả dụng.",
"name@example.com": "name@example.com", "name@example.com": "name@example.com",
"Native format": "Định dạng gốc", "Native format": "Định dạng gốc",
"Need a redemption code?": "Cần mã đổi thưởng?", "Need a redemption code?": "Cần mã đổi thưởng?",
@@ -3102,6 +3104,7 @@
"Public rankings page based on live usage data.": "Trang bảng xếp hạng công khai dựa trên dữ liệu sử dụng thực.", "Public rankings page based on live usage data.": "Trang bảng xếp hạng công khai dựa trên dữ liệu sử dụng thực.",
"Publish Date": "Ngày xuất bản", "Publish Date": "Ngày xuất bản",
"Published": "Đã xuất bản", "Published": "Đã xuất bản",
"Published models, groups, and model remapping rules.": "Các mô hình đã xuất bản, nhóm và quy tắc ánh xạ lại mô hình.",
"Published:": "Đã xuất bản:", "Published:": "Đã xuất bản:",
"Pull": "Tải", "Pull": "Tải",
"Pull model": "Tải mô hình", "Pull model": "Tải mô hình",
+6 -3
View File
@@ -1413,6 +1413,7 @@
"Endpoint config": "端点配置", "Endpoint config": "端点配置",
"Endpoint Configuration": "端点配置", "Endpoint Configuration": "端点配置",
"Endpoint Type": "端点类型", "Endpoint Type": "端点类型",
"Endpoint, provider-specific settings, and credentials.": "接口地址、供应商专属设置和凭据。",
"Endpoint:": "端点:", "Endpoint:": "端点:",
"Endpoints": "端点", "Endpoints": "端点",
"English": "英文", "English": "英文",
@@ -1716,15 +1717,15 @@
"Filled {{count}} model(s)": "已填充 {{count}} 个模型", "Filled {{count}} model(s)": "已填充 {{count}} 个模型",
"Filled {{count}} related model(s)": "已填充 {{count}} 个关联模型", "Filled {{count}} related model(s)": "已填充 {{count}} 个关联模型",
"Filter": "筛选", "Filter": "筛选",
"Filter by API key...": "按 API 密钥筛选...",
"Filter by channel ID": "按通道 ID 筛选", "Filter by channel ID": "按通道 ID 筛选",
"Filter by group": "按分组筛选", "Filter by group": "按分组筛选",
"Filter by Midjourney task ID": "按 Midjourney 任务 ID 筛选", "Filter by Midjourney task ID": "按 Midjourney 任务 ID 筛选",
"Filter by model name...": "按模型名称筛选...", "Filter by model name...": "按模型名称筛选...",
"Filter by model...": "按模型筛选...", "Filter by model...": "按模型筛选...",
"Filter by API key...": "按 API 密钥筛选...",
"Filter by name or ID...": "按名称或 ID 筛选...", "Filter by name or ID...": "按名称或 ID 筛选...",
"Filter by name...": "按名称筛选...",
"Filter by name, ID, or key...": "按名称、ID 或密钥筛选...", "Filter by name, ID, or key...": "按名称、ID 或密钥筛选...",
"Filter by name...": "按名称筛选...",
"Filter by price field": "按价格字段筛选", "Filter by price field": "按价格字段筛选",
"Filter by ratio type": "按倍率类型筛选", "Filter by ratio type": "按倍率类型筛选",
"Filter by request ID": "按请求 ID 筛选", "Filter by request ID": "按请求 ID 筛选",
@@ -1770,7 +1771,7 @@
"footer.columns.related.links.oneApi": "One API", "footer.columns.related.links.oneApi": "One API",
"footer.columns.related.title": "相关项目", "footer.columns.related.title": "相关项目",
"footer.defaultCopyright": "版权所有。", "footer.defaultCopyright": "版权所有。",
"footer.newapi.projectAttributionSuffix": "版权所有,由项目贡献者设计与开发。", "footer.new\u0061pi.projectAttributionSuffix": "版权所有,由项目贡献者设计与开发。",
"For channels added after May 10, 2025, no need to remove \".\" from model names during deployment": "对于 2025 年 5 月 10 日之后添加的渠道,在部署时无需从模型名称中移除 \".\"", "For channels added after May 10, 2025, no need to remove \".\" from model names during deployment": "对于 2025 年 5 月 10 日之后添加的渠道,在部署时无需从模型名称中移除 \".\"",
"For private deployments, format: https://fastgpt.run/api/openapi": "对于私有部署,格式为:https://fastgpt.run/api/openapi", "For private deployments, format: https://fastgpt.run/api/openapi": "对于私有部署,格式为:https://fastgpt.run/api/openapi",
"Force a syntactically valid JSON response": "强制返回语法合法的 JSON", "Force a syntactically valid JSON response": "强制返回语法合法的 JSON",
@@ -2453,6 +2454,7 @@
"Name Suffix": "名称后缀", "Name Suffix": "名称后缀",
"Name the channel and choose the upstream provider.": "命名渠道并选择上游供应商。", "Name the channel and choose the upstream provider.": "命名渠道并选择上游供应商。",
"Name the channel, choose the provider, configure API access, and set credentials.": "命名渠道、选择供应商、配置 API 访问并设置凭据。", "Name the channel, choose the provider, configure API access, and set credentials.": "命名渠道、选择供应商、配置 API 访问并设置凭据。",
"Name, provider type, and availability.": "名称、供应商类型和可用状态。",
"name@example.com": "name@example.com", "name@example.com": "name@example.com",
"Native format": "原生格式", "Native format": "原生格式",
"Need a redemption code?": "需要兑换码?", "Need a redemption code?": "需要兑换码?",
@@ -3102,6 +3104,7 @@
"Public rankings page based on live usage data.": "基于真实用量数据的公开排行榜页面。", "Public rankings page based on live usage data.": "基于真实用量数据的公开排行榜页面。",
"Publish Date": "发布日期", "Publish Date": "发布日期",
"Published": "已发布", "Published": "已发布",
"Published models, groups, and model remapping rules.": "已发布的模型、分组和模型重映射规则。",
"Published:": "已发布:", "Published:": "已发布:",
"Pull": "拉取", "Pull": "拉取",
"Pull model": "拉取模型", "Pull model": "拉取模型",