feat(plugins): localize optional feature previews
This commit is contained in:
1 parent
fb752c7763
commit
37dbd15e0c
31 files changed
+220
-48
No files matched your search
@@ -705,6 +705,18 @@ describe('web e2e: plugin manager', () => {
|
||||
expect(fits).toBe(true)
|
||||
await compareOrRefreshGolden(join(SNAPSHOT_DIR, 'preview.expected.md'),
|
||||
await captureStableAria(page, '[data-plugin-panel]', scaffold.workspaceCwd), MODE)
|
||||
const chineseSource = await preview.getAttribute('src')
|
||||
try {
|
||||
await setLanguage('en')
|
||||
const englishPreview = detail.getByRole('img', { name: 'DSH badge skill feature preview', exact: true })
|
||||
await englishPreview.waitFor()
|
||||
await englishPreview.evaluate(async (image: HTMLImageElement) => { await image.decode() })
|
||||
expect(await englishPreview.evaluate((image: HTMLImageElement) => image.naturalWidth)).toBe(640)
|
||||
expect(await englishPreview.getAttribute('src')).not.toBe(chineseSource)
|
||||
} finally {
|
||||
await setLanguage('zh')
|
||||
}
|
||||
expect(await preview.getAttribute('src')).toBe(chineseSource)
|
||||
await panel.getByRole('button', { name: '返回 实验性插件', exact: true }).click()
|
||||
await panel.getByRole('button', { name: '查看 智能体团队', exact: true }).click()
|
||||
expect(await panel.getByRole('img').count()).toBe(0)
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
en: 0894bd9f35430753
|
||||
zh: 2d28090e71134edd
|
||||
/cookbook-adding-a-workspace-package/5-add-optional-plugin-display-metadata:
|
||||
en: 80c93d1bf8215864
|
||||
zh: 846a02590c73b0af
|
||||
en: fa5fab4d94ca22d4
|
||||
zh: 969d5979850c94b0
|
||||
/cookbook-adding-a-workspace-package/6-verify:
|
||||
en: 80c7fb90b1175aae
|
||||
zh: 2ba37962dbc57299
|
||||
@@ -147,7 +147,7 @@ Export `<package name>/locale/en.json` for locale lookup; expose `<package name>
|
||||
|
||||
For an image on bundle cards, details, and component rows, a package-root plugin sets top-level `"icon": "./icon.svg"` in its exported manifest, or exports `./icon` when that field is omitted. A subpath plugin exports its own icon, such as `"./search/icon": "./search.svg"`. Include each image in `files`. A manifest `icon` is relative to the manifest's directory; absolute paths, URLs, paths outside that directory, and symlinks resolving outside it are rejected. An exported icon resolves through Node exports like locale resources and must remain inside its package. SVG, PNG, JPEG (`.jpg`/`.jpeg`), and WebP files are supported up to 256 KiB. Images must be self-contained; SVG is rendered as an image, not inline HTML. The Host returns a data URL without activating the plugin. Invalid declarations or unreadable files produce a metadata diagnostic while retaining valid text, without trying the export; missing or undecodable images use the panel's default artwork.
|
||||
|
||||
Optionally add `"preview": "./preview.svg"` to the same manifest for a larger feature image on bundle details, or export `./preview` when the field is absent. Include the file in `files`. It accepts the same formats and path restrictions as `icon`, up to 1 MiB; use a self-contained SVG or an optimized screenshot. It is read without activation. Omission leaves the detail layout unchanged; a bad preview preserves other metadata and management actions. There is no requirement to provide an image.
|
||||
Optionally add `"preview": "./preview.svg"` to the same manifest for a larger feature image on bundle details, or export `./preview` when the field is absent. For artwork containing text, use a language map such as `"preview": { "en": "./preview.svg", "zh": "./preview.zh.svg" }`; English is required as the fallback, and the UI selects an image through its existing locale resolver. Include every image in `files`. The formats and path restrictions match `icon`, with a 1 MiB total limit across variants; use self-contained SVGs or optimized screenshots. Reading requires no activation. Omission leaves the detail layout unchanged; a bad preview preserves other metadata and management actions. Images remain optional.
|
||||
|
||||
Installed bundle cards and details, component lists and configuration details, and Settings' plugin inventory display this metadata, including disabled and preset plugins. Reads do not activate plugins.
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ Append-only, prefix-stable, replacing, or independent behavior, including the ex
|
||||
|
||||
要在组合包卡片、详情和组件行显示图片,包根插件在导出清单顶层设置 `"icon": "./icon.svg"`,或在省略该字段时导出 `./icon`。子路径插件导出自己的图标,例如 `"./search/icon": "./search.svg"`。将每张图片加入 `files`。清单 `icon` 相对于清单所在目录;绝对路径、URL、目录外路径,以及解析到目录外的符号链接均被拒绝。导出的图标像 locale 资源一样经 Node exports 解析,且必须位于所属包内。支持不超过 256 KiB 的 SVG、PNG、JPEG(`.jpg`/`.jpeg`)和 WebP 文件。图片必须自包含;SVG 作为图片渲染,不作为内联 HTML。Host 返回 data URL,不激活插件。声明无效或文件不可读时,显示元信息诊断并保留有效文本,不再尝试导出的图标;图片缺失或无法解码时使用面板的默认插画。
|
||||
|
||||
需要在组合包详情展示较大的功能配图时,可在同一清单中添加 `"preview": "./preview.svg"`,或在省略字段时导出 `./preview`,并将文件加入 `files`。格式和路径限制与 `icon` 相同,上限为 1 MiB;使用自包含 SVG 或优化后的截图,读取时无需激活插件。省略配图不改变详情布局;配图错误不影响其他元信息和管理操作。插件不必提供配图。
|
||||
需要在组合包详情展示较大的功能配图时,可在同一清单中添加 `"preview": "./preview.svg"`,或在省略字段时导出 `./preview`。含文字的配图可使用语言映射,如 `"preview": { "en": "./preview.svg", "zh": "./preview.zh.svg" }`;必须提供英文回退,界面通过现有语言解析器选择图片。将每张图片加入 `files`。格式和路径限制与 `icon` 相同,各语言图片合计上限为 1 MiB;使用自包含 SVG 或优化后的截图,读取时无需激活插件。省略配图不改变详情布局;配图错误不影响其他元信息和管理操作。插件不必提供配图。
|
||||
|
||||
已安装 bundle 的卡片和详情、组件列表与配置详情、设置中的插件清单都展示这些元信息,包括禁用插件和预设内插件。读取时不激活插件。
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
en: c4a301652b851ce9
|
||||
zh: 784871e19cd9db0a
|
||||
/deepseek-ai-dsh-app-boot/use-this-package/reading-plugin-display-metadata:
|
||||
en: e3a731622b9acdd2
|
||||
zh: c60284a12a17cd92
|
||||
en: fc096cfd8722ec02
|
||||
zh: 2fdd2e8ae66768a5
|
||||
/deepseek-ai-dsh-app-boot/use-this-package/startup-and-reload-failures:
|
||||
en: dc13dfa1f79292e4
|
||||
zh: d51682ced7a18ac2
|
||||
|
||||
@@ -88,7 +88,7 @@ Use `readPluginMeta(specifier, parentURL)` or `ctx.pluginPackages.metaOf(specifi
|
||||
|
||||
`ON_DEMAND_BUNDLES` names the public Official packages installed only on request. `OFFICIAL_ON_DEMAND_CATALOG` embeds their package-owned localized metadata and icons for offline discovery; `pnpm gen-official-bundle-catalog` explicitly updates generated content, and `verify-official-bundle-catalog` checks resource completeness and freshness; builds consume the committed catalog without importing provider code. The catalog contains no install target: [Plugin Manager](../plugin-manager/README.md#use-this-package) derives it from the running version and installation and uses the ordinary bundle installer. The [product-use check](../../../scripts/verify-product-use.ts) composes shipped and on-demand selections against Web without executing providers.
|
||||
|
||||
The optional `preview` field follows the same package resource lookup and confinement as `icon`, with a 1 MiB limit. Each image is read independently: a preview failure retains valid text and the icon, and an icon failure retains a valid preview. Neither image requires plugin activation.
|
||||
The optional `preview` field follows the same package resource lookup and confinement as `icon`. A manifest may provide one path or a language-to-path map with a required English fallback; all variants together are limited to 1 MiB. Each image field is read independently: an invalid preview retains valid text and the icon, and an invalid icon retains a valid preview. Neither image requires plugin activation.
|
||||
|
||||
<a id="startup-and-reload-failures"></a>
|
||||
### Startup and reload failures
|
||||
|
||||
@@ -88,7 +88,7 @@ profile 导入插件前,DSH 会检查其 `peerDependencies` 中对 `@deepseek-
|
||||
|
||||
`ON_DEMAND_BUNDLES` 列出仅按需安装的官方公开包。`OFFICIAL_ON_DEMAND_CATALOG` 内嵌这些包拥有的本地化元信息和图标,支持离线发现;`pnpm gen-official-bundle-catalog` 显式更新生成内容,`verify-official-bundle-catalog` 检查资源完整性与新鲜度;构建只读取已提交的目录,不导入提供者代码。目录不保存安装目标;[插件管理器](../plugin-manager/README.zh.md#use-this-package)根据当前版本和安装位置确定目标,并使用普通组合包安装器。[产品用途检查](../../../scripts/verify-product-use.ts)将随附和按需选择与 Web 组合,但不执行提供者。
|
||||
|
||||
可选的 `preview` 字段沿用 `icon` 的包资源查询和路径限制,上限为 1 MiB。每张图片独立读取:配图出错时保留有效文本与图标,图标出错时保留有效配图。读取两类图片均无需激活插件。
|
||||
可选的 `preview` 字段沿用 `icon` 的包资源查询和路径限制。清单可提供单一路径或包含英文回退的语言路径映射,各语言图片合计上限为 1 MiB。每个图片字段独立读取:配图出错时保留有效文本与图标,图标出错时保留有效配图。读取两类图片均无需激活插件。
|
||||
|
||||
<a id="startup-and-reload-failures"></a>
|
||||
### 启动与重载失败
|
||||
|
||||
@@ -20,6 +20,13 @@ const IMAGE_MEDIA_TYPES = new Map([
|
||||
['.jpeg', 'image/jpeg'], ['.webp', 'image/webp'],
|
||||
])
|
||||
|
||||
// A declared image resolves or throws; only an absent optional export returns undefined.
|
||||
function imageOf(
|
||||
field: ImageField, specifier: string, packageName: string, parentURL: string, manifestPath: string, value: string,
|
||||
): string
|
||||
function imageOf(
|
||||
field: ImageField, specifier: string, packageName: string, parentURL: string, manifestPath: string | undefined, value: unknown,
|
||||
): string | undefined
|
||||
function imageOf(
|
||||
field: ImageField, specifier: string, packageName: string, parentURL: string, manifestPath: string | undefined, value: unknown,
|
||||
): string | undefined {
|
||||
@@ -55,6 +62,30 @@ function imageOf(
|
||||
return `data:${mediaType};base64,${bytes.toString('base64')}`
|
||||
}
|
||||
|
||||
/** A translated preview shares the text resolver's language keys and English fallback. */
|
||||
function previewOf(
|
||||
specifier: string, packageName: string, parentURL: string, manifestPath: string | undefined, value: unknown,
|
||||
): LocalizedText | undefined {
|
||||
if (manifestPath === undefined || typeof value !== 'object' || value === null || Array.isArray(value)) {
|
||||
return imageOf('preview', specifier, packageName, parentURL, manifestPath, value)
|
||||
}
|
||||
const translations = new Map<string, string>()
|
||||
let bytes = 0
|
||||
for (const [language, path] of Object.entries(value)) {
|
||||
if (!LANGUAGE_ID.test(language)) throw new Error(`${manifestPath}: preview key ${language} must be a language id`)
|
||||
const id = language.toLowerCase()
|
||||
if (translations.has(id)) throw new Error(`${manifestPath}: preview duplicates locale ${id}`)
|
||||
if (typeof path !== 'string' || path.trim() === '') throw new Error(`${manifestPath}: preview.${language} must be a non-empty string`)
|
||||
const image = imageOf('preview', specifier, packageName, parentURL, manifestPath, path)
|
||||
bytes += Buffer.byteLength(image.slice(image.indexOf(',') + 1), 'base64')
|
||||
if (bytes > IMAGE_LIMIT_KIB.preview * 1024) throw new Error(`${manifestPath}: localized previews exceed 1024 KiB in total`)
|
||||
translations.set(id, image)
|
||||
}
|
||||
const en = translations.get('en')
|
||||
if (en === undefined) throw new Error(`${manifestPath}: preview translations require an English (en) image`)
|
||||
return { ...Object.fromEntries(translations), en }
|
||||
}
|
||||
|
||||
/** Require an ancestor of the real file whose package.json names the owning package. */
|
||||
function assertPackageOwned(file: string, name: string, field: ImageField): void {
|
||||
for (let directory = dirname(file); ; directory = dirname(directory)) {
|
||||
@@ -163,7 +194,8 @@ function localizedText(
|
||||
* A subpath specifier never reads package.json; its images come only from `<specifier>/icon` or `/preview`.
|
||||
* Manifest images remain inside their declaring directory; exported images remain inside their
|
||||
* owning package after realpath resolution. SVG, PNG, JPEG, and WebP are accepted, up to 256 KiB
|
||||
* for icons and 1 MiB for previews. Each image failure retains the other fields without falling back.
|
||||
* for icons and 1 MiB total for previews. A manifest preview may map language ids to paths with
|
||||
* an English fallback. Each image field failure retains the other fields without falling back.
|
||||
* Non-package specifiers are skipped without invoking the resource resolver.
|
||||
* Language files share the directory containing the resolved English resource;
|
||||
* each file is resolved through the complete plugin specifier before reading.
|
||||
@@ -187,12 +219,17 @@ export function readPluginMeta(specifier: string, parentURL: string): PluginLoca
|
||||
...title === undefined ? {} : { title },
|
||||
...description === undefined ? {} : { description },
|
||||
}
|
||||
const images: Partial<Record<ImageField, string>> = {}
|
||||
const images: { icon?: string; preview?: LocalizedText } = {}
|
||||
const errors: string[] = []
|
||||
for (const field of ['icon', 'preview'] as const) {
|
||||
try {
|
||||
const image = imageOf(field, specifier, packageName, parentURL, manifestPath, manifest?.[field])
|
||||
if (image !== undefined) images[field] = image
|
||||
if (field === 'icon') {
|
||||
const image = imageOf(field, specifier, packageName, parentURL, manifestPath, manifest?.icon)
|
||||
if (image !== undefined) images.icon = image
|
||||
} else {
|
||||
const image = previewOf(specifier, packageName, parentURL, manifestPath, manifest?.preview)
|
||||
if (image !== undefined) images.preview = image
|
||||
}
|
||||
} catch (error) {
|
||||
errors.push(`Plugin metadata for ${specifier}: ${String(error)}`)
|
||||
}
|
||||
|
||||
@@ -391,6 +391,48 @@ describe('plugin locale display metadata', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('reads localized preview paths without evaluating the plugin and normalizes language keys', () => {
|
||||
manifest({ '.': './index.js', './package.json': './package.json' }, {
|
||||
preview: { en: './preview.svg', 'ZH-CN': './preview.zh.svg' },
|
||||
})
|
||||
file(join(dir, 'preview.svg'), '<svg>English</svg>')
|
||||
file(join(dir, 'preview.zh.svg'), '<svg>中文</svg>')
|
||||
expect(readPluginMeta('localized', parentURL)?.preview).toEqual({
|
||||
en: `data:image/svg+xml;base64,${Buffer.from('<svg>English</svg>').toString('base64')}`,
|
||||
'zh-cn': `data:image/svg+xml;base64,${Buffer.from('<svg>中文</svg>').toString('base64')}`,
|
||||
})
|
||||
})
|
||||
|
||||
it.each([
|
||||
[{ zh: './preview.svg' }, 'require an English'],
|
||||
[{ en: './preview.svg', EN: './preview.svg' }, 'duplicates locale en'],
|
||||
[{ en: './preview.svg', zh_CN: './preview.svg' }, 'must be a language id'],
|
||||
[{ en: './preview.svg', zh: '' }, 'must be a non-empty string'],
|
||||
[{ en: './preview.svg', zh: '../outside.svg' }, 'inside its manifest directory'],
|
||||
[{ en: './preview.svg', zh: 'https://example.test/preview.svg' }, 'relative file path'],
|
||||
])('keeps other metadata when localized previews are invalid: %j', (preview, diagnostic) => {
|
||||
manifest({ './package.json': './package.json' }, { icon: './icon.svg', preview })
|
||||
file(join(dir, 'icon.svg'), '<svg/>')
|
||||
file(join(dir, 'preview.svg'), '<svg/>')
|
||||
file(join(dir, '../outside.svg'), '<svg/>')
|
||||
const meta = readPluginMeta('localized', parentURL)
|
||||
expect(meta?.preview).toBeUndefined()
|
||||
expect(meta?.icon).toBeDefined()
|
||||
expect(meta?.title).toBe('localized')
|
||||
expect(meta?.error).toContain(diagnostic)
|
||||
})
|
||||
|
||||
it('bounds the combined size of localized previews at 1 MiB', () => {
|
||||
manifest({ './package.json': './package.json' }, { preview: { en: './en.png', zh: './zh.png' } })
|
||||
writeFileSync(join(dir, 'en.png'), Buffer.alloc(512 * 1024))
|
||||
writeFileSync(join(dir, 'zh.png'), Buffer.alloc(512 * 1024))
|
||||
expect(readPluginMeta('localized', parentURL)?.preview).toBeDefined()
|
||||
writeFileSync(join(dir, 'zh.png'), Buffer.alloc(512 * 1024 + 1))
|
||||
const meta = readPluginMeta('localized', parentURL)
|
||||
expect(meta?.preview).toBeUndefined()
|
||||
expect(meta?.error).toContain('localized previews exceed 1024 KiB in total')
|
||||
})
|
||||
|
||||
it('reads a subpath preview independently of root artwork', () => {
|
||||
manifest({ './preview': './root.svg', './search/preview': './search.webp' })
|
||||
file(join(dir, 'root.svg'), 'root')
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
en: e9da90f03691101b
|
||||
zh: 902cda935a4ce3c8
|
||||
/deepseek-ai-dsh-client-ui-plugin-manager/use-this-package/detail-page-extension-points:
|
||||
en: 8319b9e4028844a4
|
||||
zh: 5266a572fdfbbed6
|
||||
en: 61098791b28e2777
|
||||
zh: 391369947303ca83
|
||||
/deepseek-ai-dsh-client-ui-plugin-manager/understand-the-implementation:
|
||||
en: 203168fc87e939bd
|
||||
zh: 72d0ccd2c54f3f44
|
||||
|
||||
@@ -96,7 +96,7 @@ ctx.slots.inject('plugins.detail.section', () => ctx.slots.register({
|
||||
|
||||
A row's page exists only while a `plugins.row.config` entry names the row, so a contribution meant for a row renders on the page that configuration opens.
|
||||
|
||||
Bundle details display an optional package-owned feature preview below the description, including before activation. No preview means no image or reserved space; a decode failure shows a localized message without blocking configuration or enablement. Cards and component rows keep their small icons.
|
||||
Bundle details display an optional package-owned feature preview below the description, including before activation. Translated artwork follows the UI language through the existing locale resolver, with English as the fallback. No preview means no image or reserved space; a decode failure shows a localized message without blocking configuration or enablement. Cards and component rows keep their small icons.
|
||||
|
||||
-----
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ ctx.slots.inject('plugins.detail.section', () => ctx.slots.register({
|
||||
|
||||
行页只在某个 `plugins.row.config` 条目点名这一行时存在,因此给行的贡献渲染在该配置打开的页面上。
|
||||
|
||||
组合包详情在描述下方展示可选的包内功能配图,未启用时也可查看。没有配图就不显示图片或预留空位;解码失败时显示本地化提示,不影响配置或启用。卡片与组件行保留小尺寸图标。
|
||||
组合包详情在描述下方展示可选的包内功能配图,未启用时也可查看。多语言配图通过现有语言解析器跟随界面语言,以英文回退。没有配图就不显示图片或预留空位;解码失败时显示本地化提示,不影响配置或启用。卡片与组件行保留小尺寸图标。
|
||||
|
||||
-----
|
||||
|
||||
|
||||
@@ -709,6 +709,7 @@ function PackageDetail({
|
||||
}): ReactNode {
|
||||
const { title, description, beta } = packageText(pkg, resolveText)
|
||||
const status = packageStatus(pkg)
|
||||
const preview = pkg.meta?.preview === undefined ? undefined : resolveText(pkg.meta.preview)
|
||||
const subject: PluginsSubject = { kind: 'bundle', pkg: packageRef(pkg) }
|
||||
return (
|
||||
<div className={css.detail} data-plugin-detail={pkg.name}>
|
||||
@@ -761,7 +762,7 @@ function PackageDetail({
|
||||
<MetadataError error={pkg.meta?.error} t={t} />
|
||||
{pkg.error === undefined ? null : <p className={css.reason} role="status">{t('reasonLabel')}: {managementText(pkg.error, t)}</p>}
|
||||
{pkg.readOnlyReason === undefined ? null : <p className={css.reason} role="status">{managementText({ code: pkg.readOnlyReason }, t)}</p>}
|
||||
{pkg.meta?.preview === undefined ? null : <PackagePreview key={pkg.meta.preview} src={pkg.meta.preview} title={title} t={t} />}
|
||||
{preview === undefined ? null : <PackagePreview key={preview} src={preview} title={title} t={t} />}
|
||||
<div className={css.detailSections}>
|
||||
{configured
|
||||
? (
|
||||
|
||||
@@ -679,6 +679,21 @@ describe('PluginManagerPage', () => {
|
||||
expect(screen.queryByText(zh.previewUnavailable)).toBeNull()
|
||||
})
|
||||
|
||||
it('switches preview artwork with the UI language and uses the English fallback', () => {
|
||||
const enImage = 'data:image/svg+xml;base64,ZW4='
|
||||
const zhImage = 'data:image/svg+xml;base64,emg='
|
||||
const bundle = pkg({ meta: { preview: { en: enImage, zh: zhImage } } })
|
||||
const { set, setLanguage } = renderTab({ packages: [bundle] })
|
||||
fireEvent.click(screen.getByRole('button', { name: 'View dsh-better-sidebar' }))
|
||||
expect(screen.getByRole('img').getAttribute('src')).toBe(enImage)
|
||||
fireEvent.error(screen.getByRole('img'))
|
||||
setLanguage(zh)
|
||||
expect(screen.getByRole('img').getAttribute('src')).toBe(zhImage)
|
||||
expect(screen.queryByText(zh.previewUnavailable)).toBeNull()
|
||||
set({ packages: [{ ...bundle, meta: { preview: { en: enImage } } }] })
|
||||
expect(screen.getByRole('img').getAttribute('src')).toBe(enImage)
|
||||
})
|
||||
|
||||
it('shows metadata diagnostics without blocking management or displaying legacy descriptions', () => {
|
||||
const error = 'locale/zh.json: invalid title'
|
||||
const { actions, set, setLanguage } = renderTab({
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
en: d152484eb41ac6b4
|
||||
zh: 988e839059414d27
|
||||
/deepseek-ai-dsh-experimental-badge-skill-bundle/use-this-package:
|
||||
en: a5b3ce4165f7a95b
|
||||
zh: a9c5f7d9d53c67cd
|
||||
en: 2935cc992a9d8efd
|
||||
zh: 5f3c480538d98dd0
|
||||
/deepseek-ai-dsh-experimental-badge-skill-bundle/understand-the-implementation:
|
||||
en: e1ce6533996f4fe6
|
||||
zh: 5bf2931419881347
|
||||
|
||||
@@ -29,7 +29,7 @@ In Web or Desktop, open Plugins and enable **DSH badge skill** in Official. Swit
|
||||
|
||||
The switch adds or removes a Host-wide skill provider for existing and new Agents. Presets that expose skill loading can use the badge; minimal keeps its tool catalog unchanged.
|
||||
|
||||
The optional `preview.svg` illustrates the official attribution badge at the end of a document. Plugin details display it before activation; the skill owns the badge assets and usage instructions.
|
||||
The optional `preview.svg` and `preview.zh.svg` illustrate the official attribution badge at the end of a document in English and Chinese. Plugin details select the artwork for the UI language and display it before activation; the skill owns the badge assets and usage instructions.
|
||||
|
||||
-----
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ kind: "package-bundle"
|
||||
|
||||
开关为已有和新建智能体添加或移除 Host 级技能提供方。提供技能加载能力的预设可以使用徽章;minimal 的工具目录保持不变。
|
||||
|
||||
可选的 `preview.svg` 示意在文档末尾添加官方署名徽章的效果,插件未启用时详情页也可展示。徽章资源和使用说明由技能拥有。
|
||||
可选的 `preview.svg` 和 `preview.zh.svg` 分别用英文和中文示意在文档末尾添加官方署名徽章的效果,详情页按界面语言选择配图,插件未启用时也可展示。徽章资源和使用说明由技能拥有。
|
||||
|
||||
-----
|
||||
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
"description": "Let agents add a “powered by dsh” badge to documents, pull requests, and other outputs.",
|
||||
"version": "0.2.1-alpha.2",
|
||||
"icon": "./icon.svg",
|
||||
"preview": "./preview.svg",
|
||||
"preview": {
|
||||
"en": "./preview.svg",
|
||||
"zh": "./preview.zh.svg"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
@@ -28,6 +31,7 @@
|
||||
"files": [
|
||||
"icon.svg",
|
||||
"preview.svg",
|
||||
"preview.zh.svg",
|
||||
"locale/*.json",
|
||||
"lib/index.js",
|
||||
"cordis.patch.yml",
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
<path d="M0 246C151 294 262 278 388 229C492 189 563 179 640 196V300H0Z" fill="#EBF0FC"/>
|
||||
<g transform="rotate(8 457 185)"><rect x="308" y="64" width="288" height="258" rx="8" fill="#DEE6FF" stroke="#CAD5FB"/></g>
|
||||
<g transform="rotate(-5 464 156)"><rect x="323" y="27" width="282" height="287" rx="8" fill="#FFF" stroke="#DFE4EE"/>
|
||||
<path transform="translate(348 59) scale(1)" d="M4.10 -3.89Q4.78 -3.89 5.18 -4.16Q5.58 -4.43 5.58 -5.15Q5.58 -5.91 5.02 -6.19Q4.72 -6.34 4.22 -6.34L1.85 -6.34L1.85 -3.89ZM0.88 -7.17L4.20 -7.17Q5.02 -7.17 5.55 -6.93Q6.56 -6.47 6.56 -5.24Q6.56 -4.59 6.30 -4.18Q6.03 -3.77 5.55 -3.53Q5.97 -3.35 6.18 -3.08Q6.40 -2.80 6.42 -2.17L6.46 -1.21Q6.47 -0.80 6.52 -0.60Q6.61 -0.26 6.84 -0.16L6.84 -0.00L5.64 -0.00Q5.60 -0.09 5.57 -0.24Q5.54 -0.39 5.52 -0.81L5.46 -2.00Q5.42 -2.71 4.94 -2.94Q4.66 -3.08 4.06 -3.08L1.85 -3.08L1.85 -0.00L0.88 -0.00ZM8.08 -7.17L13.31 -7.17L13.31 -6.29L9.02 -6.29L9.02 -4.12L12.98 -4.12L12.98 -3.29L9.02 -3.29L9.02 -0.85L13.38 -0.85L13.38 -0.00L8.08 -0.00ZM18.33 -2.94L17.25 -6.11L16.09 -2.94ZM16.74 -7.17L17.84 -7.17L20.44 -0.00L19.38 -0.00L18.65 -2.15L15.81 -2.15L15.03 -0.00L14.04 -0.00ZM24.08 -0.83Q24.57 -0.83 24.89 -0.93Q25.45 -1.12 25.82 -1.67Q26.10 -2.10 26.23 -2.78Q26.30 -3.18 26.30 -3.53Q26.30 -4.86 25.77 -5.60Q25.24 -6.34 24.07 -6.34L22.34 -6.34L22.34 -0.83ZM21.37 -7.17L24.27 -7.17Q25.75 -7.17 26.57 -6.12Q27.29 -5.18 27.29 -3.70Q27.29 -2.55 26.87 -1.63Q26.11 -0.00 24.26 -0.00L21.37 -0.00ZM28.52 -7.17L29.91 -7.17L31.97 -1.11L34.02 -7.17L35.40 -7.17L35.40 -0.00L34.47 -0.00L34.47 -4.23Q34.47 -4.45 34.48 -4.96Q34.49 -5.47 34.49 -6.05L32.45 -0.00L31.48 -0.00L29.42 -6.05L29.42 -5.83Q29.42 -5.57 29.44 -5.03Q29.45 -4.49 29.45 -4.23L29.45 -0.00L28.52 -0.00ZM36.97 -7.17L42.20 -7.17L42.20 -6.29L37.92 -6.29L37.92 -4.12L41.88 -4.12L41.88 -3.29L37.92 -3.29L37.92 -0.85L42.27 -0.85L42.27 -0.00L36.97 -0.00ZM43.64 -1.06L44.66 -1.06L44.66 -0.00L43.64 -0.00ZM46.21 -5.23L47.08 -5.23L47.08 -4.49Q47.39 -4.87 47.64 -5.05Q48.08 -5.35 48.63 -5.35Q49.25 -5.35 49.63 -5.04Q49.85 -4.86 50.02 -4.52Q50.32 -4.94 50.71 -5.14Q51.11 -5.35 51.60 -5.35Q52.66 -5.35 53.04 -4.58Q53.24 -4.17 53.24 -3.48L53.24 -0.00L52.33 -0.00L52.33 -3.63Q52.33 -4.16 52.07 -4.35Q51.81 -4.55 51.43 -4.55Q50.91 -4.55 50.54 -4.20Q50.17 -3.85 50.17 -3.04L50.17 -0.00L49.27 -0.00L49.27 -3.41Q49.27 -3.95 49.15 -4.19Q48.95 -4.56 48.40 -4.56Q47.90 -4.56 47.49 -4.17Q47.08 -3.78 47.08 -2.77L47.08 -0.00L46.21 -0.00ZM55.09 -2.55Q55.09 -1.71 55.45 -1.15Q55.81 -0.58 56.59 -0.58Q57.20 -0.58 57.60 -1.11Q57.99 -1.63 57.99 -2.61Q57.99 -3.60 57.58 -4.08Q57.18 -4.56 56.58 -4.56Q55.92 -4.56 55.51 -4.05Q55.09 -3.54 55.09 -2.55ZM56.42 -5.32Q57.02 -5.32 57.42 -5.07Q57.66 -4.92 57.95 -4.56L57.95 -7.20L58.80 -7.20L58.80 -0.00L58.01 -0.00L58.01 -0.73Q57.70 -0.24 57.28 -0.03Q56.86 0.19 56.32 0.19Q55.44 0.19 54.80 -0.55Q54.17 -1.28 54.17 -2.50Q54.17 -3.65 54.75 -4.48Q55.33 -5.32 56.42 -5.32Z" fill="#7A8494"/><path transform="translate(348 102) scale(0.78)" d="M4.56 -17.86L4.56 -5.24C3.44 -4.93 2.30 -4.62 1.12 -4.34L1.90 -1.71C5.10 -2.58 7.92 -3.53 10.39 -4.54L10.39 -7.20C9.38 -6.80 8.34 -6.41 7.25 -6.05L7.25 -17.86L10.28 -17.86L10.28 -20.44L1.46 -20.44L1.46 -17.86L4.56 -17.86ZM11.17 -21.98L11.17 -19.40L17.72 -19.40C17.61 -18.59 17.44 -17.81 17.22 -17.02L12.24 -17.02L12.24 -3.47L14.78 -3.47L14.78 -14.56L23.16 -14.56L23.16 -3.47L25.73 -3.47L25.73 -17.02L19.85 -17.02C20.02 -17.78 20.19 -18.56 20.33 -19.40L26.85 -19.40L26.85 -21.98L11.17 -21.98ZM21.56 -3.64L19.80 -1.93C22.15 -0.14 23.97 1.51 25.26 3.05L27.16 1.15C25.65 -0.42 23.80 -2.02 21.56 -3.64ZM17.56 -13.16L17.56 -8.26C17.44 -5.96 16.80 -4.09 15.68 -2.63C14.50 -1.29 12.26 -0.17 9.02 0.73L10.47 3.00C13.83 2.04 16.24 0.76 17.72 -0.92C19.24 -2.77 20.08 -5.24 20.22 -8.26L20.22 -13.16L17.56 -13.16ZM51.77 -21.81L32.26 -21.81L32.26 2.91L34.97 2.91L34.97 1.20L49.08 1.20L49.08 2.86L51.77 2.86L51.77 -21.81ZM34.97 -1.37L34.97 -6.02L49.08 -6.02L49.08 -1.37L34.97 -1.37ZM34.97 -8.43L34.97 -12.74L49.08 -12.74L49.08 -8.43L34.97 -8.43ZM34.97 -15.20L34.97 -19.24L49.08 -19.24L49.08 -15.20L34.97 -15.20ZM65.86 -20.86L65.86 -18.45L72.74 -18.45L72.74 -16.58L66.75 -16.58L66.75 -9.07L71.20 -9.07C69.92 -7.14 67.87 -5.46 65.07 -4.03L66.72 -1.93C69.33 -3.56 71.34 -5.46 72.74 -7.64L72.74 -0.84L75.24 -0.84L75.24 -9.07L81.23 -9.07L81.23 -16.58L75.24 -16.58L75.24 -18.45L82.07 -18.45L82.07 -20.86L75.24 -20.86L75.24 -22.88L72.74 -22.88L72.74 -20.86L65.86 -20.86ZM78.79 -11.37L75.24 -11.37L75.24 -14.28L78.79 -14.28L78.79 -11.37ZM72.74 -11.37L69.22 -11.37L69.22 -14.28L72.74 -14.28L72.74 -11.37ZM77.56 -8.51L75.85 -6.89C77.81 -5.26 79.35 -3.72 80.47 -2.30L82.24 -4.03C80.95 -5.54 79.41 -7.03 77.56 -8.51ZM59.78 -22.68L57.96 -20.94C60.00 -19.32 61.57 -17.81 62.69 -16.41L64.57 -18.26C63.28 -19.71 61.68 -21.20 59.78 -22.68ZM75.85 2.41L82.26 2.41L82.94 -0.22C82.15 -0.17 81.06 -0.11 79.66 -0.08C78.26 -0.06 76.86 -0.03 75.49 -0.03C73.30 -0.03 71.40 -0.06 69.83 -0.08C68.18 -0.14 66.95 -0.39 66.11 -0.78C65.41 -1.15 64.74 -1.71 64.09 -2.46C63.95 -2.63 63.81 -2.77 63.67 -2.88L63.67 -13.47L57.43 -13.47L57.43 -11.00L61.18 -11.00L61.18 -3.08C60.06 -2.52 58.80 -1.09 57.40 1.18L59.36 3.00C60.79 0.48 61.80 -0.78 62.38 -0.78C62.72 -0.78 63.06 -0.56 63.45 -0.08C64.29 0.87 65.27 1.54 66.39 1.88C67.54 2.16 69.02 2.32 70.84 2.35C72.63 2.38 74.31 2.41 75.85 2.41ZM111.24 -4.96L108.58 -5.85CLine truncated
|
||||
<path transform="translate(348 59) scale(1)" d="M4.10 -3.89Q4.78 -3.89 5.18 -4.16Q5.58 -4.43 5.58 -5.15Q5.58 -5.91 5.02 -6.19Q4.72 -6.34 4.22 -6.34L1.85 -6.34L1.85 -3.89ZM0.88 -7.17L4.20 -7.17Q5.02 -7.17 5.55 -6.93Q6.56 -6.47 6.56 -5.24Q6.56 -4.59 6.30 -4.18Q6.03 -3.77 5.55 -3.53Q5.97 -3.35 6.18 -3.08Q6.40 -2.80 6.42 -2.17L6.46 -1.21Q6.47 -0.80 6.52 -0.60Q6.61 -0.26 6.84 -0.16L6.84 -0.00L5.64 -0.00Q5.60 -0.09 5.57 -0.24Q5.54 -0.39 5.52 -0.81L5.46 -2.00Q5.42 -2.71 4.94 -2.94Q4.66 -3.08 4.06 -3.08L1.85 -3.08L1.85 -0.00L0.88 -0.00ZM8.08 -7.17L13.31 -7.17L13.31 -6.29L9.02 -6.29L9.02 -4.12L12.98 -4.12L12.98 -3.29L9.02 -3.29L9.02 -0.85L13.38 -0.85L13.38 -0.00L8.08 -0.00ZM18.33 -2.94L17.25 -6.11L16.09 -2.94ZM16.74 -7.17L17.84 -7.17L20.44 -0.00L19.38 -0.00L18.65 -2.15L15.81 -2.15L15.03 -0.00L14.04 -0.00ZM24.08 -0.83Q24.57 -0.83 24.89 -0.93Q25.45 -1.12 25.82 -1.67Q26.10 -2.10 26.23 -2.78Q26.30 -3.18 26.30 -3.53Q26.30 -4.86 25.77 -5.60Q25.24 -6.34 24.07 -6.34L22.34 -6.34L22.34 -0.83ZM21.37 -7.17L24.27 -7.17Q25.75 -7.17 26.57 -6.12Q27.29 -5.18 27.29 -3.70Q27.29 -2.55 26.87 -1.63Q26.11 -0.00 24.26 -0.00L21.37 -0.00ZM28.52 -7.17L29.91 -7.17L31.97 -1.11L34.02 -7.17L35.40 -7.17L35.40 -0.00L34.47 -0.00L34.47 -4.23Q34.47 -4.45 34.48 -4.96Q34.49 -5.47 34.49 -6.05L32.45 -0.00L31.48 -0.00L29.42 -6.05L29.42 -5.83Q29.42 -5.57 29.44 -5.03Q29.45 -4.49 29.45 -4.23L29.45 -0.00L28.52 -0.00ZM36.97 -7.17L42.20 -7.17L42.20 -6.29L37.92 -6.29L37.92 -4.12L41.88 -4.12L41.88 -3.29L37.92 -3.29L37.92 -0.85L42.27 -0.85L42.27 -0.00L36.97 -0.00ZM43.64 -1.06L44.66 -1.06L44.66 -0.00L43.64 -0.00ZM46.21 -5.23L47.08 -5.23L47.08 -4.49Q47.39 -4.87 47.64 -5.05Q48.08 -5.35 48.63 -5.35Q49.25 -5.35 49.63 -5.04Q49.85 -4.86 50.02 -4.52Q50.32 -4.94 50.71 -5.14Q51.11 -5.35 51.60 -5.35Q52.66 -5.35 53.04 -4.58Q53.24 -4.17 53.24 -3.48L53.24 -0.00L52.33 -0.00L52.33 -3.63Q52.33 -4.16 52.07 -4.35Q51.81 -4.55 51.43 -4.55Q50.91 -4.55 50.54 -4.20Q50.17 -3.85 50.17 -3.04L50.17 -0.00L49.27 -0.00L49.27 -3.41Q49.27 -3.95 49.15 -4.19Q48.95 -4.56 48.40 -4.56Q47.90 -4.56 47.49 -4.17Q47.08 -3.78 47.08 -2.77L47.08 -0.00L46.21 -0.00ZM55.09 -2.55Q55.09 -1.71 55.45 -1.15Q55.81 -0.58 56.59 -0.58Q57.20 -0.58 57.60 -1.11Q57.99 -1.63 57.99 -2.61Q57.99 -3.60 57.58 -4.08Q57.18 -4.56 56.58 -4.56Q55.92 -4.56 55.51 -4.05Q55.09 -3.54 55.09 -2.55ZM56.42 -5.32Q57.02 -5.32 57.42 -5.07Q57.66 -4.92 57.95 -4.56L57.95 -7.20L58.80 -7.20L58.80 -0.00L58.01 -0.00L58.01 -0.73Q57.70 -0.24 57.28 -0.03Q56.86 0.19 56.32 0.19Q55.44 0.19 54.80 -0.55Q54.17 -1.28 54.17 -2.50Q54.17 -3.65 54.75 -4.48Q55.33 -5.32 56.42 -5.32Z" fill="#7A8494"/><path transform="translate(348 102) scale(0.78)" d="M2.13 -19.99L10.95 -19.99Q13.08 -19.99 14.42 -19.38Q15.76 -18.76 16.49 -17.84Q17.22 -16.91 17.49 -15.82Q17.75 -14.73 17.75 -13.80Q17.75 -12.88 17.49 -11.80Q17.22 -10.72 16.49 -9.80Q15.76 -8.88 14.42 -8.27Q13.08 -7.67 10.95 -7.67L5.63 -7.67L5.63 -0.00L2.13 -0.00ZM5.63 -10.53L10.75 -10.53Q11.34 -10.53 11.96 -10.70Q12.57 -10.86 13.09 -11.24Q13.61 -11.62 13.93 -12.25Q14.25 -12.88 14.25 -13.83Q14.25 -14.81 13.97 -15.46Q13.69 -16.10 13.22 -16.48Q12.74 -16.86 12.12 -17.00Q11.51 -17.14 10.81 -17.14L5.63 -17.14ZM20.36 -14.48L23.35 -14.48L23.35 -11.68L23.41 -11.68Q23.55 -12.26 23.95 -12.82Q24.36 -13.38 24.93 -13.85Q25.51 -14.31 26.21 -14.59Q26.91 -14.87 27.64 -14.87Q28.20 -14.87 28.41 -14.84Q28.62 -14.81 28.84 -14.78L28.84 -11.70Q28.50 -11.76 28.15 -11.80Q27.80 -11.84 27.47 -11.84Q26.66 -11.84 25.94 -11.52Q25.23 -11.20 24.70 -10.57Q24.16 -9.94 23.86 -9.02Q23.55 -8.09 23.55 -6.89L23.55 -0.00L20.36 -0.00ZM36.85 0.39Q35.11 0.39 33.75 -0.18Q32.40 -0.76 31.46 -1.76Q30.52 -2.77 30.03 -4.17Q29.54 -5.57 29.54 -7.25Q29.54 -8.90 30.03 -10.30Q30.52 -11.70 31.46 -12.71Q32.40 -13.72 33.75 -14.29Q35.11 -14.87 36.85 -14.87Q38.58 -14.87 39.94 -14.29Q41.30 -13.72 42.24 -12.71Q43.18 -11.70 43.67 -10.30Q44.16 -8.90 44.16 -7.25Q44.16 -5.57 43.67 -4.17Q43.18 -2.77 42.24 -1.76Q41.30 -0.76 39.94 -0.18Q38.58 0.39 36.85 0.39ZM36.85 -2.13Q37.91 -2.13 38.70 -2.58Q39.48 -3.02 39.98 -3.75Q40.49 -4.48 40.73 -5.39Q40.96 -6.30 40.96 -7.25Q40.96 -8.18 40.73 -9.10Q40.49 -10.02 39.98 -10.74Q39.48 -11.45 38.70 -11.90Q37.91 -12.35 36.85 -12.35Q35.78 -12.35 35.00 -11.90Q34.22 -11.45 33.71 -10.74Q33.21 -10.02 32.97 -9.10Q32.73 -8.18 32.73 -7.25Q32.73 -6.30 32.97 -5.39Q33.21 -4.48 33.71 -3.75Q34.22 -3.02 35.00 -2.58Q35.78 -2.13 36.85 -2.13ZM46.90 -19.99L50.09 -19.99L50.09 -16.97L46.90 -16.97ZM46.90 -14.48L50.09 -14.48L50.09 1.23Q50.09 3.39 49.14 4.56Q48.19 5.74 45.95 5.74Q45.47 5.74 45.15 5.71Q44.83 5.68 44.52 5.63L44.52 3.11Q44.83 3.16 45.11 3.19Q45.39 3.22 45.61 3.22Q46.48 3.22 46.69 2.69Q46.90 2.16 46.90 1.09ZM63.50 -8.51Q63.45 -9.27 63.18 -9.97Q62.92 -10.67 62.45 -11.19Q61.99 -11.70 61.33 -12.03Q60.68 -12.35 59.86 -12.35Q59.02 -12.35 58.34 -12.05Q57.65 -11.76 57.16 -11.24Q56.67 -10.72 56.38 -10.02Q56.08 -9.32 56.06 -8.51ZM56.06 -6.41Q56.06 -5.57 56.29 -4.79Q56.53 -4.00 57.01 -3.42Q57.48 -2.83 58.21 -2.48Q58.94 -2.13 59.95 -2.13Q61.35 -2.13 62.20 -2.73Q63.06 -3.33 63.48Line truncated
|
||||
<path d="M348 184H581" stroke="#E6EAF1"/>
|
||||
<rect x="348" y="204" width="158" height="42" rx="6" fill="#EEF2FF"/>
|
||||
<image x="366" y="215" width="121" height="20.0" href="data:image/png;base64,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 truncated
|
||||
<path transform="translate(36 130) scale(1.05)" d="M10.15 -2.78C7.65 -1.88 4.70 -1.15 1.33 -0.60L1.62 1.70C4.83 1.12 7.65 0.38 10.15 -0.53L10.15 -2.78ZM5.25 -20.58C4.33 -17.82 3.25 -15.35 2.00 -13.10C1.70 -12.68 1.38 -12.38 1.03 -12.23L1.60 -10.05C2.85 -10.23 4.08 -10.40 5.25 -10.60C4.15 -8.55 3.23 -7.12 2.48 -6.30C2.18 -6.03 1.83 -5.80 1.40 -5.62L2.02 -3.48C4.42 -3.83 6.98 -4.45 9.68 -5.38L9.68 -7.50C8.03 -6.93 6.40 -6.45 4.80 -6.10C6.15 -7.90 7.83 -10.75 9.83 -14.65L7.70 -15.45C7.25 -14.50 6.80 -13.60 6.38 -12.75C5.53 -12.60 4.67 -12.48 3.83 -12.38C5.08 -14.25 6.28 -16.70 7.48 -19.73L5.25 -20.58ZM22.18 -8.05L11.33 -8.05L11.33 2.27L13.60 2.27L13.60 1.10L19.85 1.10L19.85 2.27L22.18 2.27L22.18 -8.05ZM13.60 -1.18L13.60 -5.80L19.85 -5.80L19.85 -1.18L13.60 -1.18ZM15.65 -20.40C13.98 -17.35 11.83 -14.85 9.18 -12.90L10.55 -10.93C11.25 -11.48 11.93 -12.05 12.58 -12.70L12.58 -10.62L20.78 -10.62L20.78 -12.80C21.43 -12.15 22.15 -11.58 22.90 -11.03L24.28 -13.05C21.43 -15.00 19.28 -17.45 17.85 -20.40L15.65 -20.40ZM12.73 -12.85C14.20 -14.35 15.55 -16.15 16.75 -18.23C17.80 -16.18 19.12 -14.38 20.73 -12.85L12.73 -12.85ZM37.35 -14.85L38.25 -14.85L38.25 2.62L40.65 2.62L40.65 -3.03L47.73 -3.03L47.73 -5.30L40.65 -5.30L40.65 -8.97L47.67 -8.97L47.67 -11.28L40.65 -11.28L40.65 -14.85L48.67 -14.85L48.67 -17.18L38.38 -17.18C38.75 -18.12 39.12 -19.12 39.48 -20.18L37.08 -20.70C35.62 -16.45 33.85 -13.10 31.77 -10.68L33.48 -8.62C34.90 -10.38 36.20 -12.45 37.35 -14.85ZM28.82 -10.73L28.82 2.62L31.23 2.62L31.23 -14.18C32.23 -15.88 33.05 -17.68 33.70 -19.58L31.45 -20.62C30.23 -16.88 28.32 -13.58 25.75 -10.75L26.55 -8.20C27.35 -9.03 28.12 -9.88 28.82 -10.73ZM55.40 -19.65L55.40 -10.93L69.60 -10.93L69.60 -19.65L55.40 -19.65ZM67.22 -13.18L57.77 -13.18L57.77 -17.40L67.22 -17.40L67.22 -13.18ZM61.30 -9.05L52.05 -9.05L52.05 2.20L54.38 2.20L54.38 1.00L59.00 1.00L59.00 2.20L61.30 2.20L61.30 -9.05ZM54.38 -1.23L54.38 -6.80L59.00 -6.80L59.00 -1.23L54.38 -1.23ZM72.95 -9.05L63.42 -9.05L63.42 2.20L65.75 2.20L65.75 1.00L70.58 1.00L70.58 2.20L72.95 2.20L72.95 -9.05ZM65.75 -1.23L65.75 -6.80L70.58 -6.80L70.58 -1.23L65.75 -1.23ZM96.55 -8.85L78.55 -8.85L78.55 2.60L80.88 2.60L80.88 1.65L94.22 1.65L94.22 2.58L96.55 2.58L96.55 -8.85ZM80.88 -0.58L80.88 -2.55L86.45 -2.55L86.45 -0.58L80.88 -0.58ZM88.80 -0.58L88.80 -2.55L94.22 -2.55L94.22 -0.58L88.80 -0.58ZM80.88 -4.65L80.88 -6.65L86.45 -6.65L86.45 -4.65L80.88 -4.65ZM88.80 -6.65L94.22 -6.65L94.22 -4.65L88.80 -4.65L88.80 -6.65ZM84.95 -16.75L82.72 -16.12C83.08 -15.25 83.42 -14.35 83.75 -13.43C82.67 -12.98 81.30 -12.53 79.62 -12.03L79.62 -16.75C82.47 -17.10 84.83 -17.78 86.67 -18.73L85.50 -20.70C83.33 -19.65 80.60 -18.95 77.33 -18.65L77.33 -12.98C77.33 -12.28 77.05 -11.73 76.50 -11.33L77.35 -9.15C80.17 -9.83 82.55 -10.55 84.45 -11.33C84.65 -10.68 84.85 -10.00 85.05 -9.30L87.33 -10.12C86.78 -12.12 85.97 -14.35 84.95 -16.75ZM89.88 -17.28C89.67 -16.00 89.45 -14.95 89.15 -14.10C88.75 -13.05 88.15 -12.08 87.38 -11.20L88.78 -9.43C89.85 -10.50 90.65 -11.73 91.20 -13.08C91.60 -14.15 91.90 -15.55 92.15 -17.28L95.40 -17.28C95.35 -14.98 95.28 -13.55 95.12 -12.98C94.95 -12.12 94.53 -11.68 93.88 -11.65C93.25 -11.65 92.47 -11.70 91.55 -11.78L92.25 -9.68C92.95 -9.62 93.58 -9.58 94.12 -9.58C95.62 -9.60 96.62 -10.28 97.08 -11.60C97.45 -12.68 97.67 -15.35 97.78 -19.60L87.45 -19.60L87.45 -17.28L89.88 -17.28ZM111.30 -13.05L111.30 2.55L113.70 2.55L113.70 -13.05L111.30 -13.05ZM111.45 -20.50C108.95 -16.85 105.40 -13.88 100.80 -11.58L102.22 -9.43C106.38 -11.50 109.80 -14.45 112.50 -18.28C114.75 -14.78 118.17 -11.83 122.78 -9.45L124.20 -11.62C119.17 -14.18 115.62 -17.15 113.55 -20.50L111.45 -20.50ZM128.38 -19.70L128.38 -14.62L135.55 -14.62L135.55 -13.40L129.15 -13.40L129.15 -11.55L135.55 -11.55L135.55 -10.18L126.42 -10.18L126.42 -8.15L136.80 -8.15C133.80 -7.00 130.30 -6.20 126.33 -5.80L127.60 -3.85C128.75 -4.08 129.90 -4.33 131.00 -4.58L131.00 2.75L133.32 2.75L133.32 1.73L143.38 1.73L143.38 2.75L145.70 2.75L145.70 -6.75L137.80 -6.75C138.88 -7.20 139.90 -7.65 140.85 -8.15L148.70 -8.15L148.70 -10.18L144.20 -10.18C145.45 -11.08 146.60 -12.05 147.62 -13.12L145.68 -14.15C144.88 -13.28 143.97 -12.43 142.97 -11.62L142.97 -13.40L137.85 -13.40L137.85 -14.62L146.53 -14.62L146.53 -19.70L128.38 -19.70ZM140.90 -10.18L137.85 -10.18L137.85 -11.55L142.88 -11.55C142.25 -11.08 141.60 -10.62 140.90 -10.18ZM144.28 -16.35L141.18 -16.35L141.18 -17.95L144.28 -17.95L144.28 -16.35ZM139.00 -16.35L135.95 -16.35L135.95 -17.95L139.00 -17.95L139.00 -16.35ZM133.78 -16.35L130.62 -16.35L130.62 -17.95L133.78 -17.95L133.78 -16.35ZM133.32 -1.65L143.38 -1.65L143.38 -0.20L133.32 -0.20L133.32 -1.65ZM143.38 -3.45L133.32 -3.45L133.32 -4.95L143.38 -4.95L143.38 -3.45ZM159.18 1.18L169.75 1.18L169.75 2.50L172.15 2.50L172.15 -8.38L162.57 -8.38C166.80 -10.48 169.72 -13.12 171.35 -16.30L171.35 -18.40L161.97 -18.40C162.40 -19.00 162.78 -19.62 163.12 -20.28L160.53 -20.58C159.03 -18.00 156.18 -15.83 151.95 -14.03L153.55 -11.98C156.15 -13.23 158.28 -14.62 159.97 -16.18L168.62 -16.18C167.53 -14.38Line truncated
|
||||
<path d="M38 180H74" stroke="#4D6BFE" stroke-width="2" stroke-linecap="round"/>
|
||||
<path transform="translate(36 131)" d="M13.88 -0.00L8.11 -0.00L8.11 -0.69Q8.87 -0.74 9.37 -0.89Q9.87 -1.04 9.87 -1.25Q9.87 -1.34 9.85 -1.46Q9.83 -1.59 9.79 -1.69L8.64 -4.79L3.79 -4.79Q3.52 -4.11 3.34 -3.60Q3.17 -3.10 3.04 -2.67Q2.91 -2.25 2.86 -1.98Q2.81 -1.72 2.81 -1.55Q2.81 -1.16 3.43 -0.95Q4.04 -0.73 4.81 -0.69L4.81 -0.00L-0.40 -0.00L-0.40 -0.69Q-0.15 -0.71 0.23 -0.81Q0.62 -0.90 0.86 -1.05Q1.25 -1.32 1.46 -1.61Q1.68 -1.89 1.88 -2.40Q2.93 -5.01 4.19 -8.26Q5.45 -11.51 6.44 -14.05L7.22 -14.05L11.84 -2.10Q11.98 -1.72 12.17 -1.48Q12.35 -1.25 12.69 -1.03Q12.91 -0.89 13.27 -0.80Q13.63 -0.70 13.88 -0.69ZM8.29 -5.66L6.19 -11.04L4.13 -5.66ZM25.30 -4.72Q25.70 -4.37 25.92 -3.91Q26.13 -3.45 26.13 -2.78Q26.13 -1.45 25.13 -0.60Q24.13 0.25 22.54 0.25Q21.70 0.25 20.99 -0.05Q20.28 -0.35 19.98 -0.61L19.79 0.03L19.05 0.03L18.96 -3.32L19.63 -3.32Q19.71 -2.94 19.96 -2.43Q20.21 -1.92 20.58 -1.51Q20.96 -1.08 21.49 -0.79Q22.02 -0.50 22.69 -0.50Q23.62 -0.50 24.13 -0.92Q24.64 -1.35 24.64 -2.14Q24.64 -2.55 24.48 -2.85Q24.32 -3.14 24.00 -3.37Q23.68 -3.59 23.21 -3.77Q22.74 -3.96 22.17 -4.13Q21.71 -4.27 21.15 -4.51Q20.59 -4.75 20.19 -5.07Q19.76 -5.41 19.48 -5.91Q19.21 -6.41 19.21 -7.08Q19.21 -8.26 20.09 -9.08Q20.97 -9.90 22.44 -9.90Q23.01 -9.90 23.60 -9.76Q24.19 -9.61 24.56 -9.40L24.79 -9.91L25.49 -9.91L25.63 -6.82L24.96 -6.82Q24.76 -7.85 24.08 -8.50Q23.40 -9.15 22.42 -9.15Q21.62 -9.15 21.16 -8.75Q20.70 -8.35 20.70 -7.78Q20.70 -7.34 20.85 -7.05Q21.01 -6.76 21.31 -6.55Q21.60 -6.36 22.05 -6.19Q22.49 -6.02 23.14 -5.80Q23.79 -5.60 24.36 -5.32Q24.93 -5.05 25.30 -4.72ZM32.27 -0.00L27.61 -0.00L27.61 -0.64Q27.83 -0.66 28.07 -0.68Q28.31 -0.70 28.49 -0.76Q28.76 -0.85 28.89 -1.07Q29.02 -1.29 29.02 -1.64L29.02 -7.59Q29.02 -7.90 28.88 -8.16Q28.74 -8.42 28.49 -8.59Q28.30 -8.71 27.95 -8.79Q27.60 -8.88 27.30 -8.90L27.30 -9.53L30.70 -9.75L30.84 -9.61L30.84 -1.76Q30.84 -1.42 30.97 -1.19Q31.10 -0.97 31.39 -0.86Q31.60 -0.77 31.81 -0.72Q32.01 -0.66 32.27 -0.64ZM31.04 -13.54Q31.04 -12.99 30.67 -12.57Q30.30 -12.16 29.77 -12.16Q29.27 -12.16 28.90 -12.55Q28.54 -12.95 28.54 -13.46Q28.54 -13.99 28.90 -14.39Q29.27 -14.79 29.77 -14.79Q30.32 -14.79 30.68 -14.42Q31.04 -14.04 31.04 -13.54ZM41.70 -1.00Q42.09 -0.62 42.31 -0.16Q42.54 0.31 42.54 1.01Q42.54 1.70 42.24 2.31Q41.93 2.92 41.32 3.37Q40.66 3.83 39.76 4.08Q38.85 4.34 37.51 4.34Q35.32 4.34 34.24 3.70Q33.15 3.06 33.15 1.83Q33.15 0.83 33.94 0.25Q34.72 -0.32 35.93 -0.37L35.93 -0.51Q35.63 -0.60 35.32 -0.73Q35.01 -0.86 34.79 -1.04Q34.53 -1.24 34.38 -1.52Q34.22 -1.80 34.22 -2.21Q34.22 -2.72 34.58 -3.16Q34.95 -3.59 35.69 -3.91L35.69 -4.05Q34.76 -4.49 34.24 -5.18Q33.72 -5.87 33.72 -6.78Q33.72 -8.14 34.74 -9.02Q35.76 -9.90 37.35 -9.90Q37.79 -9.90 38.23 -9.81Q38.66 -9.73 39.11 -9.59L42.47 -9.59L42.47 -8.65L40.21 -8.65L40.21 -8.59Q40.57 -8.17 40.74 -7.67Q40.92 -7.16 40.92 -6.67Q40.92 -5.40 39.89 -4.52Q38.86 -3.64 37.49 -3.64L36.31 -3.64Q36.08 -3.56 35.84 -3.36Q35.60 -3.15 35.60 -2.80Q35.60 -2.44 35.80 -2.25Q36.01 -2.06 36.30 -1.99Q36.58 -1.91 36.96 -1.89Q37.33 -1.88 37.73 -1.87Q38.16 -1.86 38.91 -1.81Q39.66 -1.76 39.97 -1.75Q40.42 -1.73 40.87 -1.53Q41.33 -1.34 41.70 -1.00ZM39.06 -6.71Q39.06 -7.85 38.60 -8.53Q38.13 -9.21 37.29 -9.21Q36.84 -9.21 36.51 -9.02Q36.18 -8.83 35.98 -8.48Q35.78 -8.15 35.70 -7.70Q35.62 -7.25 35.62 -6.77Q35.62 -5.68 36.09 -5.00Q36.56 -4.32 37.31 -4.32Q38.15 -4.32 38.61 -5.00Q39.06 -5.67 39.06 -6.71ZM40.94 1.37Q40.94 0.82 40.68 0.47Q40.43 0.12 39.91 -0.01Q39.64 -0.05 38.79 -0.10Q37.94 -0.15 36.82 -0.15Q35.76 0.06 35.32 0.54Q34.87 1.03 34.87 1.79Q34.87 2.13 35.02 2.44Q35.17 2.75 35.53 3.02Q35.87 3.27 36.45 3.43Q37.02 3.59 37.85 3.59Q39.29 3.59 40.11 3.04Q40.94 2.49 40.94 1.37ZM54.27 -0.00L49.55 -0.00L49.55 -0.64Q49.78 -0.66 50.04 -0.68Q50.31 -0.70 50.49 -0.76Q50.76 -0.85 50.89 -1.07Q51.03 -1.29 51.03 -1.64L51.03 -6.59Q51.03 -7.62 50.54 -8.17Q50.06 -8.73 49.37 -8.73Q48.85 -8.73 48.42 -8.57Q47.99 -8.41 47.66 -8.17Q47.33 -7.95 47.14 -7.69Q46.95 -7.43 46.87 -7.28L46.87 -1.74Q46.87 -1.41 47.00 -1.19Q47.14 -0.98 47.41 -0.86Q47.62 -0.76 47.86 -0.71Q48.10 -0.66 48.35 -0.64L48.35 -0.00L43.63 -0.00L43.63 -0.64Q43.86 -0.66 44.10 -0.68Q44.34 -0.70 44.51 -0.76Q44.79 -0.85 44.92 -1.07Q45.05 -1.29 45.05 -1.64L45.05 -7.59Q45.05 -7.92 44.91 -8.20Q44.77 -8.48 44.51 -8.65Q44.33 -8.77 44.07 -8.82Q43.82 -8.88 43.53 -8.90L43.53 -9.53L46.73 -9.75L46.87 -9.61L46.87 -8.25L46.91 -8.25Q47.15 -8.49 47.50 -8.81Q47.85 -9.14 48.16 -9.35Q48.53 -9.58 49.02 -9.74Q49.52 -9.89 50.15 -9.89Q51.53 -9.89 52.20 -9.03Q52.87 -8.16 52.87 -6.73L52.87 -1.72Q52.87 -1.38 52.99 -1.17Q53.11 -0.96 53.39 -0.84Q53.62 -0.74 53.79 -0.70Q53.96 -0.66 54.27 -0.64ZM64.57 -0.18Q64.11 -0.01 63.76 0.09Q63.42 0.20 62.98 0.20Q62.22 0.20 61.76 -0.16Q61.31 -0.52 61.18 -1.20L61.12 -1.20Q60.49 -0.50 59.76 -0.13Q59.03 0.24 58.01 0.24Q56.92 0.24 56.23 -0.42Q55.53 -1.08 55.53 -2.16Q55.53 -2.71 55.68 -3.15Q55.84 -3.59 56.15 -3.95Q56.40 -4.24 56.80 -4.47Q57.20 -4.70 57.55 -4.83Q57.99 -5.00 59.33 -5.45Q60.67 -5.90 61.14 -6.15L61.14 -7.12Q61.14 -7.25 61.09 -7.61Q61.04 -7.97 6Line truncated
|
||||
|
||||
|
||||
<!-- Magnified detail of the unchanged official badge in the document footer. -->
|
||||
<path d="M354 220H322Q306 220 306 236Q306 250 290 250H266" stroke="#8FA5F1" stroke-width="1.5"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 85 KiB |
@@ -0,0 +1,22 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="300" viewBox="0 0 640 300" fill="none">
|
||||
<defs><clipPath id="canvas"><rect width="640" height="300" rx="10"/></clipPath></defs>
|
||||
<g clip-path="url(#canvas)">
|
||||
<rect width="640" height="300" fill="#F3F6FC"/>
|
||||
<path d="M0 246C151 294 262 278 388 229C492 189 563 179 640 196V300H0Z" fill="#EBF0FC"/>
|
||||
<g transform="rotate(8 457 185)"><rect x="308" y="64" width="288" height="258" rx="8" fill="#DEE6FF" stroke="#CAD5FB"/></g>
|
||||
<g transform="rotate(-5 464 156)"><rect x="323" y="27" width="282" height="287" rx="8" fill="#FFF" stroke="#DFE4EE"/>
|
||||
<path transform="translate(348 59) scale(1)" d="M4.10 -3.89Q4.78 -3.89 5.18 -4.16Q5.58 -4.43 5.58 -5.15Q5.58 -5.91 5.02 -6.19Q4.72 -6.34 4.22 -6.34L1.85 -6.34L1.85 -3.89ZM0.88 -7.17L4.20 -7.17Q5.02 -7.17 5.55 -6.93Q6.56 -6.47 6.56 -5.24Q6.56 -4.59 6.30 -4.18Q6.03 -3.77 5.55 -3.53Q5.97 -3.35 6.18 -3.08Q6.40 -2.80 6.42 -2.17L6.46 -1.21Q6.47 -0.80 6.52 -0.60Q6.61 -0.26 6.84 -0.16L6.84 -0.00L5.64 -0.00Q5.60 -0.09 5.57 -0.24Q5.54 -0.39 5.52 -0.81L5.46 -2.00Q5.42 -2.71 4.94 -2.94Q4.66 -3.08 4.06 -3.08L1.85 -3.08L1.85 -0.00L0.88 -0.00ZM8.08 -7.17L13.31 -7.17L13.31 -6.29L9.02 -6.29L9.02 -4.12L12.98 -4.12L12.98 -3.29L9.02 -3.29L9.02 -0.85L13.38 -0.85L13.38 -0.00L8.08 -0.00ZM18.33 -2.94L17.25 -6.11L16.09 -2.94ZM16.74 -7.17L17.84 -7.17L20.44 -0.00L19.38 -0.00L18.65 -2.15L15.81 -2.15L15.03 -0.00L14.04 -0.00ZM24.08 -0.83Q24.57 -0.83 24.89 -0.93Q25.45 -1.12 25.82 -1.67Q26.10 -2.10 26.23 -2.78Q26.30 -3.18 26.30 -3.53Q26.30 -4.86 25.77 -5.60Q25.24 -6.34 24.07 -6.34L22.34 -6.34L22.34 -0.83ZM21.37 -7.17L24.27 -7.17Q25.75 -7.17 26.57 -6.12Q27.29 -5.18 27.29 -3.70Q27.29 -2.55 26.87 -1.63Q26.11 -0.00 24.26 -0.00L21.37 -0.00ZM28.52 -7.17L29.91 -7.17L31.97 -1.11L34.02 -7.17L35.40 -7.17L35.40 -0.00L34.47 -0.00L34.47 -4.23Q34.47 -4.45 34.48 -4.96Q34.49 -5.47 34.49 -6.05L32.45 -0.00L31.48 -0.00L29.42 -6.05L29.42 -5.83Q29.42 -5.57 29.44 -5.03Q29.45 -4.49 29.45 -4.23L29.45 -0.00L28.52 -0.00ZM36.97 -7.17L42.20 -7.17L42.20 -6.29L37.92 -6.29L37.92 -4.12L41.88 -4.12L41.88 -3.29L37.92 -3.29L37.92 -0.85L42.27 -0.85L42.27 -0.00L36.97 -0.00ZM43.64 -1.06L44.66 -1.06L44.66 -0.00L43.64 -0.00ZM46.21 -5.23L47.08 -5.23L47.08 -4.49Q47.39 -4.87 47.64 -5.05Q48.08 -5.35 48.63 -5.35Q49.25 -5.35 49.63 -5.04Q49.85 -4.86 50.02 -4.52Q50.32 -4.94 50.71 -5.14Q51.11 -5.35 51.60 -5.35Q52.66 -5.35 53.04 -4.58Q53.24 -4.17 53.24 -3.48L53.24 -0.00L52.33 -0.00L52.33 -3.63Q52.33 -4.16 52.07 -4.35Q51.81 -4.55 51.43 -4.55Q50.91 -4.55 50.54 -4.20Q50.17 -3.85 50.17 -3.04L50.17 -0.00L49.27 -0.00L49.27 -3.41Q49.27 -3.95 49.15 -4.19Q48.95 -4.56 48.40 -4.56Q47.90 -4.56 47.49 -4.17Q47.08 -3.78 47.08 -2.77L47.08 -0.00L46.21 -0.00ZM55.09 -2.55Q55.09 -1.71 55.45 -1.15Q55.81 -0.58 56.59 -0.58Q57.20 -0.58 57.60 -1.11Q57.99 -1.63 57.99 -2.61Q57.99 -3.60 57.58 -4.08Q57.18 -4.56 56.58 -4.56Q55.92 -4.56 55.51 -4.05Q55.09 -3.54 55.09 -2.55ZM56.42 -5.32Q57.02 -5.32 57.42 -5.07Q57.66 -4.92 57.95 -4.56L57.95 -7.20L58.80 -7.20L58.80 -0.00L58.01 -0.00L58.01 -0.73Q57.70 -0.24 57.28 -0.03Q56.86 0.19 56.32 0.19Q55.44 0.19 54.80 -0.55Q54.17 -1.28 54.17 -2.50Q54.17 -3.65 54.75 -4.48Q55.33 -5.32 56.42 -5.32Z" fill="#7A8494"/><path transform="translate(348 102) scale(0.78)" d="M4.56 -17.86L4.56 -5.24C3.44 -4.93 2.30 -4.62 1.12 -4.34L1.90 -1.71C5.10 -2.58 7.92 -3.53 10.39 -4.54L10.39 -7.20C9.38 -6.80 8.34 -6.41 7.25 -6.05L7.25 -17.86L10.28 -17.86L10.28 -20.44L1.46 -20.44L1.46 -17.86L4.56 -17.86ZM11.17 -21.98L11.17 -19.40L17.72 -19.40C17.61 -18.59 17.44 -17.81 17.22 -17.02L12.24 -17.02L12.24 -3.47L14.78 -3.47L14.78 -14.56L23.16 -14.56L23.16 -3.47L25.73 -3.47L25.73 -17.02L19.85 -17.02C20.02 -17.78 20.19 -18.56 20.33 -19.40L26.85 -19.40L26.85 -21.98L11.17 -21.98ZM21.56 -3.64L19.80 -1.93C22.15 -0.14 23.97 1.51 25.26 3.05L27.16 1.15C25.65 -0.42 23.80 -2.02 21.56 -3.64ZM17.56 -13.16L17.56 -8.26C17.44 -5.96 16.80 -4.09 15.68 -2.63C14.50 -1.29 12.26 -0.17 9.02 0.73L10.47 3.00C13.83 2.04 16.24 0.76 17.72 -0.92C19.24 -2.77 20.08 -5.24 20.22 -8.26L20.22 -13.16L17.56 -13.16ZM51.77 -21.81L32.26 -21.81L32.26 2.91L34.97 2.91L34.97 1.20L49.08 1.20L49.08 2.86L51.77 2.86L51.77 -21.81ZM34.97 -1.37L34.97 -6.02L49.08 -6.02L49.08 -1.37L34.97 -1.37ZM34.97 -8.43L34.97 -12.74L49.08 -12.74L49.08 -8.43L34.97 -8.43ZM34.97 -15.20L34.97 -19.24L49.08 -19.24L49.08 -15.20L34.97 -15.20ZM65.86 -20.86L65.86 -18.45L72.74 -18.45L72.74 -16.58L66.75 -16.58L66.75 -9.07L71.20 -9.07C69.92 -7.14 67.87 -5.46 65.07 -4.03L66.72 -1.93C69.33 -3.56 71.34 -5.46 72.74 -7.64L72.74 -0.84L75.24 -0.84L75.24 -9.07L81.23 -9.07L81.23 -16.58L75.24 -16.58L75.24 -18.45L82.07 -18.45L82.07 -20.86L75.24 -20.86L75.24 -22.88L72.74 -22.88L72.74 -20.86L65.86 -20.86ZM78.79 -11.37L75.24 -11.37L75.24 -14.28L78.79 -14.28L78.79 -11.37ZM72.74 -11.37L69.22 -11.37L69.22 -14.28L72.74 -14.28L72.74 -11.37ZM77.56 -8.51L75.85 -6.89C77.81 -5.26 79.35 -3.72 80.47 -2.30L82.24 -4.03C80.95 -5.54 79.41 -7.03 77.56 -8.51ZM59.78 -22.68L57.96 -20.94C60.00 -19.32 61.57 -17.81 62.69 -16.41L64.57 -18.26C63.28 -19.71 61.68 -21.20 59.78 -22.68ZM75.85 2.41L82.26 2.41L82.94 -0.22C82.15 -0.17 81.06 -0.11 79.66 -0.08C78.26 -0.06 76.86 -0.03 75.49 -0.03C73.30 -0.03 71.40 -0.06 69.83 -0.08C68.18 -0.14 66.95 -0.39 66.11 -0.78C65.41 -1.15 64.74 -1.71 64.09 -2.46C63.95 -2.63 63.81 -2.77 63.67 -2.88L63.67 -13.47L57.43 -13.47L57.43 -11.00L61.18 -11.00L61.18 -3.08C60.06 -2.52 58.80 -1.09 57.40 1.18L59.36 3.00C60.79 0.48 61.80 -0.78 62.38 -0.78C62.72 -0.78 63.06 -0.56 63.45 -0.08C64.29 0.87 65.27 1.54 66.39 1.88C67.54 2.16 69.02 2.32 70.84 2.35C72.63 2.38 74.31 2.41 75.85 2.41ZM111.24 -4.96L108.58 -5.85CLine truncated
|
||||
<path d="M348 184H581" stroke="#E6EAF1"/>
|
||||
<rect x="348" y="204" width="158" height="42" rx="6" fill="#EEF2FF"/>
|
||||
<image x="366" y="215" width="121" height="20.0" href="data:image/png;base64,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 truncated
|
||||
<path transform="translate(36 131)" d="M16.48 -17.32Q13.73 -11.00 8.45 -6.89L8.14 -7.20Q13.78 -13.31 15.18 -20.02L17.52 -19.06Q17.78 -18.93 17.78 -18.80Q17.78 -18.67 17.47 -18.50Q17.16 -18.33 16.95 -18.07Q18.28 -15.03 20.21 -13.26Q22.15 -11.49 25.17 -10.66L25.14 -10.32Q24.41 -10.14 23.95 -9.89Q23.48 -9.65 23.27 -9.27Q23.06 -8.89 22.91 -8.89Q22.52 -8.89 20.06 -11.23Q17.60 -13.57 16.48 -17.32ZM5.98 -9.65Q2.94 -9.15 2.34 -8.89Q1.74 -8.63 1.62 -8.63Q1.51 -8.63 1.43 -8.81L0.70 -10.40Q1.46 -10.69 1.77 -10.95Q2.08 -11.21 2.81 -12.58Q3.54 -13.96 4.32 -15.98Q5.10 -17.99 5.38 -19.63L7.51 -17.94Q7.85 -17.65 7.85 -17.52Q7.85 -17.39 7.51 -17.34Q6.99 -17.26 6.50 -16.43Q4.71 -13.39 2.55 -10.40L6.40 -10.43Q7.51 -12.66 8.53 -15.11L10.48 -13.73Q10.79 -13.49 10.79 -13.32Q10.79 -13.16 10.48 -13.08Q9.78 -12.87 9.20 -11.91Q7.72 -9.41 3.95 -4.68L9.80 -5.41L9.85 -4.94Q3.48 -2.99 2.57 -2.60Q2.42 -2.52 2.30 -2.52Q2.18 -2.52 2.11 -2.73L1.61 -4.24Q2.05 -4.34 2.57 -4.71Q3.09 -5.07 4.15 -6.66Q5.20 -8.24 5.98 -9.65ZM13.83 -9.62L17.94 -9.62L19.24 -11.13L20.72 -9.33Q20.93 -9.07 20.93 -8.97Q20.93 -8.87 20.54 -8.87L14.43 -8.87Q13.36 -8.87 12.66 -8.58L11.67 -9.75Q12.66 -9.62 13.83 -9.62ZM13.88 -5.69L19.29 -5.69L20.12 -6.97L21.97 -5.59Q22.18 -5.43 22.18 -5.29Q22.18 -5.15 21.87 -4.97L21.45 -4.68L21.45 0.16Q21.45 1.09 21.50 1.85L21.61 3.07Q21.61 3.59 20.80 3.94Q19.99 4.29 19.82 4.29Q19.66 4.29 19.66 3.93L19.66 1.53L13.42 1.53L13.42 3.30Q13.42 3.72 13.27 3.90Q13.13 4.08 12.52 4.32Q11.91 4.55 11.70 4.55Q11.49 4.55 11.41 4.39Q11.34 4.24 11.41 3.69Q11.62 1.56 11.62 -0.39L11.62 -3.74Q11.62 -5.49 11.54 -6.92ZM19.66 0.81L19.66 -4.97L13.42 -4.97L13.42 0.81ZM10.71 -0.91L5.28 1.33Q3.48 2.05 2.90 2.33Q2.31 2.60 2.22 2.60Q2.13 2.60 2.05 2.44L0.96 0.49L10.50 -1.43ZM31.93 -11.05Q29.82 -7.93 27.80 -5.93L27.43 -6.21Q32.27 -13.26 33.96 -19.86L36.22 -18.80Q36.64 -18.59 36.64 -18.39Q36.64 -18.20 36.21 -18.07Q35.78 -17.94 35.31 -16.98Q34.06 -14.48 32.63 -12.14L34.01 -11.57Q34.40 -11.41 34.40 -11.26Q34.40 -11.10 34.14 -10.92L33.78 -10.63L33.78 -1.90Q33.78 0.60 33.81 1.72Q33.85 2.83 33.85 2.91Q33.85 3.38 33.04 3.82Q32.22 4.26 32.01 4.26Q31.70 4.26 31.70 3.87Q31.70 3.48 31.72 3.25Q31.80 2.60 31.87 0.62Q31.93 -1.35 31.93 -2.44ZM42.93 -8.68L47.17 -8.68L48.54 -10.35L50.21 -8.40Q50.36 -8.22 50.36 -8.09Q50.36 -7.96 50.00 -7.96L42.93 -7.96L42.93 -3.20L47.87 -3.20L49.35 -4.89L51.01 -2.91Q51.20 -2.70 51.20 -2.57Q51.20 -2.44 50.83 -2.44L42.93 -2.44Q42.93 0.47 42.98 1.74Q43.03 3.02 43.03 3.09Q43.03 3.69 42.16 4.03Q41.29 4.37 41.04 4.37Q40.80 4.37 40.80 3.87L40.95 1.12Q41.03 -0.73 41.03 -2.29L41.03 -13.65L39.89 -13.65Q37.49 -9.62 34.61 -6.73L34.22 -6.99Q38.43 -12.74 40.48 -19.76L42.90 -18.46Q43.27 -18.28 43.27 -18.12Q43.27 -17.97 42.93 -17.86Q42.15 -17.65 41.68 -16.77L40.33 -14.38L48.18 -14.38L49.77 -16.22L51.59 -14.12Q51.74 -13.91 51.74 -13.78Q51.74 -13.65 51.38 -13.65L42.93 -13.65ZM61.96 -18.04L69.92 -18.04L70.91 -19.24L72.67 -17.89Q72.99 -17.63 72.99 -17.50Q72.99 -17.37 72.67 -17.19L72.10 -16.82L72.10 -13.47Q72.10 -12.48 72.18 -11.70L72.28 -10.53Q72.28 -10.06 71.50 -9.71Q70.72 -9.36 70.52 -9.36Q70.31 -9.36 70.31 -9.70L70.31 -10.71L61.88 -10.71L61.88 -10.06Q61.88 -9.41 61.08 -9.09Q60.27 -8.76 60.03 -8.76Q59.78 -8.76 59.78 -9.05Q59.78 -9.33 59.80 -9.62Q59.99 -10.87 59.99 -12.58L59.99 -15.99Q59.99 -17.68 59.91 -19.14ZM70.31 -11.44L70.31 -17.29L61.88 -17.29L61.88 -11.44ZM69.42 -7.12L73.97 -7.12L74.81 -8.27L76.70 -7.07Q76.94 -6.92 76.94 -6.79Q76.94 -6.66 76.76 -6.47L76.13 -5.98L76.13 -1.12Q76.13 -0.18 76.18 0.57L76.26 1.87Q76.26 2.31 75.51 2.65Q74.75 2.99 74.56 2.99Q74.36 2.99 74.36 2.65L74.36 0.91L69.42 0.91L69.42 2.37Q69.42 2.73 69.27 2.92Q69.11 3.12 68.51 3.39Q67.92 3.67 67.71 3.67Q67.50 3.67 67.45 3.48Q67.40 3.30 67.45 2.76Q67.68 0.62 67.68 -1.30L67.68 -5.12Q67.68 -6.84 67.58 -8.29ZM74.36 0.18L74.36 -6.40L69.42 -6.40L69.42 0.18ZM58.06 -6.97L62.61 -6.97L63.47 -8.14L65.08 -6.92Q65.42 -6.68 65.42 -6.54Q65.42 -6.40 65.24 -6.21L64.64 -5.75L64.64 -1.40Q64.64 -0.42 64.69 0.36L64.77 1.53Q64.77 2.03 64.03 2.37Q63.29 2.70 63.09 2.70Q62.90 2.70 62.90 2.37L62.90 1.04L57.98 1.04L57.98 2.76Q57.98 3.22 57.76 3.39Q57.54 3.56 57.00 3.81Q56.45 4.06 56.22 4.06Q55.98 4.06 55.98 3.76Q55.98 3.46 56.03 3.15Q56.24 1.01 56.24 -0.91L56.24 -4.94Q56.24 -6.66 56.16 -8.11ZM62.90 0.31L62.90 -6.21L57.98 -6.21L57.98 0.31ZM85.10 -17.32Q86.66 -17.78 89.97 -19.81L91.21 -18.46Q91.45 -18.25 91.45 -18.07Q91.45 -17.78 91.01 -17.89Q90.82 -17.91 90.67 -17.91Q90.30 -17.91 89.16 -17.63Q86.27 -16.87 85.21 -16.72L85.21 -11.00L89.42 -12.69Q88.77 -14.07 87.86 -15.08L88.07 -15.47Q89.71 -14.56 90.62 -13.81Q91.53 -13.05 91.53 -12.29Q91.53 -11.52 91.24 -11.06Q90.95 -10.61 90.55 -10.61Q90.15 -10.61 89.95 -11.28Q89.76 -11.96 89.65 -12.17L85.60 -9.49Q84.79 -8.94 84.49 -8.55Q84.19 -8.16 84.01 -8.16Q83.83 -8.16 83.67 -8.45L82.92 -9.59Q83.54 -10.11 83.54 -10.89L83.54 -15.99Q83.54 -17.39 83.44 -18.33ZM96.65 -16.72Q96.31 -12.66 94.65 -10.52Q92.98 -8.37 89.45 -7.23L89.26 -7.67Q91.97 -9.02 93.23 -11.02Q94.49 -13.03 94.93 -16.72L93.53 -1Line truncated
|
||||
|
||||
|
||||
<!-- Magnified detail of the unchanged official badge in the document footer. -->
|
||||
<path d="M354 220H322Q306 220 306 236Q306 250 290 250H266" stroke="#8FA5F1" stroke-width="1.5"/>
|
||||
<circle cx="354" cy="220" r="2.5" fill="#6B86E7"/>
|
||||
<rect x="32" y="216" width="228" height="72" rx="10" fill="#E2E8FC"/>
|
||||
<rect x="38" y="210" width="228" height="72" rx="10" fill="#FFF" stroke="#D3DCF0"/>
|
||||
<image x="55" y="230" width="193.6" height="32" href="data:image/png;base64,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 truncated
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 68 KiB |
@@ -6294,7 +6294,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
},
|
||||
{
|
||||
name: 'PluginLocalizedMeta',
|
||||
declaration: 'export interface PluginLocalizedMeta {\n readonly title?: LocalizedText;\n readonly description?: LocalizedText;\n readonly icon?: string;\n readonly preview?: string;\n readonly error?: string;\n}',
|
||||
declaration: 'export interface PluginLocalizedMeta {\n readonly title?: LocalizedText;\n readonly description?: LocalizedText;\n readonly icon?: string;\n readonly preview?: LocalizedText;\n readonly error?: string;\n}',
|
||||
},
|
||||
{
|
||||
name: 'PluginOptions',
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
en: d152484eb41ac6b4
|
||||
zh: 1db86285abf6c499
|
||||
/deepseek-ai-dsh-package-manifest/use-this-package:
|
||||
en: 043740e276a0fd5c
|
||||
zh: d825e0c613ddeccf
|
||||
en: 801f4f07a2159bc5
|
||||
zh: 7be0f86a03864e31
|
||||
/deepseek-ai-dsh-package-manifest/understand-the-implementation:
|
||||
en: 41ec449dee927f04
|
||||
zh: ec1b583bd9025d84
|
||||
|
||||
@@ -56,7 +56,7 @@ The following metadata fields are optional. Omitting them leaves the format vers
|
||||
|
||||
Public composition declarations are defined in [`src/types.ts`](src/types.ts). Internal `configTrees`, `sessionFormatMigration`, and generated `moduleFallback` metadata remain owned by their image-packer, catalog, and launcher readers; the public types do not expose them.
|
||||
|
||||
`DshPackageManifest.preview` optionally names a feature image, and `PluginLocalizedMeta.preview` carries its resolved data URL. It is independent of the small `icon` and is omitted when no preview is supplied.
|
||||
`DshPackageManifest.preview` optionally names a feature image or maps language ids to image paths with an English fallback. `PluginLocalizedMeta.preview` carries the corresponding data URL or language map, resolved by the UI like localized text. It is independent of the small `icon` and is omitted when no preview is supplied.
|
||||
|
||||
-----
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ const manifest: DshPackageManifest = {
|
||||
|
||||
公共组合声明定义在 [`src/types.ts`](src/types.ts) 中。内部 `configTrees`、`sessionFormatMigration` 和生成的 `moduleFallback` 元数据分别由镜像打包器、目录生成器和启动器读取方拥有;公共类型不暴露这些字段。
|
||||
|
||||
`DshPackageManifest.preview` 可选地指定功能配图,`PluginLocalizedMeta.preview` 携带解析后的 data URL。它与小尺寸 `icon` 相互独立;未提供配图时省略。
|
||||
`DshPackageManifest.preview` 可选地指定功能配图,或将语言标识映射到图片路径并提供英文回退。`PluginLocalizedMeta.preview` 携带对应的 data URL 或语言映射,界面像本地化文本一样解析。它与小尺寸 `icon` 相互独立;未提供配图时省略。
|
||||
|
||||
-----
|
||||
|
||||
|
||||
@@ -14,8 +14,11 @@ export interface DshPackageManifest {
|
||||
description?: string
|
||||
/** SVG, PNG, JPEG, or WebP file relative to this manifest's directory, at most 256 KiB and contained there after realpath resolution. */
|
||||
icon?: string
|
||||
/** Feature preview image relative to this manifest, SVG/PNG/JPEG/WebP up to 1 MiB and contained in its directory. */
|
||||
preview?: string
|
||||
/**
|
||||
* Feature image path, or language-to-path map with an English fallback.
|
||||
* SVG/PNG/JPEG/WebP files stay in this directory, up to 1 MiB total.
|
||||
*/
|
||||
preview?: LocalizedText
|
||||
/** Prevent npm publication, for example for local profile projects. */
|
||||
private?: boolean
|
||||
/** Packages installed alongside this package. */
|
||||
@@ -51,8 +54,8 @@ export interface PluginLocalizedMeta {
|
||||
readonly description?: LocalizedText
|
||||
/** Base64 image data URL from a package root's manifest icon or an exported `<specifier>/icon`; render as an image, not inline markup. */
|
||||
readonly icon?: string
|
||||
/** Base64 image data URL for the bundle detail preview; read without enabling the plugin and rendered as an image. */
|
||||
readonly preview?: string
|
||||
/** Base64 image data URL or language-to-data-URL map with an English fallback; read before activation and rendered as an image. */
|
||||
readonly preview?: LocalizedText
|
||||
/** Unmodified local metadata diagnostic; the plugin remains manageable. */
|
||||
readonly error?: string
|
||||
}
|
||||
|
||||
@@ -312,7 +312,13 @@ describe('package payload constraints', () => {
|
||||
])
|
||||
})
|
||||
|
||||
it.each(['icon.svg', 'preview.svg'])('accepts the badge skill artwork payload and rejects omission of %s', (image) => {
|
||||
it('includes each localized preview in the published payload without duplicate paths', () => {
|
||||
expect(expectedDshPackageFiles({ preview: { en: './preview.svg', zh: './preview.zh.svg', fr: './preview.svg' } })).toEqual([
|
||||
'preview.svg', 'preview.zh.svg', 'lib/index.js', 'lib/types/**/*.d.ts',
|
||||
])
|
||||
})
|
||||
|
||||
it.each(['icon.svg', 'preview.svg', 'preview.zh.svg'])('accepts the badge skill artwork payload and rejects omission of %s', (image) => {
|
||||
const dir = 'packages/experimental/badge-skill-bundle'
|
||||
const manifest = JSON.parse(readFileSync(new URL(`../${dir}/package.json`, import.meta.url), 'utf8')) as WorkspaceManifest['manifest']
|
||||
expect(checkWorkspaceManifest({ dir, manifest })).toEqual([])
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
PRIVATE_EXPERIMENTAL_PACKAGE_DIRECTORIES,
|
||||
} from './experimental-package-policy.ts'
|
||||
import { hasTypertRemoteNavigation, isForbiddenPublicationFile } from './publication-payload.ts'
|
||||
import type { DshBundleManifest } from '../packages/util/package-manifest/src/types.ts'
|
||||
import type { DshBundleManifest, LocalizedText } from '../packages/util/package-manifest/src/types.ts'
|
||||
import { OPTIONAL_BUNDLES, bundlePatchFiles } from '../packages/boot/app-boot/src/profile.ts'
|
||||
import { collectProjectReferenceFaceViolations } from './project-reference-faces.ts'
|
||||
|
||||
@@ -85,7 +85,7 @@ export interface PackageManifest {
|
||||
exports?: Record<string, ExportTarget | undefined>
|
||||
files?: string[]
|
||||
icon?: string
|
||||
preview?: string
|
||||
preview?: LocalizedText
|
||||
publishConfig?: { access?: string }
|
||||
repository?: { type?: string; url?: string; directory?: string }
|
||||
peerDependencies?: Record<string, string>
|
||||
@@ -259,7 +259,7 @@ export function expectedDshPackageFiles(manifest: PackageManifest): readonly str
|
||||
const targets = (value: ExportTarget | undefined): string[] => typeof value === 'string' ? [value]
|
||||
: typeof value === 'object' && value !== null ? Object.values(value).flatMap(targets) : []
|
||||
const images = [
|
||||
...[manifest.icon, manifest.preview].flatMap(image => typeof image === 'string' ? [image.replace(/^\.\//u, '')] : []),
|
||||
...[manifest.icon, manifest.preview].flatMap(targets).map(image => image.replace(/^\.\//u, '')),
|
||||
...Object.entries(manifest.exports ?? {}).filter(([key]) => /^\.\/(?:.+\/)?(?:icon|preview)$/u.test(key))
|
||||
.flatMap(([, target]) => targets(target)).filter(icon => icon.startsWith('./')).map(icon => icon.slice(2)),
|
||||
]
|
||||
|
||||
@@ -67,6 +67,19 @@ describe('Official bundle catalog generation', () => {
|
||||
expect(renderOfficialBundleCatalog(entries)).toContain(`preview: '${preview}'`)
|
||||
})
|
||||
|
||||
it('preserves translated preview images in offline discovery', () => {
|
||||
const root = fixture()
|
||||
const name = ON_DEMAND_BUNDLES[0]!
|
||||
updateManifest(root, name, { preview: { en: './preview.png', zh: './preview.zh.png' } })
|
||||
write(root, `${directory(name)}/preview.png`, 'English')
|
||||
write(root, `${directory(name)}/preview.zh.png`, '中文')
|
||||
const entries = generateOfficialBundleCatalog(root)
|
||||
const en = `data:image/png;base64,${Buffer.from('English').toString('base64')}`
|
||||
const zh = `data:image/png;base64,${Buffer.from('中文').toString('base64')}`
|
||||
expect(entries[0]?.meta.preview).toEqual({ en, zh })
|
||||
expect(renderOfficialBundleCatalog(entries)).toContain(`preview: { 'en': '${en}', 'zh': '${zh}' }`)
|
||||
})
|
||||
|
||||
it.each(['private', 'not-bundle', 'missing', 'duplicate'])('rejects %s catalog membership', (kind) => {
|
||||
const root = fixture()
|
||||
const name = ON_DEMAND_BUNDLES[0]!
|
||||
|
||||
@@ -95,7 +95,7 @@ export function renderOfficialBundleCatalog(entries: readonly OfficialBundleCata
|
||||
+ ` title: ${localized(entry.meta.title)},\n`
|
||||
+ ` description: ${localized(entry.meta.description)},\n`
|
||||
+ ` icon: ${quote(entry.meta.icon)},\n`
|
||||
+ (entry.meta.preview === undefined ? '' : ` preview: ${quote(entry.meta.preview)},\n`)
|
||||
+ (entry.meta.preview === undefined ? '' : ` preview: ${localized(entry.meta.preview)},\n`)
|
||||
+ ' },\n },\n').join('')
|
||||
+ ']\n'
|
||||
}
|
||||
|
||||
@@ -67,6 +67,18 @@ it('requires optional preview files to be published', () => {
|
||||
expect(packageMetaProblems(root)).toEqual([`${join(dir, 'package.json')}: files must include preview.png`])
|
||||
})
|
||||
|
||||
it('validates every localized preview and requires each variant in the published package', () => {
|
||||
const preview = { en: './preview.svg', ZH: './preview.zh.svg' }
|
||||
manifest({ preview, files: ['preview.svg'] })
|
||||
file('preview.svg', validSvg)
|
||||
file('preview.zh.svg', validSvg)
|
||||
expect(packageMetaProblems(root)).toEqual([`${join(dir, 'package.json')}: files must include preview.zh.svg`])
|
||||
manifest({ preview, files: ['preview*.svg'] })
|
||||
expect(packageMetaProblems(root)).toEqual([])
|
||||
file('preview.zh.svg', validSvg.replace('<path ', '<script>run()</script><path '))
|
||||
expect(packageMetaProblems(root).join('\n')).toContain('preview.zh.svg: SVG preview must use self-contained geometry')
|
||||
})
|
||||
|
||||
it('requires preview declarations to be discoverable', () => {
|
||||
manifest({ preview: './preview.png', exports: { '.': './lib/index.js' }, files: ['preview.png'] })
|
||||
file('preview.png', 'image')
|
||||
|
||||
@@ -198,16 +198,21 @@ function packageProblems(manifestPath: string, parser: DOMParser): string[] {
|
||||
if (sourceManifest && resources.every(({ file }) => byPath.has(file))) {
|
||||
const meta = readPluginMeta(specifier, parentURL)
|
||||
if (meta?.error !== undefined) problems.push(meta.error)
|
||||
const imageTargets = imageFields.map((field) => {
|
||||
const imageTargets = imageFields.flatMap((field) => {
|
||||
const image = meta?.[field]
|
||||
if (image === undefined) return undefined
|
||||
const path = displayDocument?.[field]
|
||||
const target = displayManifest !== undefined && typeof path === 'string'
|
||||
? resolve(dirname(displayManifest), path) : lookup(`${specifier}/${field}`)
|
||||
if (pkg.name.startsWith('@deepseek-ai/dsh-')) {
|
||||
problems.push(...svgArtworkProblems(image, parser, field).map(problem => `${target ?? specifier}: ${problem}`))
|
||||
}
|
||||
return target
|
||||
if (image === undefined) return []
|
||||
const declaration = displayDocument?.[field]
|
||||
const variants = typeof image === 'string' ? [['', image] as const] : Object.entries(image)
|
||||
return variants.map(([language, data]) => {
|
||||
const path: unknown = typeof declaration === 'object' && declaration !== null
|
||||
? Object.entries(declaration).find(([key]) => key.toLowerCase() === language)?.[1] : declaration
|
||||
const target = displayManifest !== undefined && typeof path === 'string'
|
||||
? resolve(dirname(displayManifest), path) : lookup(`${specifier}/${field}`)
|
||||
if (pkg.name.startsWith('@deepseek-ai/dsh-')) {
|
||||
problems.push(...svgArtworkProblems(data, parser, field).map(problem => `${target ?? specifier}: ${problem}`))
|
||||
}
|
||||
return target
|
||||
})
|
||||
})
|
||||
for (const target of [displayManifest, ...imageTargets]) {
|
||||
if (target === undefined) continue
|
||||
|
||||
Reference in new issue
Block a user