@spunto/design-system 0.9.3 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -4
- package/package.json +9 -1
- package/src/components/command-palette.tsx +702 -0
- package/src/components/devcontainer/catalog-card.tsx +269 -0
- package/src/components/devcontainer/catalog-tile.tsx +133 -0
- package/src/components/devcontainer/extension-card.tsx +146 -0
- package/src/components/devcontainer/feature-card.tsx +157 -0
- package/src/components/devcontainer/feature-tile.tsx +63 -0
- package/src/components/devcontainer/image-card.tsx +107 -0
- package/src/components/devcontainer/image-tile.tsx +56 -0
- package/src/components/devcontainer/index.ts +68 -0
- package/src/components/devcontainer/publisher-badge.tsx +91 -0
- package/src/components/devcontainer/registry-ref.tsx +89 -0
- package/src/components/devcontainer/registry.ts +154 -0
- package/src/components/devcontainer/stack-mark-paths.ts +60 -0
- package/src/components/devcontainer/stack-mark.tsx +92 -0
- package/src/components/devcontainer/types.ts +84 -0
- package/src/components/kbd.tsx +117 -0
- package/src/components/projects/advanced-sections.tsx +136 -0
- package/src/components/projects/build-manifest.tsx +116 -0
- package/src/components/projects/extension-picker.tsx +169 -0
- package/src/components/projects/feature-picker.tsx +193 -0
- package/src/components/projects/form-section.tsx +97 -0
- package/src/components/projects/image-picker.tsx +206 -0
- package/src/components/projects/index.ts +58 -0
- package/src/components/projects/project-form.tsx +488 -0
- package/src/components/projects/repo-list.tsx +302 -0
- package/src/components/projects/secret-list.tsx +159 -0
- package/src/components/projects/types.ts +136 -0
- package/src/index.ts +35 -0
- package/styles.css +13 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// Pure helpers: what an OCI reference says about who publishes it.
|
|
2
|
+
//
|
|
3
|
+
// None of the catalogs carry an author today (`DevImage` is `{id, label, image,
|
|
4
|
+
// description}`), and adding one to the API would only move the problem for
|
|
5
|
+
// hand-typed refs, which have no catalog entry at all. So the author is
|
|
6
|
+
// *derived* from the reference itself — `ghcr.io/<owner>/…` is an owner on
|
|
7
|
+
// GitHub, `mcr.microsoft.com/devcontainers/…` is the Dev Containers team — and
|
|
8
|
+
// the `publisher` prop stays as an override for the day the API knows better.
|
|
9
|
+
//
|
|
10
|
+
// Everything here is a pure function on a string: no fetch, no React. That's
|
|
11
|
+
// what lets the cards stay presentational and the showcase draw them from
|
|
12
|
+
// hand-written fixtures.
|
|
13
|
+
|
|
14
|
+
import type { CatalogPublisher } from "./types"
|
|
15
|
+
|
|
16
|
+
export interface ParsedRegistryRef {
|
|
17
|
+
/** Registry host — `ghcr.io`, `mcr.microsoft.com`. Absent = implicit Docker Hub. */
|
|
18
|
+
registry?: string
|
|
19
|
+
/** First path segment under the registry: the org/owner (`devcontainers`, `coderhammer`). */
|
|
20
|
+
owner?: string
|
|
21
|
+
/** Segments between the owner and the name (`features` in `ghcr.io/x/features/node`). */
|
|
22
|
+
path: string[]
|
|
23
|
+
/** Last path segment, tag and digest stripped. */
|
|
24
|
+
name?: string
|
|
25
|
+
tag?: string
|
|
26
|
+
digest?: string
|
|
27
|
+
/** The ref without its tag/digest — `ghcr.io/devcontainers/features/node`. */
|
|
28
|
+
repository: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const EMPTY: ParsedRegistryRef = { path: [], repository: "" }
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Split an image/feature reference into its parts.
|
|
35
|
+
*
|
|
36
|
+
* Deliberately tolerant: an unparseable string comes back with everything
|
|
37
|
+
* `undefined` rather than throwing, because one of the three call sites is a
|
|
38
|
+
* free-text input the user is still typing into.
|
|
39
|
+
*/
|
|
40
|
+
export function parseRegistryRef(ref?: string | null): ParsedRegistryRef {
|
|
41
|
+
const raw = ref?.trim()
|
|
42
|
+
if (!raw) return EMPTY
|
|
43
|
+
|
|
44
|
+
const [beforeDigest, digest] = splitOnce(raw, "@")
|
|
45
|
+
const segments = beforeDigest.split("/").filter(Boolean)
|
|
46
|
+
if (segments.length === 0) return EMPTY
|
|
47
|
+
|
|
48
|
+
// A first segment is a registry host only if it looks like one: a dot (a
|
|
49
|
+
// domain), a colon (a port) or literally localhost. Otherwise it's a Docker
|
|
50
|
+
// Hub namespace — `library/node` is a repository, not a host.
|
|
51
|
+
const first = segments[0]
|
|
52
|
+
const hasRegistry = segments.length > 1 && (first.includes(".") || first.includes(":") || first === "localhost")
|
|
53
|
+
const registry = hasRegistry ? first : undefined
|
|
54
|
+
const pathSegments = hasRegistry ? segments.slice(1) : segments
|
|
55
|
+
|
|
56
|
+
const last = pathSegments[pathSegments.length - 1] ?? ""
|
|
57
|
+
const [namePart, tag] = splitOnce(last, ":")
|
|
58
|
+
const middle = pathSegments.slice(0, -1)
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
registry,
|
|
62
|
+
owner: middle[0],
|
|
63
|
+
path: middle.slice(1),
|
|
64
|
+
name: namePart || undefined,
|
|
65
|
+
tag: tag || undefined,
|
|
66
|
+
digest: digest || undefined,
|
|
67
|
+
repository: [registry, ...middle, namePart].filter(Boolean).join("/"),
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function splitOnce(value: string, separator: string): [string, string | undefined] {
|
|
72
|
+
const at = value.lastIndexOf(separator)
|
|
73
|
+
if (at < 0) return [value, undefined]
|
|
74
|
+
const rest = value.slice(at + 1)
|
|
75
|
+
// A colon in a path segment is a port, not a tag: `localhost:5000/node`.
|
|
76
|
+
if (separator === ":" && rest.includes("/")) return [value, undefined]
|
|
77
|
+
return [value.slice(0, at), rest]
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* GitHub org behind a `ghcr.io/<owner>/…` ref — `undefined` for any other
|
|
82
|
+
* registry. That single mapping covers the whole feature catalog today
|
|
83
|
+
* (`devcontainers`, `coderhammer`, `stu-bell`).
|
|
84
|
+
*/
|
|
85
|
+
export function githubOwner(ref?: string | null): string | undefined {
|
|
86
|
+
const parsed = parseRegistryRef(ref)
|
|
87
|
+
return parsed.registry === "ghcr.io" ? parsed.owner : undefined
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Avatar of a GitHub account. `github.com/<login>.png` 302s to
|
|
92
|
+
* avatars.githubusercontent.com, so it works straight in an `<img>` — no API
|
|
93
|
+
* call, no token, no id to look up.
|
|
94
|
+
*/
|
|
95
|
+
export function githubAvatarUrl(login: string, size = 80): string {
|
|
96
|
+
return `https://github.com/${encodeURIComponent(login)}.png?size=${size}`
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Registries whose publisher we can name without asking anyone. */
|
|
100
|
+
const KNOWN_REGISTRIES: Record<string, (parsed: ParsedRegistryRef) => CatalogPublisher | undefined> = {
|
|
101
|
+
"ghcr.io": (parsed) =>
|
|
102
|
+
parsed.owner
|
|
103
|
+
? { name: parsed.owner, login: parsed.owner, avatarUrl: githubAvatarUrl(parsed.owner) }
|
|
104
|
+
: undefined,
|
|
105
|
+
"mcr.microsoft.com": (parsed) =>
|
|
106
|
+
parsed.owner === "devcontainers"
|
|
107
|
+
? { name: "Dev Containers", login: "devcontainers", avatarUrl: githubAvatarUrl("devcontainers"), verified: true }
|
|
108
|
+
: { name: "Microsoft", login: "microsoft", avatarUrl: githubAvatarUrl("microsoft"), verified: true },
|
|
109
|
+
"quay.io": (parsed) => (parsed.owner ? { name: parsed.owner, login: parsed.owner } : undefined),
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Who publishes this ref, as far as the ref itself admits. `undefined` when
|
|
114
|
+
* nothing is derivable — the caller then falls back to a monogram, which is the
|
|
115
|
+
* honest answer for `my-registry.internal/team/thing:1`.
|
|
116
|
+
*/
|
|
117
|
+
export function derivePublisher(ref?: string | null): CatalogPublisher | undefined {
|
|
118
|
+
const parsed = parseRegistryRef(ref)
|
|
119
|
+
if (!parsed.registry) return parsed.owner ? { name: parsed.owner, login: parsed.owner } : undefined
|
|
120
|
+
const known = KNOWN_REGISTRIES[parsed.registry]
|
|
121
|
+
if (known) return known(parsed)
|
|
122
|
+
return parsed.owner ? { name: parsed.owner, login: parsed.owner } : undefined
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** `12 400 000` → `12.4M`. Open VSX download counts, at a glance. */
|
|
126
|
+
export function formatCount(value?: number | null): string | undefined {
|
|
127
|
+
if (value == null || !Number.isFinite(value) || value < 0) return undefined
|
|
128
|
+
if (value < 1000) return String(Math.round(value))
|
|
129
|
+
if (value < 1_000_000) return `${trim(value / 1000)}k`
|
|
130
|
+
return `${trim(value / 1_000_000)}M`
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function trim(value: number): string {
|
|
134
|
+
return value >= 100 ? String(Math.round(value)) : value.toFixed(1).replace(/\.0$/, "")
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** `namespace.name`, or whatever the payload already carries as an id. */
|
|
138
|
+
export function extensionId(extension: { id?: string; namespace?: string; name?: string }): string {
|
|
139
|
+
if (extension.id) return extension.id
|
|
140
|
+
return [extension.namespace, extension.name].filter(Boolean).join(".")
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* The reverse: `dbaeumer.vscode-eslint` → publisher + extension name. A project
|
|
145
|
+
* only stores the id, so a card drawn from the database has nothing else to go
|
|
146
|
+
* on — and "dbaeumer" is still worth showing.
|
|
147
|
+
*/
|
|
148
|
+
export function parseExtensionId(id?: string | null): { namespace?: string; name?: string } {
|
|
149
|
+
const value = id?.trim()
|
|
150
|
+
if (!value) return {}
|
|
151
|
+
const at = value.indexOf(".")
|
|
152
|
+
if (at <= 0) return { name: value }
|
|
153
|
+
return { namespace: value.slice(0, at), name: value.slice(at + 1) || undefined }
|
|
154
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Brand marks for the devcontainer catalogs, as single-path SVGs drawn with
|
|
2
|
+
// `currentColor` — so a logo inherits the warm accent of the card it sits in
|
|
3
|
+
// instead of dragging 20 clashing brand colors into the grid. Same approach (and
|
|
4
|
+
// same source, simple-icons) as the marketing templates' logos; embedded in the
|
|
5
|
+
// package rather than fetched from a CDN so the cards render offline, in the
|
|
6
|
+
// showcase, and inside a worker with no egress.
|
|
7
|
+
//
|
|
8
|
+
// Paths only — the component that draws them is `StackMark`.
|
|
9
|
+
|
|
10
|
+
export const STACK_MARK_PATHS = {
|
|
11
|
+
node:
|
|
12
|
+
"M11.998,24c-0.321,0-0.641-0.084-0.922-0.247l-2.936-1.737c-0.438-0.245-0.224-0.332-0.08-0.383 c0.585-0.203,0.703-0.25,1.328-0.604c0.065-0.037,0.151-0.023,0.218,0.017l2.256,1.339c0.082,0.045,0.197,0.045,0.272,0l8.795-5.076 c0.082-0.047,0.134-0.141,0.134-0.238V6.921c0-0.099-0.053-0.192-0.137-0.242l-8.791-5.072c-0.081-0.047-0.189-0.047-0.271,0 L3.075,6.68C2.99,6.729,2.936,6.825,2.936,6.921v10.15c0,0.097,0.054,0.189,0.139,0.235l2.409,1.392 c1.307,0.654,2.108-0.116,2.108-0.89V7.787c0-0.142,0.114-0.253,0.256-0.253h1.115c0.139,0,0.255,0.112,0.255,0.253v10.021 c0,1.745-0.95,2.745-2.604,2.745c-0.508,0-0.909,0-2.026-0.551L2.28,18.675c-0.57-0.329-0.922-0.945-0.922-1.604V6.921 c0-0.659,0.353-1.275,0.922-1.603l8.795-5.082c0.557-0.315,1.296-0.315,1.848,0l8.794,5.082c0.57,0.329,0.924,0.944,0.924,1.603 v10.15c0,0.659-0.354,1.273-0.924,1.604l-8.794,5.078C12.643,23.916,12.324,24,11.998,24z M19.099,13.993 c0-1.9-1.284-2.406-3.987-2.763c-2.731-0.361-3.009-0.548-3.009-1.187c0-0.528,0.235-1.233,2.258-1.233 c1.807,0,2.473,0.389,2.747,1.607c0.024,0.115,0.129,0.199,0.247,0.199h1.141c0.071,0,0.138-0.031,0.186-0.081 c0.048-0.054,0.074-0.123,0.067-0.196c-0.177-2.098-1.571-3.076-4.388-3.076c-2.508,0-4.004,1.058-4.004,2.833 c0,1.925,1.488,2.457,3.895,2.695c2.88,0.282,3.103,0.703,3.103,1.269c0,0.983-0.789,1.402-2.642,1.402 c-2.327,0-2.839-0.584-3.011-1.742c-0.02-0.124-0.126-0.215-0.253-0.215h-1.137c-0.141,0-0.254,0.112-0.254,0.253 c0,1.482,0.806,3.248,4.655,3.248C17.501,17.007,19.099,15.91,19.099,13.993z",
|
|
13
|
+
typescript:
|
|
14
|
+
"M1.125 0C.502 0 0 .502 0 1.125v21.75C0 23.498.502 24 1.125 24h21.75c.623 0 1.125-.502 1.125-1.125V1.125C24 .502 23.498 0 22.875 0zm17.363 9.75c.612 0 1.154.037 1.627.111a6.38 6.38 0 0 1 1.306.34v2.458a3.95 3.95 0 0 0-.643-.361 5.093 5.093 0 0 0-.717-.26 5.453 5.453 0 0 0-1.426-.2c-.3 0-.573.028-.819.086a2.1 2.1 0 0 0-.623.242c-.17.104-.3.229-.393.374a.888.888 0 0 0-.14.49c0 .196.053.373.156.529.104.156.252.304.443.444s.423.276.696.41c.273.135.582.274.926.416.47.197.892.407 1.266.628.374.222.695.473.963.753.268.279.472.598.614.957.142.359.214.776.214 1.253 0 .657-.125 1.21-.373 1.656a3.033 3.033 0 0 1-1.012 1.085 4.38 4.38 0 0 1-1.487.596c-.566.12-1.163.18-1.79.18a9.916 9.916 0 0 1-1.84-.164 5.544 5.544 0 0 1-1.512-.493v-2.63a5.033 5.033 0 0 0 3.237 1.2c.333 0 .624-.03.872-.09.249-.06.456-.144.623-.25.166-.108.29-.234.373-.38a1.023 1.023 0 0 0-.074-1.089 2.12 2.12 0 0 0-.537-.5 5.597 5.597 0 0 0-.807-.444 27.72 27.72 0 0 0-1.007-.436c-.918-.383-1.602-.852-2.053-1.405-.45-.553-.676-1.222-.676-2.005 0-.614.123-1.141.369-1.582.246-.441.58-.804 1.004-1.089a4.494 4.494 0 0 1 1.47-.629 7.536 7.536 0 0 1 1.77-.201zm-15.113.188h9.563v2.166H9.506v9.646H6.789v-9.646H3.375z",
|
|
15
|
+
javascript:
|
|
16
|
+
"M0 0h24v24H0V0zm22.034 18.276c-.175-1.095-.888-2.015-3.003-2.873-.736-.345-1.554-.585-1.797-1.14-.091-.33-.105-.51-.046-.705.15-.646.915-.84 1.515-.66.39.12.75.42.976.9 1.034-.676 1.034-.676 1.755-1.125-.27-.42-.404-.601-.586-.78-.63-.705-1.469-1.065-2.834-1.034l-.705.089c-.676.165-1.32.525-1.71 1.005-1.14 1.291-.811 3.541.569 4.471 1.365 1.02 3.361 1.244 3.616 2.205.24 1.17-.87 1.545-1.966 1.41-.811-.18-1.26-.586-1.755-1.336l-1.83 1.051c.21.48.45.689.81 1.109 1.74 1.756 6.09 1.666 6.871-1.004.029-.09.24-.705.074-1.65l.046.067zm-8.983-7.245h-2.248c0 1.938-.009 3.864-.009 5.805 0 1.232.063 2.363-.138 2.711-.33.689-1.18.601-1.566.48-.396-.196-.597-.466-.83-.855-.063-.105-.11-.196-.127-.196l-1.825 1.125c.305.63.75 1.172 1.324 1.517.855.51 2.004.675 3.207.405.783-.226 1.458-.691 1.811-1.411.51-.93.402-2.07.397-3.346.012-2.054 0-4.109 0-6.179l.004-.056z",
|
|
17
|
+
python:
|
|
18
|
+
"M14.25.18l.9.2.73.26.59.3.45.32.34.34.25.34.16.33.1.3.04.26.02.2-.01.13V8.5l-.05.63-.13.55-.21.46-.26.38-.3.31-.33.25-.35.19-.35.14-.33.1-.3.07-.26.04-.21.02H8.77l-.69.05-.59.14-.5.22-.41.27-.33.32-.27.35-.2.36-.15.37-.1.35-.07.32-.04.27-.02.21v3.06H3.17l-.21-.03-.28-.07-.32-.12-.35-.18-.36-.26-.36-.36-.35-.46-.32-.59-.28-.73-.21-.88-.14-1.05-.05-1.23.06-1.22.16-1.04.24-.87.32-.71.36-.57.4-.44.42-.33.42-.24.4-.16.36-.1.32-.05.24-.01h.16l.06.01h8.16v-.83H6.18l-.01-2.75-.02-.37.05-.34.11-.31.17-.28.25-.26.31-.23.38-.2.44-.18.51-.15.58-.12.64-.1.71-.06.77-.04.84-.02 1.27.05zm-6.3 1.98l-.23.33-.08.41.08.41.23.34.33.22.41.09.41-.09.33-.22.23-.34.08-.41-.08-.41-.23-.33-.33-.22-.41-.09-.41.09zm13.09 3.95l.28.06.32.12.35.18.36.27.36.35.35.47.32.59.28.73.21.88.14 1.04.05 1.23-.06 1.23-.16 1.04-.24.86-.32.71-.36.57-.4.45-.42.33-.42.24-.4.16-.36.09-.32.05-.24.02-.16-.01h-8.22v.82h5.84l.01 2.76.02.36-.05.34-.11.31-.17.29-.25.25-.31.24-.38.2-.44.17-.51.15-.58.13-.64.09-.71.07-.77.04-.84.01-1.27-.04-1.07-.14-.9-.2-.73-.25-.59-.3-.45-.33-.34-.34-.25-.34-.16-.33-.1-.3-.04-.25-.02-.2.01-.13v-5.34l.05-.64.13-.54.21-.46.26-.38.3-.32.33-.24.35-.2.35-.14.33-.1.3-.06.26-.04.21-.02.13-.01h5.84l.69-.05.59-.14.5-.21.41-.28.33-.32.27-.35.2-.36.15-.36.1-.35.07-.32.04-.28.02-.21V6.07h2.09l.14.01zm-6.47 14.25l-.23.33-.08.41.08.41.23.33.33.23.41.08.41-.08.33-.23.23-.33.08-.41-.08-.41-.23-.33-.33-.23-.41-.08-.41.08z",
|
|
19
|
+
anaconda:
|
|
20
|
+
"M12.045.033a12.181 12.182 0 00-1.361.078 17.512 17.513 0 011.813 1.433l.48.438-.465.45a15.047 15.048 0 00-1.126 1.205l-.178.215a8.527 8.527 0 01.86-.05 8.154 8.155 0 11-4.286 15.149 15.764 15.765 0 01-1.841.106h-.86a21.847 21.848 0 00.264 2.866 11.966 11.967 0 106.7-21.89zM8.17.678a12.181 12.182 0 00-2.624 1.275 15.506 15.507 0 011.813.43A18.551 18.552 0 018.17.678zM9.423.75a16.237 16.238 0 00-.995 1.998 16.15 16.152 0 011.605.66 6.98 6.98 0 01.43-.509c.234-.286.472-.559.716-.817A15.047 15.048 0 009.423.75zM4.68 2.949a14.969 14.97 0 000 2.336c.587-.065 1.196-.1 1.812-.107a16.617 16.617 0 01.48-1.748 16.48 16.481 0 00-2.292-.481zM3.62 3.5A11.938 11.938 0 001.762 5.88a17.004 17.004 0 011.877-.444A17.39 17.391 0 013.62 3.5zm4.406.287c-.143.437-.265.888-.38 1.347a8.255 8.255 0 011.67-.803c-.423-.2-.845-.38-1.29-.544zM6.3 6.216a14.051 14.052 0 00-1.555.108c.064.523.157 1.038.272 1.554a8.39 8.391 0 011.283-1.662zm-2.55.137a15.313 15.313 0 00-2.602.716h-.078v.079a17.104 17.105 0 001.267 2.544l.043.071.072-.049a16.309 16.31 0 011.734-1.083l.057-.035V8.54a16.867 16.868 0 01-.408-2.094v-.092zM.644 8.095l-.063.2A11.844 11.845 0 000 11.655v.209l.143-.152a17.706 17.707 0 011.584-1.447l.057-.043-.043-.064a16.18 16.18 0 01-1.025-1.87zm3.77 1.253l-.18.1c-.465.273-.93.573-1.375.889l-.065.05.05.064c.309.437.645.867.996 1.276l.137.165v-.208a8.176 8.176 0 01.364-2.15zM2.2 10.853l-.072.05a16.574 16.574 0 00-1.813 1.734l-.058.058.066.057a15.449 15.45 0 001.991 1.483l.072.05.043-.08a16.738 16.74 0 011.053-1.64v-.05l-.043-.05a16.99 16.99 0 01-1.19-1.54zm1.855 2.071l-.121.172a15.363 15.363 0 00-.917 1.433l-.043.072.071.043a16.61 16.61 0 001.562.766l.193.086-.086-.193a8.04 8.04 0 01-.66-2.172zm-3.976.48v.2a11.758 11.759 0 00.946 3.326l.078.186.072-.194a16.215 16.216 0 01.845-2l.057-.063-.064-.043a17.197 17.198 0 01-1.776-1.284zm2.543 1.805l-.035.08a15.764 15.765 0 00-.983 2.479v.08h.086a16.15 16.152 0 002.688.5l.072.007v-.086a17.562 17.563 0 01.164-2.056v-.065H4.55a16.266 16.266 0 01-1.849-.896zm2.544 1.169v.114a17.254 17.255 0 00-.151 1.828v.078h.931c.287 0 .624.014.946 0h.209l-.166-.129a8.011 8.011 0 01-1.64-1.834zm-3.29 2.1l.115.172a11.988 11.988 0 002.502 2.737l.157.129v-.201a22.578 22.58 0 01-.2-2.336v-.071h-.072a16.23 16.23 0 01-2.3-.387z",
|
|
21
|
+
go:
|
|
22
|
+
"M1.811 10.231c-.047 0-.058-.023-.035-.059l.246-.315c.023-.035.081-.058.128-.058h4.172c.046 0 .058.035.035.07l-.199.303c-.023.036-.082.07-.117.07zM.047 11.306c-.047 0-.059-.023-.035-.058l.245-.316c.023-.035.082-.058.129-.058h5.328c.047 0 .07.035.058.07l-.093.28c-.012.047-.058.07-.105.07zm2.828 1.075c-.047 0-.059-.035-.035-.07l.163-.292c.023-.035.07-.07.117-.07h2.337c.047 0 .07.035.07.082l-.023.28c0 .047-.047.082-.082.082zm12.129-2.36c-.736.187-1.239.327-1.963.514-.176.046-.187.058-.34-.117-.174-.199-.303-.327-.548-.444-.737-.362-1.45-.257-2.115.175-.795.514-1.204 1.274-1.192 2.22.011.935.654 1.706 1.577 1.835.795.105 1.46-.175 1.987-.77.105-.13.198-.27.315-.434H10.47c-.245 0-.304-.152-.222-.35.152-.362.432-.97.596-1.274a.315.315 0 01.292-.187h4.253c-.023.316-.023.631-.07.947a4.983 4.983 0 01-.958 2.29c-.841 1.11-1.94 1.8-3.33 1.986-1.145.152-2.209-.07-3.143-.77-.865-.655-1.356-1.52-1.484-2.595-.152-1.274.222-2.419.993-3.424.83-1.086 1.928-1.776 3.272-2.02 1.098-.2 2.15-.07 3.096.571.62.41 1.063.97 1.356 1.648.07.105.023.164-.117.2m3.868 6.461c-1.064-.024-2.034-.328-2.852-1.029a3.665 3.665 0 01-1.262-2.255c-.21-1.32.152-2.489.947-3.529.853-1.122 1.881-1.706 3.272-1.95 1.192-.21 2.314-.095 3.33.595.923.63 1.496 1.484 1.648 2.605.198 1.578-.257 2.863-1.344 3.962-.771.783-1.718 1.273-2.805 1.495-.315.06-.63.07-.934.106zm2.78-4.72c-.011-.153-.011-.27-.034-.387-.21-1.157-1.274-1.81-2.384-1.554-1.087.245-1.788.935-2.045 2.033-.21.912.234 1.835 1.075 2.21.643.28 1.285.244 1.905-.07.923-.48 1.425-1.228 1.484-2.233z",
|
|
23
|
+
rust:
|
|
24
|
+
"M23.8346 11.7033l-1.0073-.6236a13.7268 13.7268 0 00-.0283-.2936l.8656-.8069a.3483.3483 0 00-.1154-.578l-1.1066-.414a8.4958 8.4958 0 00-.087-.2856l.6904-.9587a.3462.3462 0 00-.2257-.5446l-1.1663-.1894a9.3574 9.3574 0 00-.1407-.2622l.49-1.0761a.3437.3437 0 00-.0274-.3361.3486.3486 0 00-.3006-.154l-1.1845.0416a6.7444 6.7444 0 00-.1873-.2268l.2723-1.153a.3472.3472 0 00-.417-.4172l-1.1532.2724a14.0183 14.0183 0 00-.2278-.1873l.0415-1.1845a.3442.3442 0 00-.49-.328l-1.076.491c-.0872-.0476-.1742-.0952-.2623-.1407l-.1903-1.1673A.3483.3483 0 0016.256.955l-.9597.6905a8.4867 8.4867 0 00-.2855-.086l-.414-1.1066a.3483.3483 0 00-.5781-.1154l-.8069.8666a9.2936 9.2936 0 00-.2936-.0284L12.2946.1683a.3462.3462 0 00-.5892 0l-.6236 1.0073a13.7383 13.7383 0 00-.2936.0284L9.9803.3374a.3462.3462 0 00-.578.1154l-.4141 1.1065c-.0962.0274-.1903.0567-.2855.086L7.744.955a.3483.3483 0 00-.5447.2258L7.009 2.348a9.3574 9.3574 0 00-.2622.1407l-1.0762-.491a.3462.3462 0 00-.49.328l.0416 1.1845a7.9826 7.9826 0 00-.2278.1873L3.8413 3.425a.3472.3472 0 00-.4171.4171l.2713 1.1531c-.0628.075-.1255.1509-.1863.2268l-1.1845-.0415a.3462.3462 0 00-.328.49l.491 1.0761a9.167 9.167 0 00-.1407.2622l-1.1662.1894a.3483.3483 0 00-.2258.5446l.6904.9587a13.303 13.303 0 00-.087.2855l-1.1065.414a.3483.3483 0 00-.1155.5781l.8656.807a9.2936 9.2936 0 00-.0283.2935l-1.0073.6236a.3442.3442 0 000 .5892l1.0073.6236c.008.0982.0182.1964.0283.2936l-.8656.8079a.3462.3462 0 00.1155.578l1.1065.4141c.0273.0962.0567.1914.087.2855l-.6904.9587a.3452.3452 0 00.2268.5447l1.1662.1893c.0456.088.0922.1751.1408.2622l-.491 1.0762a.3462.3462 0 00.328.49l1.1834-.0415c.0618.0769.1235.1528.1873.2277l-.2713 1.1541a.3462.3462 0 00.4171.4161l1.153-.2713c.075.0638.151.1255.2279.1863l-.0415 1.1845a.3442.3442 0 00.49.327l1.0761-.49c.087.0486.1741.0951.2622.1407l.1903 1.1662a.3483.3483 0 00.5447.2268l.9587-.6904a9.299 9.299 0 00.2855.087l.414 1.1066a.3452.3452 0 00.5781.1154l.8079-.8656c.0972.0111.1954.0203.2936.0294l.6236 1.0073a.3472.3472 0 00.5892 0l.6236-1.0073c.0982-.0091.1964-.0183.2936-.0294l.8069.8656a.3483.3483 0 00.578-.1154l.4141-1.1066a8.4626 8.4626 0 00.2855-.087l.9587.6904a.3452.3452 0 00.5447-.2268l.1903-1.1662c.088-.0456.1751-.0931.2622-.1407l1.0762.49a.3472.3472 0 00.49-.327l-.0415-1.1845a6.7267 6.7267 0 00.2267-.1863l1.1531.2713a.3472.3472 0 00.4171-.416l-.2713-1.1542c.0628-.0749.1255-.1508.1863-.2278l1.1845.0415a.3442.3442 0 00.328-.49l-.49-1.076c.0475-.0872.0951-.1742.1407-.2623l1.1662-.1893a.3483.3483 0 00.2258-.5447l-.6904-.9587.087-.2855 1.1066-.414a.3462.3462 0 00.1154-.5781l-.8656-.8079c.0101-.0972.0202-.1954.0283-.2936l1.0073-.6236a.3442.3442 0 000-.5892zm-6.7413 8.3551a.7138.7138 0 01.2986-1.396.714.714 0 11-.2997 1.396zm-.3422-2.3142a.649.649 0 00-.7715.5l-.3573 1.6685c-1.1035.501-2.3285.7795-3.6193.7795a8.7368 8.7368 0 01-3.6951-.814l-.3574-1.6684a.648.648 0 00-.7714-.499l-1.473.3158a8.7216 8.7216 0 01-.7613-.898h7.1676c.081 0 .1356-.0141.1356-.088v-2.536c0-.074-.0536-.0881-.1356-.0881h-2.0966v-1.6077h2.2677c.2065 0 1.1065.0587 1.394 1.2088.0901.3533.2875 1.5044.4232 1.8729.1346.413.6833 1.2381 1.2685 1.2381h3.5716a.7492.7492 0 00.1296-.0131 8.7874 8.7874 0 01-.8119.9526zM6.8369 20.024a.714.714 0 11-.2997-1.396.714.714 0 01.2997 1.396zM4.1177 8.9972a.7137.7137 0 11-1.304.5791.7137.7137 0 011.304-.579zm-.8352 1.9813l1.5347-.6824a.65.65 0 00.33-.8585l-.3158-.7147h1.2432v5.6025H3.5669a8.7753 8.7753 0 01-.2834-3.348zm6.7343-.5437V8.7836h2.9601c.153 0 1.0792.1772 1.0792.8697 0 .575-.7107.7815-1.2948.7815zm10.7574 1.4862c0 .2187-.008.4363-.0243.651h-.9c-.09 0-.1265.0586-.1265.1477v.413c0 .973-.5487 1.1846-1.0296 1.2382-.4576.0517-.9648-.1913-1.0275-.4717-.2704-1.5186-.7198-1.8436-1.4305-2.4034.8817-.5599 1.799-1.386 1.799-2.4915 0-1.1936-.819-1.9458-1.3769-2.3153-.7825-.5163-1.6491-.6195-1.883-.6195H5.4682a8.7651 8.7651 0 014.907-2.7699l1.0974 1.151a.648.648 0 00.9182.0213l1.227-1.1743a8.7753 8.7753 0 016.0044 4.2762l-.8403 1.8982a.652.652 0 00.33.8585l1.6178.7188c.0283.2875.0425.577.0425.8717zm-9.3006-9.5993a.7128.7128 0 11.984 1.0316.7137.7137 0 01-.984-1.0316zm8.3389 6.71a.7107.7107 0 01.9395-.3625.7137.7137 0 11-.9405.3635z",
|
|
25
|
+
java:
|
|
26
|
+
"M11.915 0 11.7.215C9.515 2.4 7.47 6.39 6.046 10.483c-1.064 1.024-3.633 2.81-3.711 3.551-.093.87 1.746 2.611 1.55 3.235-.198.625-1.304 1.408-1.014 1.939.1.188.823.011 1.277-.491a13.389 13.389 0 0 0-.017 2.14c.076.906.27 1.668.643 2.232.372.563.956.911 1.667.911.397 0 .727-.114 1.024-.264.298-.149.571-.33.91-.5.68-.34 1.634-.666 3.53-.604 1.903.062 2.872.39 3.559.704.687.314 1.15.664 1.925.664.767 0 1.395-.336 1.807-.9.412-.563.631-1.33.72-2.24.06-.623.055-1.32 0-2.066.454.45 1.117.604 1.213.424.29-.53-.816-1.314-1.013-1.937-.198-.624 1.642-2.366 1.549-3.236-.08-.748-2.707-2.568-3.748-3.586C16.428 6.374 14.308 2.394 12.13.215zm.175 6.038a2.95 2.95 0 0 1 2.943 2.942 2.95 2.95 0 0 1-2.943 2.943A2.95 2.95 0 0 1 9.148 8.98a2.95 2.95 0 0 1 2.942-2.942zM8.685 7.983a3.515 3.515 0 0 0-.145.997c0 1.951 1.6 3.55 3.55 3.55 1.95 0 3.55-1.598 3.55-3.55 0-.329-.046-.648-.132-.951.334.095.64.208.915.336a42.699 42.699 0 0 1 2.042 5.829c.678 2.545 1.01 4.92.846 6.607-.082.844-.29 1.51-.606 1.94-.315.431-.713.651-1.315.651-.593 0-.932-.27-1.673-.61-.741-.338-1.825-.694-3.792-.758-1.974-.064-3.073.293-3.821.669-.375.188-.659.373-.911.5s-.466.2-.752.2c-.53 0-.876-.209-1.16-.64-.285-.43-.474-1.101-.545-1.948-.141-1.693.176-4.069.823-6.614a43.155 43.155 0 0 1 1.934-5.783c.348-.167.749-.31 1.192-.425zm-3.382 4.362a.216.216 0 0 1 .13.031c-.166.56-.323 1.116-.463 1.665a33.849 33.849 0 0 0-.547 2.555 3.9 3.9 0 0 0-.2-.39c-.58-1.012-.914-1.642-1.16-2.08.315-.24 1.679-1.755 2.24-1.781zm13.394.01c.562.027 1.926 1.543 2.24 1.783-.246.438-.58 1.068-1.16 2.08a4.428 4.428 0 0 0-.163.309 32.354 32.354 0 0 0-.562-2.49 40.579 40.579 0 0 0-.482-1.652.216.216 0 0 1 .127-.03z",
|
|
27
|
+
dotnet:
|
|
28
|
+
"M24 8.77h-2.468v7.565h-1.425V8.77h-2.462V7.53H24zm-6.852 7.565h-4.821V7.53h4.63v1.24h-3.205v2.494h2.953v1.234h-2.953v2.604h3.396zm-6.708 0H8.882L4.78 9.863a2.896 2.896 0 0 1-.258-.51h-.036c.032.189.048.592.048 1.21v5.772H3.157V7.53h1.659l3.965 6.32c.167.261.275.442.323.54h.024c-.04-.233-.06-.629-.06-1.185V7.529h1.372zm-8.703-.693a.868.829 0 0 1-.869.829.868.829 0 0 1-.868-.83.868.829 0 0 1 .868-.828.868.829 0 0 1 .869.829Z",
|
|
29
|
+
php:
|
|
30
|
+
"M7.01 10.207h-.944l-.515 2.648h.838c.556 0 .97-.105 1.242-.314.272-.21.455-.559.55-1.049.092-.47.05-.802-.124-.995-.175-.193-.523-.29-1.047-.29zM12 5.688C5.373 5.688 0 8.514 0 12s5.373 6.313 12 6.313S24 15.486 24 12c0-3.486-5.373-6.312-12-6.312zm-3.26 7.451c-.261.25-.575.438-.917.551-.336.108-.765.164-1.285.164H5.357l-.327 1.681H3.652l1.23-6.326h2.65c.797 0 1.378.209 1.744.628.366.418.476 1.002.33 1.752a2.836 2.836 0 0 1-.305.847c-.143.255-.33.49-.561.703zm4.024.715l.543-2.799c.063-.318.039-.536-.068-.651-.107-.116-.336-.174-.687-.174H11.46l-.704 3.625H9.388l1.23-6.327h1.367l-.327 1.682h1.218c.767 0 1.295.134 1.586.401s.378.7.263 1.299l-.572 2.944h-1.389zm7.597-2.265a2.782 2.782 0 0 1-.305.847c-.143.255-.33.49-.561.703a2.44 2.44 0 0 1-.917.551c-.336.108-.765.164-1.286.164h-1.18l-.327 1.682h-1.378l1.23-6.326h2.649c.797 0 1.378.209 1.744.628.366.417.477 1.001.331 1.751zM17.766 10.207h-.943l-.516 2.648h.838c.557 0 .971-.105 1.242-.314.272-.21.455-.559.551-1.049.092-.47.049-.802-.125-.995s-.524-.29-1.047-.29z",
|
|
31
|
+
ruby:
|
|
32
|
+
"M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16.5 2.114 20.159.073l-.003.01zM0 19.089zM5.13 5.073c3.561-3.533 8.157-5.621 9.922-3.84 1.762 1.777-.105 6.105-3.673 9.636-3.563 3.532-8.103 5.734-9.864 3.957-1.766-1.777.045-6.217 3.612-9.75l.003-.003z",
|
|
33
|
+
jekyll:
|
|
34
|
+
"M8.073 24c-.348 0-.689-.063-1.02-.189-1.375-.525-2.104-2.02-1.726-3.402l-.015-.006.09-.226L12.399 2.01c.105-.27.057-.91.006-1.267-.016-.085-.016-.161.008-.24l.008-.023.006-.015V.458l.009-.019c.108-.292.45-.439 1.008-.439.673 0 1.602.21 2.551.573.797.307 1.523.689 2.033 1.075.602.45.842.854.707 1.2l-.031.045-.016.015c-.045.061-.09.12-.15.165-.314.271-.764.735-.84.945l-7.063 18.421-.016-.006c-.494.948-1.457 1.557-2.543 1.561H8.07l.003.006zm-2.187-3.718l-.02.05c-.447 1.201.162 2.557 1.364 3.018.271.105.551.154.837.154.971 0 1.83-.585 2.188-1.5l.027-.061 6.959-18.09c.146-.39.84-1.02.979-1.14l.016-.016c.012-.015.02-.015.02-.03 0-.06-.061-.27-.557-.645-.479-.36-1.154-.72-1.904-1.005-.868-.328-1.768-.539-2.368-.539-.39 0-.524.082-.545.126v.04c.016.104.147 1.035-.034 1.515l-6.962 18.12v.003zm8.95-11.507s-.964 1.109-1.843 1.509c-.88.398-1.529.293-2.32.756-.789.461-1.188 1.103-1.188 1.103L6.27 20.505c-.348.944.168 2.05 1.125 2.42.96.369 2.04-.12 2.412-1.056l5.029-13.094zM9.905 18.76c.104-.041.225 0 .266.105.042.104 0 .222-.105.264-.104.043-.225 0-.266-.104-.042-.097 0-.216.105-.265zm-1.014-1.802c-.152.068-.334 0-.397-.155-.07-.152 0-.334.154-.397.154-.07.335 0 .398.153.074.15.008.314-.155.39v.009zm.286-1.096c-.123-.288 0-.623.287-.758.285-.124.615 0 .75.285.121.289 0 .624-.285.757-.3.126-.629 0-.765-.285l.013.001zm2.426-2.258c.153-.074.335 0 .398.15.07.154 0 .336-.153.399-.155.07-.337 0-.399-.155-.074-.152 0-.334.154-.397v.003zm-1.293-1.379c.105-.042.226 0 .266.105.043.104 0 .226-.104.266-.104.042-.226 0-.265-.104-.044-.106.006-.227.103-.267zM13.681 1.14c.1-.261.993-.162 1.995.226.999.384 1.729.909 1.63 1.17-.104.264-.997.164-1.996-.221-1.005-.385-1.734-.91-1.632-1.176h.003z",
|
|
35
|
+
cpp:
|
|
36
|
+
"M22.394 6c-.167-.29-.398-.543-.652-.69L12.926.22c-.509-.294-1.34-.294-1.848 0L2.26 5.31c-.508.293-.923 1.013-.923 1.6v10.18c0 .294.104.62.271.91.167.29.398.543.652.69l8.816 5.09c.508.293 1.34.293 1.848 0l8.816-5.09c.254-.147.485-.4.652-.69.167-.29.27-.616.27-.91V6.91c.003-.294-.1-.62-.268-.91zM12 19.11c-3.92 0-7.109-3.19-7.109-7.11 0-3.92 3.19-7.11 7.11-7.11a7.133 7.133 0 016.156 3.553l-3.076 1.78a3.567 3.567 0 00-3.08-1.78A3.56 3.56 0 008.444 12 3.56 3.56 0 0012 15.555a3.57 3.57 0 003.08-1.778l3.078 1.78A7.135 7.135 0 0112 19.11zm7.11-6.715h-.79v.79h-.79v-.79h-.79v-.79h.79v-.79h.79v.79h.79zm2.962 0h-.79v.79h-.79v-.79h-.79v-.79h.79v-.79h.79v.79h.79z",
|
|
37
|
+
docker:
|
|
38
|
+
"M13.983 11.078h2.119a.186.186 0 00.186-.185V9.006a.186.186 0 00-.186-.186h-2.119a.185.185 0 00-.185.185v1.888c0 .102.083.185.185.185m-2.954-5.43h2.118a.186.186 0 00.186-.186V3.574a.186.186 0 00-.186-.185h-2.118a.185.185 0 00-.185.185v1.888c0 .102.082.185.185.185m0 2.716h2.118a.187.187 0 00.186-.186V6.29a.186.186 0 00-.186-.185h-2.118a.185.185 0 00-.185.185v1.887c0 .102.082.185.185.186m-2.93 0h2.12a.186.186 0 00.184-.186V6.29a.185.185 0 00-.185-.185H8.1a.185.185 0 00-.185.185v1.887c0 .102.083.185.185.186m-2.964 0h2.119a.186.186 0 00.185-.186V6.29a.185.185 0 00-.185-.185H5.136a.186.186 0 00-.186.185v1.887c0 .102.084.185.186.186m5.893 2.715h2.118a.186.186 0 00.186-.185V9.006a.186.186 0 00-.186-.186h-2.118a.185.185 0 00-.185.185v1.888c0 .102.082.185.185.185m-2.93 0h2.12a.185.185 0 00.184-.185V9.006a.185.185 0 00-.184-.186h-2.12a.185.185 0 00-.184.185v1.888c0 .102.083.185.185.185m-2.964 0h2.119a.185.185 0 00.185-.185V9.006a.185.185 0 00-.184-.186h-2.12a.186.186 0 00-.186.186v1.887c0 .102.084.185.186.185m-2.92 0h2.12a.185.185 0 00.184-.185V9.006a.185.185 0 00-.184-.186h-2.12a.185.185 0 00-.184.185v1.888c0 .102.082.185.185.185M23.763 9.89c-.065-.051-.672-.51-1.954-.51-.338.001-.676.03-1.01.087-.248-1.7-1.653-2.53-1.716-2.566l-.344-.199-.226.327c-.284.438-.49.922-.612 1.43-.23.97-.09 1.882.403 2.661-.595.332-1.55.413-1.744.42H.751a.751.751 0 00-.75.748 11.376 11.376 0 00.692 4.062c.545 1.428 1.355 2.48 2.41 3.124 1.18.723 3.1 1.137 5.275 1.137.983.003 1.963-.086 2.93-.266a12.248 12.248 0 003.823-1.389c.98-.567 1.86-1.288 2.61-2.136 1.252-1.418 1.998-2.997 2.553-4.4h.221c1.372 0 2.215-.549 2.68-1.009.309-.293.55-.65.707-1.046l.098-.288Z",
|
|
39
|
+
kubernetes:
|
|
40
|
+
"M10.204 14.35l.007.01-.999 2.413a5.171 5.171 0 0 1-2.075-2.597l2.578-.437.004.005a.44.44 0 0 1 .484.606zm-.833-2.129a.44.44 0 0 0 .173-.756l.002-.011L7.585 9.7a5.143 5.143 0 0 0-.73 3.255l2.514-.725.002-.009zm1.145-1.98a.44.44 0 0 0 .699-.337l.01-.005.15-2.62a5.144 5.144 0 0 0-3.01 1.442l2.147 1.523.004-.002zm.76 2.75l.723.349.722-.347.18-.78-.5-.623h-.804l-.5.623.179.779zm1.5-3.095a.44.44 0 0 0 .7.336l.008.003 2.134-1.513a5.188 5.188 0 0 0-2.992-1.442l.148 2.615.002.001zm10.876 5.97l-5.773 7.181a1.6 1.6 0 0 1-1.248.594l-9.261.003a1.6 1.6 0 0 1-1.247-.596l-5.776-7.18a1.583 1.583 0 0 1-.307-1.34L2.1 5.573c.108-.47.425-.864.863-1.073L11.305.513a1.606 1.606 0 0 1 1.385 0l8.345 3.985c.438.209.755.604.863 1.073l2.062 8.955c.108.47-.005.963-.308 1.34zm-3.289-2.057c-.042-.01-.103-.026-.145-.034-.174-.033-.315-.025-.479-.038-.35-.037-.638-.067-.895-.148-.105-.04-.18-.165-.216-.216l-.201-.059a6.45 6.45 0 0 0-.105-2.332 6.465 6.465 0 0 0-.936-2.163c.052-.047.15-.133.177-.159.008-.09.001-.183.094-.282.197-.185.444-.338.743-.522.142-.084.273-.137.415-.242.032-.024.076-.062.11-.089.24-.191.295-.52.123-.736-.172-.216-.506-.236-.745-.045-.034.027-.08.062-.111.088-.134.116-.217.23-.33.35-.246.25-.45.458-.673.609-.097.056-.239.037-.303.033l-.19.135a6.545 6.545 0 0 0-4.146-2.003l-.012-.223c-.065-.062-.143-.115-.163-.25-.022-.268.015-.557.057-.905.023-.163.061-.298.068-.475.001-.04-.001-.099-.001-.142 0-.306-.224-.555-.5-.555-.275 0-.499.249-.499.555l.001.014c0 .041-.002.092 0 .128.006.177.044.312.067.475.042.348.078.637.056.906a.545.545 0 0 1-.162.258l-.012.211a6.424 6.424 0 0 0-4.166 2.003 8.373 8.373 0 0 1-.18-.128c-.09.012-.18.04-.297-.029-.223-.15-.427-.358-.673-.608-.113-.12-.195-.234-.329-.349-.03-.026-.077-.062-.111-.088a.594.594 0 0 0-.348-.132.481.481 0 0 0-.398.176c-.172.216-.117.546.123.737l.007.005.104.083c.142.105.272.159.414.242.299.185.546.338.743.522.076.082.09.226.1.288l.16.143a6.462 6.462 0 0 0-1.02 4.506l-.208.06c-.055.072-.133.184-.215.217-.257.081-.546.11-.895.147-.164.014-.305.006-.48.039-.037.007-.09.02-.133.03l-.004.002-.007.002c-.295.071-.484.342-.423.608.061.267.349.429.645.365l.007-.001.01-.003.129-.029c.17-.046.294-.113.448-.172.33-.118.604-.217.87-.256.112-.009.23.069.288.101l.217-.037a6.5 6.5 0 0 0 2.88 3.596l-.09.218c.033.084.069.199.044.282-.097.252-.263.517-.452.813-.091.136-.185.242-.268.399-.02.037-.045.095-.064.134-.128.275-.034.591.213.71.248.12.556-.007.69-.282v-.002c.02-.039.046-.09.062-.127.07-.162.094-.301.144-.458.132-.332.205-.68.387-.897.05-.06.13-.082.215-.105l.113-.205a6.453 6.453 0 0 0 4.609.012l.106.192c.086.028.18.042.256.155.136.232.229.507.342.84.05.156.074.295.145.457.016.037.043.09.062.129.133.276.442.402.69.282.247-.118.341-.435.213-.71-.02-.039-.045-.096-.065-.134-.083-.156-.177-.261-.268-.398-.19-.296-.346-.541-.443-.793-.04-.13.007-.21.038-.294-.018-.022-.059-.144-.083-.202a6.499 6.499 0 0 0 2.88-3.622c.064.01.176.03.213.038.075-.05.144-.114.28-.104.266.039.54.138.87.256.154.06.277.128.448.173.036.01.088.019.13.028l.009.003.007.001c.297.064.584-.098.645-.365.06-.266-.128-.537-.423-.608zM16.4 9.701l-1.95 1.746v.005a.44.44 0 0 0 .173.757l.003.01 2.526.728a5.199 5.199 0 0 0-.108-1.674A5.208 5.208 0 0 0 16.4 9.7zm-4.013 5.325a.437.437 0 0 0-.404-.232.44.44 0 0 0-.372.233h-.002l-1.268 2.292a5.164 5.164 0 0 0 3.326.003l-1.27-2.296h-.01zm1.888-1.293a.44.44 0 0 0-.27.036.44.44 0 0 0-.214.572l-.003.004 1.01 2.438a5.15 5.15 0 0 0 2.081-2.615l-2.6-.44-.004.005z",
|
|
41
|
+
helm:
|
|
42
|
+
"M12.337 0c-.475 0-.861 1.016-.861 2.269 0 .527.069 1.011.183 1.396a8.514 8.514 0 0 0-3.961 1.22 5.229 5.229 0 0 0-.595-1.093c-.606-.866-1.34-1.436-1.79-1.43a.381.381 0 0 0-.217.066c-.39.273-.123 1.326.596 2.353.267.381.559.705.84.948a8.683 8.683 0 0 0-1.528 1.716h1.734a7.179 7.179 0 0 1 5.381-2.421 7.18 7.18 0 0 1 5.382 2.42h1.733a8.687 8.687 0 0 0-1.32-1.53c.35-.249.735-.643 1.078-1.133.719-1.027.986-2.08.596-2.353a.382.382 0 0 0-.217-.065c-.45-.007-1.184.563-1.79 1.43a4.897 4.897 0 0 0-.676 1.325 8.52 8.52 0 0 0-3.899-1.42c.12-.39.193-.887.193-1.429 0-1.253-.386-2.269-.862-2.269zM1.624 9.443v5.162h1.358v-1.968h1.64v1.968h1.357V9.443H4.62v1.838H2.98V9.443zm5.912 0v5.162h3.21v-1.108H8.893v-.95h1.64v-1.142h-1.64v-.84h1.853V9.443zm4.698 0v5.162h3.218v-1.362h-1.86v-3.8zm4.706 0v5.162h1.364v-2.643l1.357 1.225 1.35-1.232v2.65h1.365V9.443h-.614l-2.1 1.914-2.109-1.914zm-11.82 7.28a8.688 8.688 0 0 0 1.412 1.548 5.206 5.206 0 0 0-.841.948c-.719 1.027-.985 2.08-.596 2.353.39.273 1.289-.338 2.007-1.364a5.23 5.23 0 0 0 .595-1.092 8.514 8.514 0 0 0 3.961 1.219 5.01 5.01 0 0 0-.183 1.396c0 1.253.386 2.269.861 2.269.476 0 .862-1.016.862-2.269 0-.542-.072-1.04-.193-1.43a8.52 8.52 0 0 0 3.9-1.42c.121.4.352.865.675 1.327.719 1.026 1.617 1.637 2.007 1.364.39-.273.123-1.326-.596-2.353-.343-.49-.727-.885-1.077-1.135a8.69 8.69 0 0 0 1.202-1.36h-1.771a7.174 7.174 0 0 1-5.227 2.252 7.174 7.174 0 0 1-5.226-2.252z",
|
|
43
|
+
terraform:
|
|
44
|
+
"M1.44 0v7.575l6.561 3.79V3.787zm21.12 4.227l-6.561 3.791v7.574l6.56-3.787zM8.72 4.23v7.575l6.561 3.787V8.018zm0 8.405v7.575L15.28 24v-7.578z",
|
|
45
|
+
googlecloud:
|
|
46
|
+
"M12.19 2.38a9.344 9.344 0 0 0-9.234 6.893c.053-.02-.055.013 0 0-3.875 2.551-3.922 8.11-.247 10.941l.006-.007-.007.03a6.717 6.717 0 0 0 4.077 1.356h5.173l.03.03h5.192c6.687.053 9.376-8.605 3.835-12.35a9.365 9.365 0 0 0-2.821-4.552l-.043.043.006-.05A9.344 9.344 0 0 0 12.19 2.38zm-.358 4.146c1.244-.04 2.518.368 3.486 1.15a5.186 5.186 0 0 1 1.862 4.078v.518c3.53-.07 3.53 5.262 0 5.193h-5.193l-.008.009v-.04H6.785a2.59 2.59 0 0 1-1.067-.23h.001a2.597 2.597 0 1 1 3.437-3.437l3.013-3.012A6.747 6.747 0 0 0 8.11 8.24c.018-.01.04-.026.054-.023a5.186 5.186 0 0 1 3.67-1.69z",
|
|
47
|
+
github:
|
|
48
|
+
"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12",
|
|
49
|
+
ubuntu:
|
|
50
|
+
"M17.61.455a3.41 3.41 0 0 0-3.41 3.41 3.41 3.41 0 0 0 3.41 3.41 3.41 3.41 0 0 0 3.41-3.41 3.41 3.41 0 0 0-3.41-3.41zM12.92.8C8.923.777 5.137 2.941 3.148 6.451a4.5 4.5 0 0 1 .26-.007 4.92 4.92 0 0 1 2.585.737A8.316 8.316 0 0 1 12.688 3.6 4.944 4.944 0 0 1 13.723.834 11.008 11.008 0 0 0 12.92.8zm9.226 4.994a4.915 4.915 0 0 1-1.918 2.246 8.36 8.36 0 0 1-.273 8.303 4.89 4.89 0 0 1 1.632 2.54 11.156 11.156 0 0 0 .559-13.089zM3.41 7.932A3.41 3.41 0 0 0 0 11.342a3.41 3.41 0 0 0 3.41 3.409 3.41 3.41 0 0 0 3.41-3.41 3.41 3.41 0 0 0-3.41-3.41zm2.027 7.866a4.908 4.908 0 0 1-2.915.358 11.1 11.1 0 0 0 7.991 6.698 11.234 11.234 0 0 0 2.422.249 4.879 4.879 0 0 1-.999-2.85 8.484 8.484 0 0 1-.836-.136 8.304 8.304 0 0 1-5.663-4.32zm11.405.928a3.41 3.41 0 0 0-3.41 3.41 3.41 3.41 0 0 0 3.41 3.41 3.41 3.41 0 0 0 3.41-3.41 3.41 3.41 0 0 0-3.41-3.41z",
|
|
51
|
+
debian:
|
|
52
|
+
"M13.88 12.685c-.4 0 .08.2.601.28.14-.1.27-.22.39-.33a3.001 3.001 0 01-.99.05m2.14-.53c.23-.33.4-.69.47-1.06-.06.27-.2.5-.33.73-.75.47-.07-.27 0-.56-.8 1.01-.11.6-.14.89m.781-2.05c.05-.721-.14-.501-.2-.221.07.04.13.5.2.22M12.38.31c.2.04.45.07.42.12.23-.05.28-.1-.43-.12m.43.12l-.15.03.14-.01V.43m6.633 9.944c.02.64-.2.95-.38 1.5l-.35.181c-.28.54.03.35-.17.78-.44.39-1.34 1.22-1.62 1.301-.201 0 .14-.25.19-.34-.591.4-.481.6-1.371.85l-.03-.06c-2.221 1.04-5.303-1.02-5.253-3.842-.03.17-.07.13-.12.2a3.551 3.552 0 012.001-3.501 3.361 3.362 0 013.732.48 3.341 3.342 0 00-2.721-1.3c-1.18.01-2.281.76-2.651 1.57-.6.38-.67 1.47-.93 1.661-.361 2.601.66 3.722 2.38 5.042.27.19.08.21.12.35a4.702 4.702 0 01-1.53-1.16c.23.33.47.66.8.91-.55-.18-1.27-1.3-1.48-1.35.93 1.66 3.78 2.921 5.261 2.3a6.203 6.203 0 01-2.33-.28c-.33-.16-.77-.51-.7-.57a5.802 5.803 0 005.902-.84c.44-.35.93-.94 1.07-.95-.2.32.04.16-.12.44.44-.72-.2-.3.46-1.24l.24.33c-.09-.6.74-1.321.66-2.262.19-.3.2.3 0 .97.29-.74.08-.85.15-1.46.08.2.18.42.23.63-.18-.7.2-1.2.28-1.6-.09-.05-.28.3-.32-.53 0-.37.1-.2.14-.28-.08-.05-.26-.32-.38-.861.08-.13.22.33.34.34-.08-.42-.2-.75-.2-1.08-.34-.68-.12.1-.4-.3-.34-1.091.3-.25.34-.74.54.77.84 1.96.981 2.46-.1-.6-.28-1.2-.49-1.76.16.07-.26-1.241.21-.37A7.823 7.824 0 0017.702 1.6c.18.17.42.39.33.42-.75-.45-.62-.48-.73-.67-.61-.25-.65.02-1.06 0C15.082.73 14.862.8 13.8.4l.05.23c-.77-.25-.9.1-1.73 0-.05-.04.27-.14.53-.18-.741.1-.701-.14-1.431.03.17-.13.36-.21.55-.32-.6.04-1.44.35-1.18.07C9.6.68 7.847 1.3 6.867 2.22L6.838 2c-.45.54-1.96 1.611-2.08 2.311l-.131.03c-.23.4-.38.85-.57 1.261-.3.52-.45.2-.4.28-.6 1.22-.9 2.251-1.16 3.102.18.27 0 1.65.07 2.76-.3 5.463 3.84 10.776 8.363 12.006.67.23 1.65.23 2.49.25-.99-.28-1.12-.15-2.08-.49-.7-.32-.85-.7-1.34-1.13l.2.35c-.971-.34-.57-.42-1.361-.67l.21-.27c-.31-.03-.83-.53-.97-.81l-.34.01c-.41-.501-.63-.871-.61-1.161l-.111.2c-.13-.21-1.52-1.901-.8-1.511-.13-.12-.31-.2-.5-.55l.14-.17c-.35-.44-.64-1.02-.62-1.2.2.24.32.3.45.33-.88-2.172-.93-.12-1.601-2.202l.15-.02c-.1-.16-.18-.34-.26-.51l.06-.6c-.63-.74-.18-3.102-.09-4.402.07-.54.53-1.1.88-1.981l-.21-.04c.4-.71 2.341-2.872 3.241-2.761.43-.55-.09 0-.18-.14.96-.991 1.26-.7 1.901-.88.7-.401-.6.16-.27-.151 1.2-.3.85-.7 2.421-.85.16.1-.39.14-.52.26 1-.49 3.151-.37 4.562.27 1.63.77 3.461 3.011 3.531 5.132l.08.02c-.04.85.13 1.821-.17 2.711l.2-.42M9.54 13.236l-.05.28c.26.35.47.73.8 1.01-.24-.47-.42-.66-.75-1.3m.62-.02c-.14-.15-.22-.34-.31-.52.08.32.26.6.43.88l-.12-.36m10.945-2.382l-.07.15c-.1.76-.34 1.511-.69 2.212.4-.73.65-1.541.75-2.362M12.45.12c.27-.1.66-.05.95-.12-.37.03-.74.05-1.1.1l.15.02M3.006 5.142c.07.57-.43.8.11.42.3-.66-.11-.18-.1-.42m-.64 2.661c.12-.39.15-.62.2-.84-.35.44-.17.53-.2.83",
|
|
53
|
+
bash:
|
|
54
|
+
"M21.038,4.9l-7.577-4.498C13.009,0.134,12.505,0,12,0c-0.505,0-1.009,0.134-1.462,0.403L2.961,4.9 C2.057,5.437,1.5,6.429,1.5,7.503v8.995c0,1.073,0.557,2.066,1.462,2.603l7.577,4.497C10.991,23.866,11.495,24,12,24 c0.505,0,1.009-0.134,1.461-0.402l7.577-4.497c0.904-0.537,1.462-1.529,1.462-2.603V7.503C22.5,6.429,21.943,5.437,21.038,4.9z M15.17,18.946l0.013,0.646c0.001,0.078-0.05,0.167-0.111,0.198l-0.383,0.22c-0.061,0.031-0.111-0.007-0.112-0.085L14.57,19.29 c-0.328,0.136-0.66,0.169-0.872,0.084c-0.04-0.016-0.057-0.075-0.041-0.142l0.139-0.584c0.011-0.046,0.036-0.092,0.069-0.121 c0.012-0.011,0.024-0.02,0.036-0.026c0.022-0.011,0.043-0.014,0.062-0.006c0.229,0.077,0.521,0.041,0.802-0.101 c0.357-0.181,0.596-0.545,0.592-0.907c-0.003-0.328-0.181-0.465-0.613-0.468c-0.55,0.001-1.064-0.107-1.072-0.917 c-0.007-0.667,0.34-1.361,0.889-1.8l-0.007-0.652c-0.001-0.08,0.048-0.168,0.111-0.2l0.37-0.236 c0.061-0.031,0.111,0.007,0.112,0.087l0.006,0.653c0.273-0.109,0.511-0.138,0.726-0.088c0.047,0.012,0.067,0.076,0.048,0.151 l-0.144,0.578c-0.011,0.044-0.036,0.088-0.065,0.116c-0.012,0.012-0.025,0.021-0.038,0.028c-0.019,0.01-0.038,0.013-0.057,0.009 c-0.098-0.022-0.332-0.073-0.699,0.113c-0.385,0.195-0.52,0.53-0.517,0.778c0.003,0.297,0.155,0.387,0.681,0.396 c0.7,0.012,1.003,0.318,1.01,1.023C16.105,17.747,15.736,18.491,15.17,18.946z M19.143,17.859c0,0.06-0.008,0.116-0.058,0.145 l-1.916,1.164c-0.05,0.029-0.09,0.004-0.09-0.056v-0.494c0-0.06,0.037-0.093,0.087-0.122l1.887-1.129 c0.05-0.029,0.09-0.004,0.09,0.056V17.859z M20.459,6.797l-7.168,4.427c-0.894,0.523-1.553,1.109-1.553,2.187v8.833 c0,0.645,0.26,1.063,0.66,1.184c-0.131,0.023-0.264,0.039-0.398,0.039c-0.42,0-0.833-0.114-1.197-0.33L3.226,18.64 c-0.741-0.44-1.201-1.261-1.201-2.142V7.503c0-0.881,0.46-1.702,1.201-2.142l7.577-4.498c0.363-0.216,0.777-0.33,1.197-0.33 c0.419,0,0.833,0.114,1.197,0.33l7.577,4.498c0.624,0.371,1.046,1.013,1.164,1.732C21.686,6.557,21.12,6.411,20.459,6.797z",
|
|
55
|
+
claude:
|
|
56
|
+
"m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z",
|
|
57
|
+
} as const satisfies Record<string, string>
|
|
58
|
+
|
|
59
|
+
/** Every brand mark the catalogs can draw. */
|
|
60
|
+
export type StackMarkName = keyof typeof STACK_MARK_PATHS
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { BoxesIcon } from "lucide-react"
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../utils"
|
|
4
|
+
import { STACK_MARK_PATHS, type StackMarkName } from "./stack-mark-paths"
|
|
5
|
+
|
|
6
|
+
export type { StackMarkName }
|
|
7
|
+
export { STACK_MARK_PATHS }
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Which brand a catalog entry is about, guessed from its id/ref.
|
|
11
|
+
*
|
|
12
|
+
* Order matters and is the whole trick: `typescript-node` is TypeScript, not
|
|
13
|
+
* Node, and `javascript-node` is neither Java nor JavaScript-then-Node. So the
|
|
14
|
+
* table is scanned top to bottom and the first hit wins — the more specific
|
|
15
|
+
* patterns sit above the ones they'd otherwise be swallowed by.
|
|
16
|
+
*/
|
|
17
|
+
const PATTERNS: [RegExp, StackMarkName][] = [
|
|
18
|
+
[/typescript|(^|[^a-z])ts([^a-z]|$)/, "typescript"],
|
|
19
|
+
[/javascript/, "javascript"],
|
|
20
|
+
[/node|nvm|npm|pnpm|yarn/, "node"],
|
|
21
|
+
[/anaconda|miniconda|conda/, "anaconda"],
|
|
22
|
+
[/python|(^|[^a-z])py([^a-z]|$)/, "python"],
|
|
23
|
+
[/docker|moby|dind/, "docker"],
|
|
24
|
+
[/kubernetes|kubectl|minikube|(^|[^a-z])k8s([^a-z]|$)/, "kubernetes"],
|
|
25
|
+
[/helm/, "helm"],
|
|
26
|
+
[/terraform|hashicorp/, "terraform"],
|
|
27
|
+
[/google-?cloud|gcloud|(^|[^a-z])gcp([^a-z]|$)/, "googlecloud"],
|
|
28
|
+
[/github|(^|[^a-z])gh([^a-z]|$)/, "github"],
|
|
29
|
+
[/claude|anthropic/, "claude"],
|
|
30
|
+
[/jekyll/, "jekyll"],
|
|
31
|
+
[/ruby|rails/, "ruby"],
|
|
32
|
+
[/rust|cargo/, "rust"],
|
|
33
|
+
[/dotnet|\.net|csharp|(^|[^a-z])c#/, "dotnet"],
|
|
34
|
+
[/(^|[^a-z])php([^a-z]|$)/, "php"],
|
|
35
|
+
[/(^|[^a-z])(cpp|c\+\+)([^a-z]|$)/, "cpp"],
|
|
36
|
+
[/java|jdk|maven|gradle/, "java"],
|
|
37
|
+
[/ubuntu/, "ubuntu"],
|
|
38
|
+
[/debian/, "debian"],
|
|
39
|
+
[/common-utils|zsh|(^|[^a-z])(bash|sh)([^a-z]|$)/, "bash"],
|
|
40
|
+
// Last: "go" is two letters and lives inside django, mongo, google… so it
|
|
41
|
+
// only ever matches a whole segment, and only once nothing else has.
|
|
42
|
+
[/(^|[^a-z])go(lang)?([^a-z]|$)/, "go"],
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* First mark matching any of the hints, in the order they're given — pass the
|
|
47
|
+
* most specific first (an explicit `mark`, then the catalog id, then the ref).
|
|
48
|
+
* `undefined` when nothing matches: the caller falls back to the publisher
|
|
49
|
+
* avatar or a monogram rather than drawing a wrong logo.
|
|
50
|
+
*/
|
|
51
|
+
export function resolveStackMark(...hints: (string | null | undefined)[]): StackMarkName | undefined {
|
|
52
|
+
for (const hint of hints) {
|
|
53
|
+
if (!hint) continue
|
|
54
|
+
const value = hint.toLowerCase()
|
|
55
|
+
if (markPath(value)) return value as StackMarkName
|
|
56
|
+
for (const [pattern, mark] of PATTERNS) {
|
|
57
|
+
if (pattern.test(value)) return mark
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return undefined
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* `hasOwnProperty`, not `in`: the names come from user-controlled catalog data,
|
|
65
|
+
* and `"constructor" in STACK_MARK_PATHS` is `true` — which would hand a
|
|
66
|
+
* function to `<path d>`.
|
|
67
|
+
*/
|
|
68
|
+
function markPath(name?: string | null): string | undefined {
|
|
69
|
+
if (!name || !Object.prototype.hasOwnProperty.call(STACK_MARK_PATHS, name)) return undefined
|
|
70
|
+
return STACK_MARK_PATHS[name as StackMarkName]
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface StackMarkProps {
|
|
74
|
+
/** Known brand. Unknown/absent → a generic "box of stuff" glyph. */
|
|
75
|
+
name?: StackMarkName | string | null
|
|
76
|
+
className?: string
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* A runtime's logo, single-path and `currentColor`, so it takes the warm tone
|
|
81
|
+
* of whatever it sits in instead of importing a brand's own palette into the
|
|
82
|
+
* grid. Never a network request: the paths ship with the package.
|
|
83
|
+
*/
|
|
84
|
+
export function StackMark({ name, className }: StackMarkProps) {
|
|
85
|
+
const d = markPath(name)
|
|
86
|
+
if (!d) return <BoxesIcon className={cn("h-4 w-4", className)} aria-hidden />
|
|
87
|
+
return (
|
|
88
|
+
<svg viewBox="0 0 24 24" fill="currentColor" className={cn("h-4 w-4", className)} aria-hidden>
|
|
89
|
+
<path d={d} />
|
|
90
|
+
</svg>
|
|
91
|
+
)
|
|
92
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Structural, deliberately laxist shapes for the three devcontainer catalogs.
|
|
2
|
+
//
|
|
3
|
+
// Same rule as the worker surface: the design system never imports the
|
|
4
|
+
// OpenAPI-generated types of an app. The dashboard's `DevFeature` has an
|
|
5
|
+
// `ociRef` *or* a `localScript`, Spunto Lite's catalog is a hand-written
|
|
6
|
+
// constant, and an Open VSX search result is whatever open-vsx.org felt like
|
|
7
|
+
// returning that day. So the types below describe the *minimum* the cards read
|
|
8
|
+
// — everything optional — and every derivation degrades to a fallback instead
|
|
9
|
+
// of throwing on a shape it doesn't recognise.
|
|
10
|
+
|
|
11
|
+
/** Who publishes a catalog entry: an avatar, a name, and whether it's vouched for. */
|
|
12
|
+
export interface CatalogPublisher {
|
|
13
|
+
/** Human label — "Dev Containers", "dbaeumer". Falls back to `login`. */
|
|
14
|
+
name?: string
|
|
15
|
+
/** Handle behind the registry namespace (`devcontainers`, `stu-bell`…). */
|
|
16
|
+
login?: string
|
|
17
|
+
avatarUrl?: string | null
|
|
18
|
+
/** Registry/marketplace-verified namespace → a small check next to the name. */
|
|
19
|
+
verified?: boolean
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** A base image of the devcontainer catalog. */
|
|
23
|
+
export interface DevcontainerImageEntry {
|
|
24
|
+
id?: string
|
|
25
|
+
label?: string
|
|
26
|
+
/** Full image reference, e.g. `mcr.microsoft.com/devcontainers/typescript-node:20`. */
|
|
27
|
+
image?: string
|
|
28
|
+
description?: string
|
|
29
|
+
/** Overrides the publisher derived from the registry. */
|
|
30
|
+
publisher?: CatalogPublisher
|
|
31
|
+
/** Overrides the brand mark derived from the ref (`node`, `python`…). */
|
|
32
|
+
mark?: string
|
|
33
|
+
/** Real logo (a URL) instead of an embedded brand mark. */
|
|
34
|
+
iconUrl?: string | null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** One configurable option of a feature, as the catalog advertises it. */
|
|
38
|
+
export interface DevcontainerFeatureOption {
|
|
39
|
+
name?: string
|
|
40
|
+
default?: string
|
|
41
|
+
description?: string
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** A devcontainer feature of the catalog. */
|
|
45
|
+
export interface DevcontainerFeatureEntry {
|
|
46
|
+
id?: string
|
|
47
|
+
label?: string
|
|
48
|
+
/** OCI reference the feature is installed from. */
|
|
49
|
+
ociRef?: string
|
|
50
|
+
/** Feature installed from a script shipped by the platform, not from a registry. */
|
|
51
|
+
localScript?: string
|
|
52
|
+
description?: string
|
|
53
|
+
options?: DevcontainerFeatureOption[]
|
|
54
|
+
/** Options the platform always passes, on top of the catalog defaults. */
|
|
55
|
+
defaultOptions?: Record<string, string> | null
|
|
56
|
+
publisher?: CatalogPublisher
|
|
57
|
+
mark?: string
|
|
58
|
+
iconUrl?: string | null
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* A VS Code extension. Shaped to swallow an Open VSX search result as-is
|
|
63
|
+
* (`namespace` + `name` + `files.icon` + `downloadCount`…) as well as the
|
|
64
|
+
* flattened form an app might store.
|
|
65
|
+
*/
|
|
66
|
+
export interface VscodeExtensionEntry {
|
|
67
|
+
/** `namespace.name` — the id code-server installs. Derived from the two when absent. */
|
|
68
|
+
id?: string
|
|
69
|
+
namespace?: string
|
|
70
|
+
name?: string
|
|
71
|
+
displayName?: string
|
|
72
|
+
description?: string
|
|
73
|
+
version?: string
|
|
74
|
+
/** Flattened icon URL. Takes precedence over `files.icon`. */
|
|
75
|
+
iconUrl?: string | null
|
|
76
|
+
/** Raw Open VSX payload — only `icon` is read. */
|
|
77
|
+
files?: { icon?: string | null } | null
|
|
78
|
+
downloadCount?: number | null
|
|
79
|
+
averageRating?: number | null
|
|
80
|
+
reviewCount?: number | null
|
|
81
|
+
/** Open VSX `verified` — the namespace is owned by its publisher. */
|
|
82
|
+
verified?: boolean
|
|
83
|
+
publisher?: CatalogPublisher
|
|
84
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState, type ComponentProps } from "react"
|
|
4
|
+
|
|
5
|
+
import { cn } from "../utils"
|
|
6
|
+
|
|
7
|
+
// One key = one cap. Kept as a constant so `Kbd` and every caller (the command
|
|
8
|
+
// palette footer, an item's `shortcut`) draw the exact same box.
|
|
9
|
+
const capClass =
|
|
10
|
+
"inline-flex h-5 min-w-5 items-center justify-center rounded border border-border bg-muted px-1.5 font-sans text-[0.6875rem] leading-none font-medium text-muted-foreground"
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Symbol shown per modifier, per platform, plus the accessible name a screen
|
|
14
|
+
* reader gets instead of the glyph ("⌘" alone reads as nothing useful).
|
|
15
|
+
* `mod` is the portable modifier: ⌘ on Apple, Ctrl everywhere else — the one
|
|
16
|
+
* every "⌘K" shortcut actually means.
|
|
17
|
+
*/
|
|
18
|
+
const KEYS: Record<string, { mac: string; other: string; label: string }> = {
|
|
19
|
+
mod: { mac: "⌘", other: "Ctrl", label: "Ctrl" },
|
|
20
|
+
meta: { mac: "⌘", other: "Win", label: "Meta" },
|
|
21
|
+
cmd: { mac: "⌘", other: "Ctrl", label: "Commande" },
|
|
22
|
+
command: { mac: "⌘", other: "Ctrl", label: "Commande" },
|
|
23
|
+
ctrl: { mac: "⌃", other: "Ctrl", label: "Ctrl" },
|
|
24
|
+
control: { mac: "⌃", other: "Ctrl", label: "Ctrl" },
|
|
25
|
+
alt: { mac: "⌥", other: "Alt", label: "Alt" },
|
|
26
|
+
option: { mac: "⌥", other: "Alt", label: "Alt" },
|
|
27
|
+
shift: { mac: "⇧", other: "Maj", label: "Maj" },
|
|
28
|
+
enter: { mac: "↵", other: "↵", label: "Entrée" },
|
|
29
|
+
return: { mac: "↵", other: "↵", label: "Entrée" },
|
|
30
|
+
esc: { mac: "esc", other: "esc", label: "Échap" },
|
|
31
|
+
escape: { mac: "esc", other: "esc", label: "Échap" },
|
|
32
|
+
backspace: { mac: "⌫", other: "⌫", label: "Retour arrière" },
|
|
33
|
+
delete: { mac: "⌦", other: "Suppr", label: "Suppr" },
|
|
34
|
+
tab: { mac: "⇥", other: "⇥", label: "Tab" },
|
|
35
|
+
space: { mac: "␣", other: "␣", label: "Espace" },
|
|
36
|
+
up: { mac: "↑", other: "↑", label: "Flèche haut" },
|
|
37
|
+
down: { mac: "↓", other: "↓", label: "Flèche bas" },
|
|
38
|
+
left: { mac: "←", other: "←", label: "Flèche gauche" },
|
|
39
|
+
right: { mac: "→", other: "→", label: "Flèche droite" },
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Apple platform detection, deferred to an effect on purpose: the package is
|
|
44
|
+
* consumed from a Next.js App Router, so the first render must be identical on
|
|
45
|
+
* the server and on the client. We render the portable label ("Ctrl") first and
|
|
46
|
+
* swap to "⌘" after mount rather than reading `navigator` during render.
|
|
47
|
+
*/
|
|
48
|
+
function useApplePlatform(): boolean {
|
|
49
|
+
const [isApple, setIsApple] = useState(false)
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
const ua = navigator.userAgent
|
|
52
|
+
setIsApple(/Mac|iPhone|iPad|iPod/.test(ua))
|
|
53
|
+
}, [])
|
|
54
|
+
return isApple
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function keyGlyph(part: string, isApple: boolean): string {
|
|
58
|
+
const known = KEYS[part.toLowerCase()]
|
|
59
|
+
if (known) return isApple ? known.mac : known.other
|
|
60
|
+
// Single letters read better upper-cased ("K"), longer names as written ("F5").
|
|
61
|
+
return part.length === 1 ? part.toUpperCase() : part
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function keyLabel(part: string): string {
|
|
65
|
+
return KEYS[part.toLowerCase()]?.label ?? part.toUpperCase()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface KbdProps extends ComponentProps<"kbd"> {
|
|
69
|
+
/**
|
|
70
|
+
* Shortcut expressed as `"mod+shift+p"` — rendered as one cap per key, with
|
|
71
|
+
* `mod` resolved to ⌘ or Ctrl depending on the platform. Omit it and pass
|
|
72
|
+
* children instead to draw a single raw cap (`<Kbd>↵</Kbd>`).
|
|
73
|
+
*/
|
|
74
|
+
keys?: string
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* A keyboard key, drawn as a cap. Either a raw one (`<Kbd>↵</Kbd>`) or a whole
|
|
79
|
+
* shortcut (`<Kbd keys="mod+k" />` → ⌘ K), which is the form the command palette
|
|
80
|
+
* uses for item shortcuts and footer hints.
|
|
81
|
+
*
|
|
82
|
+
* The accessible name is spelled out ("Commande + K"), because the glyphs alone
|
|
83
|
+
* announce as gibberish — or as nothing at all.
|
|
84
|
+
*/
|
|
85
|
+
function Kbd({ className, keys, children, ...props }: KbdProps) {
|
|
86
|
+
const isApple = useApplePlatform()
|
|
87
|
+
|
|
88
|
+
if (!keys) {
|
|
89
|
+
return (
|
|
90
|
+
<kbd data-slot="kbd" className={cn(capClass, className)} {...props}>
|
|
91
|
+
{children}
|
|
92
|
+
</kbd>
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const parts = keys
|
|
97
|
+
.split("+")
|
|
98
|
+
.map((p) => p.trim())
|
|
99
|
+
.filter(Boolean)
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<kbd
|
|
103
|
+
data-slot="kbd"
|
|
104
|
+
aria-label={parts.map(keyLabel).join(" + ")}
|
|
105
|
+
className={cn("inline-flex items-center gap-1 border-0 bg-transparent p-0", className)}
|
|
106
|
+
{...props}
|
|
107
|
+
>
|
|
108
|
+
{parts.map((part, i) => (
|
|
109
|
+
<kbd key={`${part}-${i}`} aria-hidden className={capClass}>
|
|
110
|
+
{keyGlyph(part, isApple)}
|
|
111
|
+
</kbd>
|
|
112
|
+
))}
|
|
113
|
+
</kbd>
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export { Kbd }
|