@orangecheck/app-design 1.0.0 → 1.1.1
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 +21 -5
- package/dist/chrome.d.mts +31 -42
- package/dist/chrome.d.ts +31 -42
- package/dist/chrome.js +502 -24
- package/dist/chrome.js.map +1 -1
- package/dist/chrome.mjs +497 -26
- package/dist/chrome.mjs.map +1 -1
- package/dist/code.d.mts +52 -0
- package/dist/code.d.ts +52 -0
- package/dist/code.js +534 -0
- package/dist/code.js.map +1 -0
- package/dist/code.mjs +522 -0
- package/dist/code.mjs.map +1 -0
- package/dist/components.d.mts +61 -117
- package/dist/components.d.ts +61 -117
- package/dist/components.js +2178 -106
- package/dist/components.js.map +1 -1
- package/dist/components.mjs +2150 -110
- package/dist/components.mjs.map +1 -1
- package/dist/docs-DhnstueM.d.ts +219 -0
- package/dist/docs-DiR6s43s.d.mts +219 -0
- package/dist/family.js +2 -1
- package/dist/family.js.map +1 -1
- package/dist/family.mjs +2 -1
- package/dist/family.mjs.map +1 -1
- package/dist/format.d.mts +12 -0
- package/dist/format.d.ts +12 -0
- package/dist/format.js +65 -0
- package/dist/format.js.map +1 -0
- package/dist/format.mjs +58 -0
- package/dist/format.mjs.map +1 -0
- package/dist/hero-Dn37il-9.d.mts +31 -0
- package/dist/hero-Dn37il-9.d.ts +31 -0
- package/dist/index.d.mts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +2675 -131
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2621 -134
- package/dist/index.mjs.map +1 -1
- package/dist/mdx.d.mts +58 -0
- package/dist/mdx.d.ts +58 -0
- package/dist/mdx.js +1719 -0
- package/dist/mdx.js.map +1 -0
- package/dist/mdx.mjs +1692 -0
- package/dist/mdx.mjs.map +1 -0
- package/dist/primitives.d.mts +22 -5
- package/dist/primitives.d.ts +22 -5
- package/dist/primitives.js +51 -5
- package/dist/primitives.js.map +1 -1
- package/dist/primitives.mjs +51 -7
- package/dist/primitives.mjs.map +1 -1
- package/dist/session.d.mts +18 -0
- package/dist/session.d.ts +18 -0
- package/dist/session.js +432 -0
- package/dist/session.js.map +1 -0
- package/dist/session.mjs +401 -0
- package/dist/session.mjs.map +1 -0
- package/dist/styles/code.css +97 -0
- package/dist/styles/theme.css +2 -0
- package/dist/styles/tokens.css +40 -0
- package/dist/styles.css +1 -0
- package/dist/tool-shell-B1C7ahKE.d.ts +81 -0
- package/dist/tool-shell-BDx_N5ai.d.mts +81 -0
- package/dist/tools-BggNN5DV.d.ts +131 -0
- package/dist/tools-DFIxIj5p.d.mts +131 -0
- package/package.json +31 -2
package/dist/mdx.mjs
ADDED
|
@@ -0,0 +1,1692 @@
|
|
|
1
|
+
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
2
|
+
import { forwardRef, createContext, useState, useMemo, useRef, useId, useEffect, useCallback, useSyncExternalStore, Children, isValidElement } from 'react';
|
|
3
|
+
import { clsx } from 'clsx';
|
|
4
|
+
import { extendTailwindMerge } from 'tailwind-merge';
|
|
5
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
|
+
import { ArrowUpRight, ArrowRight, Check, Copy } from 'lucide-react';
|
|
7
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
8
|
+
import { cva } from 'class-variance-authority';
|
|
9
|
+
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
10
|
+
import 'sonner';
|
|
11
|
+
import Link from 'next/link';
|
|
12
|
+
|
|
13
|
+
// src/code/highlight.ts
|
|
14
|
+
var TOKEN_CLASS = {
|
|
15
|
+
keyword: "oca-k",
|
|
16
|
+
string: "oca-s",
|
|
17
|
+
number: "oca-n",
|
|
18
|
+
function: "oca-f",
|
|
19
|
+
type: "oca-y",
|
|
20
|
+
property: "oca-p",
|
|
21
|
+
comment: "oca-c",
|
|
22
|
+
tag: "oca-g",
|
|
23
|
+
url: "oca-u"
|
|
24
|
+
};
|
|
25
|
+
var ALIASES = {
|
|
26
|
+
ts: "js",
|
|
27
|
+
typescript: "js",
|
|
28
|
+
tsx: "js",
|
|
29
|
+
js: "js",
|
|
30
|
+
javascript: "js",
|
|
31
|
+
jsx: "js",
|
|
32
|
+
mjs: "js",
|
|
33
|
+
cjs: "js",
|
|
34
|
+
json: "json",
|
|
35
|
+
jsonc: "json",
|
|
36
|
+
json5: "json",
|
|
37
|
+
bash: "shell",
|
|
38
|
+
sh: "shell",
|
|
39
|
+
shell: "shell",
|
|
40
|
+
zsh: "shell",
|
|
41
|
+
console: "shell",
|
|
42
|
+
terminal: "shell",
|
|
43
|
+
py: "python",
|
|
44
|
+
python: "python",
|
|
45
|
+
yaml: "yaml",
|
|
46
|
+
yml: "yaml",
|
|
47
|
+
diff: "diff"
|
|
48
|
+
};
|
|
49
|
+
function grammarOf(lang) {
|
|
50
|
+
return lang && ALIASES[lang.toLowerCase()] || "plain";
|
|
51
|
+
}
|
|
52
|
+
function collector() {
|
|
53
|
+
const tokens = [];
|
|
54
|
+
const emit = (text, kind) => {
|
|
55
|
+
if (!text) return;
|
|
56
|
+
const last = tokens[tokens.length - 1];
|
|
57
|
+
if (last && last.kind === kind) last.text += text;
|
|
58
|
+
else tokens.push(kind ? { text, kind } : { text });
|
|
59
|
+
};
|
|
60
|
+
return { emit, tokens };
|
|
61
|
+
}
|
|
62
|
+
function at(re, src, i) {
|
|
63
|
+
re.lastIndex = i;
|
|
64
|
+
const m = re.exec(src);
|
|
65
|
+
return m ? m[0] : null;
|
|
66
|
+
}
|
|
67
|
+
var WS = /[ \t]+/y;
|
|
68
|
+
var NEWLINE = /\r?\n/y;
|
|
69
|
+
var JS_KEYWORDS = new Set(
|
|
70
|
+
"abstract as async await break case catch class const continue debugger declare default delete do else enum export extends finally for from function get if implements import in infer instanceof interface is keyof let module namespace new of override private protected public readonly return satisfies set static super switch this throw try type typeof unique var void while with yield".split(" ")
|
|
71
|
+
);
|
|
72
|
+
var JS_CONSTANTS = /* @__PURE__ */ new Set(["true", "false", "null", "undefined", "NaN", "Infinity"]);
|
|
73
|
+
var TS_PRIMITIVES = /* @__PURE__ */ new Set(["string", "number", "boolean", "bigint", "symbol", "object", "unknown", "any", "never"]);
|
|
74
|
+
var isConstant = (m) => /^[A-Z][A-Z\d_]+$/.test(m) && (m.includes("_") || m.length > 4);
|
|
75
|
+
var JS_LINE_COMMENT = /\/\/[^\n]*/y;
|
|
76
|
+
var JS_BLOCK_COMMENT = /\/\*[\s\S]*?(?:\*\/|$)/y;
|
|
77
|
+
var JS_TEMPLATE = /`(?:\\[\s\S]|[^\\`])*`?/y;
|
|
78
|
+
var JS_STRING = /'(?:\\.|[^\\'\n])*'?|"(?:\\.|[^\\"\n])*"?/y;
|
|
79
|
+
var JS_NUMBER = /(?:0[xX][\da-fA-F_]+|0[bB][01_]+|0[oO][0-7_]+|\d[\d_]*(?:\.[\d_]+)?(?:[eE][+-]?\d+)?|\.\d[\d_]*(?:[eE][+-]?\d+)?)n?/y;
|
|
80
|
+
var JS_IDENT = /[A-Za-z_$][\w$]*/y;
|
|
81
|
+
var JS_DECORATOR = /@[A-Za-z_$][\w$.]*/y;
|
|
82
|
+
var JS_CALL_AFTER = /\s*(?:<[\w$\s,.[\]|&'"]*>)?\s*\(/y;
|
|
83
|
+
var JS_TAG = /<\/?(?=[A-Za-z])/y;
|
|
84
|
+
var JS_TAG_NAME = /[A-Za-z][\w$.:-]*/y;
|
|
85
|
+
var JS_PUNCT = /=>|\.\.\.|[{}()[\];,.<>=+\-*/%!?:&|^~#]/y;
|
|
86
|
+
var JSX_BEFORE = /* @__PURE__ */ new Set(["(", ",", "=", "?", ":", "{", "[", ";", ">", "&&", "||", "=>", "return"]);
|
|
87
|
+
function scanJs(src, emit, jsx13) {
|
|
88
|
+
let i = 0;
|
|
89
|
+
let prev = "";
|
|
90
|
+
let tagDepth = 0;
|
|
91
|
+
let braceInTag = 0;
|
|
92
|
+
const sig = (t) => {
|
|
93
|
+
prev = t;
|
|
94
|
+
};
|
|
95
|
+
while (i < src.length) {
|
|
96
|
+
let m;
|
|
97
|
+
if ((m = at(WS, src, i)) || (m = at(NEWLINE, src, i))) {
|
|
98
|
+
emit(m);
|
|
99
|
+
i += m.length;
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if ((m = at(JS_LINE_COMMENT, src, i)) || (m = at(JS_BLOCK_COMMENT, src, i))) {
|
|
103
|
+
emit(m, "comment");
|
|
104
|
+
i += m.length;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if ((m = at(JS_TEMPLATE, src, i)) || (m = at(JS_STRING, src, i))) {
|
|
108
|
+
emit(m, "string");
|
|
109
|
+
i += m.length;
|
|
110
|
+
sig('"');
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (jsx13 && tagDepth === 0 && (m = at(JS_TAG, src, i)) && (prev === "" || JSX_BEFORE.has(prev))) {
|
|
114
|
+
const name = at(JS_TAG_NAME, src, i + m.length);
|
|
115
|
+
if (name) {
|
|
116
|
+
emit(m);
|
|
117
|
+
emit(name, "tag");
|
|
118
|
+
i += m.length + name.length;
|
|
119
|
+
tagDepth = 1;
|
|
120
|
+
braceInTag = 0;
|
|
121
|
+
sig("tag");
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (jsx13 && tagDepth > 0 && braceInTag === 0) {
|
|
126
|
+
if (src.startsWith("/>", i) || src[i] === ">") {
|
|
127
|
+
const close = src[i] === ">" ? ">" : "/>";
|
|
128
|
+
emit(close);
|
|
129
|
+
i += close.length;
|
|
130
|
+
tagDepth = 0;
|
|
131
|
+
sig(">");
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if ((m = at(JS_IDENT, src, i)) && /^\s*=/.test(src.slice(i + m.length, i + m.length + 4))) {
|
|
135
|
+
emit(m, "property");
|
|
136
|
+
i += m.length;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (m = at(JS_IDENT, src, i)) {
|
|
140
|
+
emit(m, "property");
|
|
141
|
+
i += m.length;
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (src[i] === "{") braceInTag = 1;
|
|
145
|
+
} else if (jsx13 && tagDepth > 0 && braceInTag > 0) {
|
|
146
|
+
if (src[i] === "{") braceInTag++;
|
|
147
|
+
else if (src[i] === "}") braceInTag--;
|
|
148
|
+
}
|
|
149
|
+
if (m = at(JS_DECORATOR, src, i)) {
|
|
150
|
+
emit(m, "function");
|
|
151
|
+
i += m.length;
|
|
152
|
+
sig("@");
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
if (m = at(JS_IDENT, src, i)) {
|
|
156
|
+
const end = i + m.length;
|
|
157
|
+
let kind;
|
|
158
|
+
if (prev !== "." && JS_CONSTANTS.has(m)) kind = "number";
|
|
159
|
+
else if (prev !== "." && JS_KEYWORDS.has(m)) kind = "keyword";
|
|
160
|
+
else if (at(JS_CALL_AFTER, src, end) !== null) kind = "function";
|
|
161
|
+
else if (prev !== "." && TS_PRIMITIVES.has(m)) kind = "type";
|
|
162
|
+
else if (isConstant(m)) kind = "number";
|
|
163
|
+
else if (/^[A-Z]/.test(m)) kind = "type";
|
|
164
|
+
emit(m, kind);
|
|
165
|
+
i = end;
|
|
166
|
+
sig(kind === "keyword" ? m : "id");
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (m = at(JS_NUMBER, src, i)) {
|
|
170
|
+
emit(m, "number");
|
|
171
|
+
i += m.length;
|
|
172
|
+
sig("0");
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (m = at(JS_PUNCT, src, i)) {
|
|
176
|
+
emit(m);
|
|
177
|
+
i += m.length;
|
|
178
|
+
sig(m === "." ? "." : m);
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
emit(src[i]);
|
|
182
|
+
i++;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
var JSON_STRING = /"(?:\\.|[^\\"\n])*"?/y;
|
|
186
|
+
var JSON_KEY_AFTER = /\s*:/y;
|
|
187
|
+
var JSON_NUMBER = /-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/y;
|
|
188
|
+
var JSON_WORD = /true|false|null/y;
|
|
189
|
+
function scanJson(src, emit) {
|
|
190
|
+
let i = 0;
|
|
191
|
+
while (i < src.length) {
|
|
192
|
+
let m;
|
|
193
|
+
if ((m = at(JS_LINE_COMMENT, src, i)) || (m = at(JS_BLOCK_COMMENT, src, i))) {
|
|
194
|
+
emit(m, "comment");
|
|
195
|
+
} else if (m = at(JSON_STRING, src, i)) {
|
|
196
|
+
emit(m, at(JSON_KEY_AFTER, src, i + m.length) !== null ? "property" : "string");
|
|
197
|
+
} else if ((m = at(JSON_NUMBER, src, i)) || (m = at(JSON_WORD, src, i))) {
|
|
198
|
+
emit(m, "number");
|
|
199
|
+
} else {
|
|
200
|
+
m = src[i];
|
|
201
|
+
emit(m);
|
|
202
|
+
}
|
|
203
|
+
i += m.length;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
var SH_KEYWORDS = new Set(
|
|
207
|
+
"if then else elif fi for in do done case esac while until function return export local select time".split(" ")
|
|
208
|
+
);
|
|
209
|
+
var SH_PROMPT = /\$ (?=\S)/y;
|
|
210
|
+
var SH_COMMENT = /#[^\n]*/y;
|
|
211
|
+
var SH_SINGLE = /'[^']*'?/y;
|
|
212
|
+
var SH_DOUBLE = /"(?:\\.|[^\\"])*"?/y;
|
|
213
|
+
var SH_VAR = /\$(?:\{[^}\n]*\}?|[A-Za-z_][\w]*|[@*#?$!\d])/y;
|
|
214
|
+
var SH_URL = /https?:\/\/[^\s'"`)]+/y;
|
|
215
|
+
var SH_FLAG = /--?[A-Za-z][\w-]*/y;
|
|
216
|
+
var SH_ASSIGN = /[A-Za-z_][\w]*(?==)/y;
|
|
217
|
+
var SH_VALUE = /=[^\s|&;()<>'"`$]*/y;
|
|
218
|
+
var SH_WORD = /[^\s|&;()<>'"`$#]+/y;
|
|
219
|
+
var SH_OPERATOR = /\|\||&&|[|;&]|\$\(|[()<>]/y;
|
|
220
|
+
function scanShell(src, emit) {
|
|
221
|
+
let i = 0;
|
|
222
|
+
let command = true;
|
|
223
|
+
let lineStart = true;
|
|
224
|
+
while (i < src.length) {
|
|
225
|
+
let m;
|
|
226
|
+
if (m = at(NEWLINE, src, i)) {
|
|
227
|
+
emit(m);
|
|
228
|
+
i += m.length;
|
|
229
|
+
command = !/\\\s*$/.test(src.slice(0, i - m.length));
|
|
230
|
+
lineStart = true;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (m = at(WS, src, i)) {
|
|
234
|
+
emit(m);
|
|
235
|
+
i += m.length;
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
if (lineStart && (m = at(SH_PROMPT, src, i))) {
|
|
239
|
+
emit(m, "comment");
|
|
240
|
+
i += m.length;
|
|
241
|
+
lineStart = false;
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
lineStart = false;
|
|
245
|
+
if ((m = at(SH_COMMENT, src, i)) && (i === 0 || /\s/.test(src[i - 1]))) {
|
|
246
|
+
emit(m, "comment");
|
|
247
|
+
i += m.length;
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if ((m = at(SH_SINGLE, src, i)) || (m = at(SH_DOUBLE, src, i))) {
|
|
251
|
+
emit(m, "string");
|
|
252
|
+
i += m.length;
|
|
253
|
+
command = false;
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
if (m = at(SH_OPERATOR, src, i)) {
|
|
257
|
+
emit(m);
|
|
258
|
+
i += m.length;
|
|
259
|
+
command = m !== ")" && m !== ">" && m !== "<";
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
if (m = at(SH_VAR, src, i)) {
|
|
263
|
+
emit(m, "type");
|
|
264
|
+
i += m.length;
|
|
265
|
+
command = false;
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
if (m = at(SH_URL, src, i)) {
|
|
269
|
+
emit(m, "url");
|
|
270
|
+
i += m.length;
|
|
271
|
+
command = false;
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
if (command && (m = at(SH_ASSIGN, src, i))) {
|
|
275
|
+
emit(m, "property");
|
|
276
|
+
i += m.length;
|
|
277
|
+
const v = at(SH_VALUE, src, i);
|
|
278
|
+
emit(v);
|
|
279
|
+
i += v.length;
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
if ((m = at(SH_FLAG, src, i)) && !command) {
|
|
283
|
+
emit(m, "keyword");
|
|
284
|
+
i += m.length;
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
if (m = at(SH_WORD, src, i)) {
|
|
288
|
+
if (command && SH_KEYWORDS.has(m)) emit(m, "keyword");
|
|
289
|
+
else if (command) {
|
|
290
|
+
emit(m, "function");
|
|
291
|
+
command = m === "sudo" || m === "npx" || m === "env" || m === "time";
|
|
292
|
+
i += m.length;
|
|
293
|
+
continue;
|
|
294
|
+
} else emit(m);
|
|
295
|
+
i += m.length;
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
emit(src[i]);
|
|
299
|
+
i++;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
var PY_KEYWORDS = new Set(
|
|
303
|
+
"and as assert async await break class continue def del elif else except finally for from global if import in is lambda match case nonlocal not or pass raise return try while with yield self cls".split(" ")
|
|
304
|
+
);
|
|
305
|
+
var PY_CONSTANTS = /* @__PURE__ */ new Set(["True", "False", "None"]);
|
|
306
|
+
var PY_TYPES = /* @__PURE__ */ new Set(["int", "str", "bool", "float", "bytes", "list", "dict", "tuple", "set", "object"]);
|
|
307
|
+
var PY_COMMENT = /#[^\n]*/y;
|
|
308
|
+
var PY_TRIPLE = /[rRbBuUfF]{0,2}(?:"""[\s\S]*?(?:"""|$)|'''[\s\S]*?(?:'''|$))/y;
|
|
309
|
+
var PY_STRING = /[rRbBuUfF]{0,2}(?:'(?:\\.|[^\\'\n])*'?|"(?:\\.|[^\\"\n])*"?)/y;
|
|
310
|
+
var PY_NUMBER = /(?:0[xX][\da-fA-F_]+|\d[\d_]*(?:\.[\d_]*)?(?:[eE][+-]?\d+)?j?)/y;
|
|
311
|
+
var PY_IDENT = /[A-Za-z_]\w*/y;
|
|
312
|
+
var PY_DECORATOR = /@[A-Za-z_][\w.]*/y;
|
|
313
|
+
var PY_CALL_AFTER = /\s*\(/y;
|
|
314
|
+
function scanPython(src, emit) {
|
|
315
|
+
let i = 0;
|
|
316
|
+
let prev = "";
|
|
317
|
+
while (i < src.length) {
|
|
318
|
+
let m;
|
|
319
|
+
if ((m = at(WS, src, i)) || (m = at(NEWLINE, src, i))) {
|
|
320
|
+
emit(m);
|
|
321
|
+
i += m.length;
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
if (m = at(PY_COMMENT, src, i)) {
|
|
325
|
+
emit(m, "comment");
|
|
326
|
+
} else if ((m = at(PY_TRIPLE, src, i)) || (m = at(PY_STRING, src, i))) {
|
|
327
|
+
if (/^[A-Za-z]+$/.test(m)) {
|
|
328
|
+
emit(m);
|
|
329
|
+
} else emit(m, "string");
|
|
330
|
+
prev = '"';
|
|
331
|
+
} else if (m = at(PY_DECORATOR, src, i)) {
|
|
332
|
+
emit(m, "function");
|
|
333
|
+
prev = "@";
|
|
334
|
+
} else if (m = at(PY_IDENT, src, i)) {
|
|
335
|
+
let kind;
|
|
336
|
+
if (PY_CONSTANTS.has(m)) kind = "number";
|
|
337
|
+
else if (prev !== "." && PY_KEYWORDS.has(m)) kind = "keyword";
|
|
338
|
+
else if (prev === "def" || at(PY_CALL_AFTER, src, i + m.length) !== null) kind = "function";
|
|
339
|
+
else if (prev === "class" || /^[A-Z][a-z]/.test(m) || PY_TYPES.has(m)) kind = "type";
|
|
340
|
+
else if (isConstant(m)) kind = "number";
|
|
341
|
+
emit(m, kind);
|
|
342
|
+
prev = kind === "keyword" ? m : "id";
|
|
343
|
+
} else if (m = at(PY_NUMBER, src, i)) {
|
|
344
|
+
emit(m, "number");
|
|
345
|
+
prev = "0";
|
|
346
|
+
} else {
|
|
347
|
+
m = src[i];
|
|
348
|
+
emit(m);
|
|
349
|
+
prev = m;
|
|
350
|
+
}
|
|
351
|
+
i += m.length;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
var YAML_KEY = /[ \t]*(?:- )?[\w.$/-]+(?=[ \t]*:(?:\s|$))/y;
|
|
355
|
+
var YAML_VALUE_WORD = /(?:true|false|null|yes|no|~|-?\d+(?:\.\d+)?)(?=\s*(?:#|$))/y;
|
|
356
|
+
function scanYaml(src, emit) {
|
|
357
|
+
let i = 0;
|
|
358
|
+
let lineStart = true;
|
|
359
|
+
while (i < src.length) {
|
|
360
|
+
let m;
|
|
361
|
+
if (m = at(NEWLINE, src, i)) {
|
|
362
|
+
emit(m);
|
|
363
|
+
i += m.length;
|
|
364
|
+
lineStart = true;
|
|
365
|
+
continue;
|
|
366
|
+
}
|
|
367
|
+
if (lineStart && (m = at(YAML_KEY, src, i))) {
|
|
368
|
+
const dash = m.match(/^([ \t]*(?:- )?)/)[1];
|
|
369
|
+
emit(dash);
|
|
370
|
+
emit(m.slice(dash.length), "property");
|
|
371
|
+
i += m.length;
|
|
372
|
+
lineStart = false;
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
lineStart = false;
|
|
376
|
+
if ((m = at(SH_COMMENT, src, i)) && (i === 0 || /\s/.test(src[i - 1]))) emit(m, "comment");
|
|
377
|
+
else if ((m = at(SH_SINGLE, src, i)) || (m = at(JSON_STRING, src, i))) emit(m, "string");
|
|
378
|
+
else if (m = at(YAML_VALUE_WORD, src, i)) emit(m, "number");
|
|
379
|
+
else if (m = at(SH_URL, src, i)) emit(m, "url");
|
|
380
|
+
else {
|
|
381
|
+
m = src[i];
|
|
382
|
+
emit(m);
|
|
383
|
+
}
|
|
384
|
+
i += m.length;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
function toLines(tokens) {
|
|
388
|
+
const lines = [[]];
|
|
389
|
+
for (const t of tokens) {
|
|
390
|
+
const parts = t.text.split(/\r?\n/);
|
|
391
|
+
parts.forEach((part, j) => {
|
|
392
|
+
if (j > 0) lines.push([]);
|
|
393
|
+
if (part) lines[lines.length - 1].push(t.kind ? { text: part, kind: t.kind } : { text: part });
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
return lines;
|
|
397
|
+
}
|
|
398
|
+
function highlight(code, lang) {
|
|
399
|
+
const src = code.replace(/\r?\n$/, "");
|
|
400
|
+
const grammar = grammarOf(lang);
|
|
401
|
+
const { emit, tokens } = collector();
|
|
402
|
+
const name = (lang ?? "").toLowerCase();
|
|
403
|
+
switch (grammar) {
|
|
404
|
+
case "js":
|
|
405
|
+
scanJs(src, emit, name === "tsx" || name === "jsx");
|
|
406
|
+
break;
|
|
407
|
+
case "json":
|
|
408
|
+
scanJson(src, emit);
|
|
409
|
+
break;
|
|
410
|
+
case "shell":
|
|
411
|
+
scanShell(src, emit);
|
|
412
|
+
break;
|
|
413
|
+
case "python":
|
|
414
|
+
scanPython(src, emit);
|
|
415
|
+
break;
|
|
416
|
+
case "yaml":
|
|
417
|
+
scanYaml(src, emit);
|
|
418
|
+
break;
|
|
419
|
+
default:
|
|
420
|
+
emit(src);
|
|
421
|
+
}
|
|
422
|
+
return toLines(tokens);
|
|
423
|
+
}
|
|
424
|
+
function readDiff(code) {
|
|
425
|
+
const diff = /* @__PURE__ */ new Map();
|
|
426
|
+
const lines = code.replace(/\r?\n$/, "").split(/\r?\n/);
|
|
427
|
+
const out = lines.map((line, i) => {
|
|
428
|
+
const c = line[0];
|
|
429
|
+
if (c === "+" || c === "-") {
|
|
430
|
+
diff.set(i + 1, c === "+" ? "add" : "remove");
|
|
431
|
+
return line.slice(1);
|
|
432
|
+
}
|
|
433
|
+
return c === " " ? line.slice(1) : line;
|
|
434
|
+
});
|
|
435
|
+
return { code: out.join("\n"), diff };
|
|
436
|
+
}
|
|
437
|
+
function parseLineRanges(spec) {
|
|
438
|
+
if (!spec) return /* @__PURE__ */ new Set();
|
|
439
|
+
if (typeof spec !== "string") return new Set(spec);
|
|
440
|
+
const out = /* @__PURE__ */ new Set();
|
|
441
|
+
for (const part of spec.split(",")) {
|
|
442
|
+
const m = part.trim().match(/^(\d+)(?:\s*-\s*(\d+))?$/);
|
|
443
|
+
if (!m) continue;
|
|
444
|
+
const a = Number(m[1]);
|
|
445
|
+
const b = m[2] ? Number(m[2]) : a;
|
|
446
|
+
for (let n = Math.min(a, b); n <= Math.max(a, b) && n - a < 1e4; n++) out.add(n);
|
|
447
|
+
}
|
|
448
|
+
return out;
|
|
449
|
+
}
|
|
450
|
+
var ESCAPE = { "&": "&", "<": "<", ">": ">", '"': """ };
|
|
451
|
+
function escapeHtml(s) {
|
|
452
|
+
return s.replace(/[&<>"]/g, (c) => ESCAPE[c]);
|
|
453
|
+
}
|
|
454
|
+
function linesToHtml(lines, marks = {}) {
|
|
455
|
+
return lines.map((line, i) => {
|
|
456
|
+
const n = i + 1;
|
|
457
|
+
const attrs = [
|
|
458
|
+
'data-line=""',
|
|
459
|
+
marks.highlight?.has(n) ? 'data-mark=""' : "",
|
|
460
|
+
marks.diff?.has(n) ? `data-diff="${marks.diff.get(n)}"` : ""
|
|
461
|
+
].filter(Boolean).join(" ");
|
|
462
|
+
const body = line.map((t) => t.kind ? `<span class="${TOKEN_CLASS[t.kind]}">${escapeHtml(t.text)}</span>` : escapeHtml(t.text)).join("");
|
|
463
|
+
return `<span ${attrs}>${body}</span>`;
|
|
464
|
+
}).join("\n");
|
|
465
|
+
}
|
|
466
|
+
var merge = extendTailwindMerge({
|
|
467
|
+
extend: {
|
|
468
|
+
classGroups: {
|
|
469
|
+
"oca-type": [
|
|
470
|
+
"oca-display-1",
|
|
471
|
+
"oca-display-2",
|
|
472
|
+
"oca-display-3",
|
|
473
|
+
"oca-title",
|
|
474
|
+
"oca-title-sm",
|
|
475
|
+
"oca-eyebrow",
|
|
476
|
+
"oca-lead",
|
|
477
|
+
"oca-body",
|
|
478
|
+
"oca-numeral"
|
|
479
|
+
]
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
function cn(...inputs) {
|
|
484
|
+
return merge(clsx(inputs));
|
|
485
|
+
}
|
|
486
|
+
function ScrollFade({ fade = "var(--card)", className, innerClassName, children, ...props }) {
|
|
487
|
+
const ref = useRef(null);
|
|
488
|
+
const [edges, setEdges] = useState({ left: false, right: false });
|
|
489
|
+
const measure = useCallback(() => {
|
|
490
|
+
const el = ref.current;
|
|
491
|
+
if (!el) return;
|
|
492
|
+
const left = el.scrollLeft > 1;
|
|
493
|
+
const right = el.scrollLeft + el.clientWidth < el.scrollWidth - 1;
|
|
494
|
+
setEdges((e) => e.left === left && e.right === right ? e : { left, right });
|
|
495
|
+
}, []);
|
|
496
|
+
useEffect(() => {
|
|
497
|
+
const el = ref.current;
|
|
498
|
+
if (!el) return;
|
|
499
|
+
measure();
|
|
500
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
501
|
+
const ro = new ResizeObserver(measure);
|
|
502
|
+
ro.observe(el);
|
|
503
|
+
if (el.firstElementChild) ro.observe(el.firstElementChild);
|
|
504
|
+
return () => ro.disconnect();
|
|
505
|
+
}, [measure]);
|
|
506
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("relative min-w-0", className), ...props, children: [
|
|
507
|
+
/* @__PURE__ */ jsx(
|
|
508
|
+
"div",
|
|
509
|
+
{
|
|
510
|
+
ref,
|
|
511
|
+
onScroll: measure,
|
|
512
|
+
tabIndex: edges.left || edges.right ? 0 : void 0,
|
|
513
|
+
className: cn(
|
|
514
|
+
"overflow-x-auto overscroll-x-contain rounded-[inherit] outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
515
|
+
innerClassName
|
|
516
|
+
),
|
|
517
|
+
children
|
|
518
|
+
}
|
|
519
|
+
),
|
|
520
|
+
/* @__PURE__ */ jsx(
|
|
521
|
+
"span",
|
|
522
|
+
{
|
|
523
|
+
"aria-hidden": true,
|
|
524
|
+
className: cn(
|
|
525
|
+
"pointer-events-none absolute inset-y-0 left-0 w-8 transition-opacity duration-150",
|
|
526
|
+
edges.left ? "opacity-100" : "opacity-0"
|
|
527
|
+
),
|
|
528
|
+
style: { background: `linear-gradient(to right, ${fade}, transparent)` }
|
|
529
|
+
}
|
|
530
|
+
),
|
|
531
|
+
/* @__PURE__ */ jsx(
|
|
532
|
+
"span",
|
|
533
|
+
{
|
|
534
|
+
"aria-hidden": true,
|
|
535
|
+
className: cn(
|
|
536
|
+
"pointer-events-none absolute inset-y-0 right-0 w-10 transition-opacity duration-150",
|
|
537
|
+
edges.right ? "opacity-100" : "opacity-0"
|
|
538
|
+
),
|
|
539
|
+
style: { background: `linear-gradient(to left, ${fade}, transparent)` }
|
|
540
|
+
}
|
|
541
|
+
)
|
|
542
|
+
] });
|
|
543
|
+
}
|
|
544
|
+
function Spinner({ className, label }) {
|
|
545
|
+
return /* @__PURE__ */ jsxs(
|
|
546
|
+
"svg",
|
|
547
|
+
{
|
|
548
|
+
viewBox: "0 0 24 24",
|
|
549
|
+
fill: "none",
|
|
550
|
+
role: label ? "status" : void 0,
|
|
551
|
+
"aria-label": label,
|
|
552
|
+
"aria-hidden": label ? void 0 : true,
|
|
553
|
+
className: cn("size-4 animate-spin", className),
|
|
554
|
+
children: [
|
|
555
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9", stroke: "currentColor", strokeOpacity: "0.2", strokeWidth: "2.5" }),
|
|
556
|
+
/* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 0 0-9-9", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" })
|
|
557
|
+
]
|
|
558
|
+
}
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
function Skeleton({ className, ...props }) {
|
|
562
|
+
return /* @__PURE__ */ jsx(
|
|
563
|
+
"div",
|
|
564
|
+
{
|
|
565
|
+
"data-ui": "skeleton",
|
|
566
|
+
className: cn("animate-pulse rounded-lg bg-[var(--oca-skeleton)]", className),
|
|
567
|
+
...props
|
|
568
|
+
}
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
forwardRef(function Separator2({ className, orientation = "horizontal", decorative = true, ...props }, ref) {
|
|
572
|
+
return /* @__PURE__ */ jsx(
|
|
573
|
+
SeparatorPrimitive.Root,
|
|
574
|
+
{
|
|
575
|
+
ref,
|
|
576
|
+
decorative,
|
|
577
|
+
orientation,
|
|
578
|
+
className: cn(
|
|
579
|
+
"shrink-0 bg-border",
|
|
580
|
+
orientation === "horizontal" ? "h-px w-full" : "h-full w-px",
|
|
581
|
+
className
|
|
582
|
+
),
|
|
583
|
+
...props
|
|
584
|
+
}
|
|
585
|
+
);
|
|
586
|
+
});
|
|
587
|
+
var buttonVariants = cva(
|
|
588
|
+
[
|
|
589
|
+
"inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-full font-medium",
|
|
590
|
+
"transition-[background-color,border-color,color,box-shadow,transform] duration-150",
|
|
591
|
+
"outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
592
|
+
"active:translate-y-px disabled:pointer-events-none",
|
|
593
|
+
// Disabled is one look for every variant: a quiet grey pill, never a
|
|
594
|
+
// faded black or orange slab that reads as broken.
|
|
595
|
+
"disabled:border disabled:border-border disabled:bg-muted disabled:text-oca-subtle disabled:shadow-none",
|
|
596
|
+
"[&_svg]:pointer-events-none [&_svg]:size-[1.1em] [&_svg]:shrink-0"
|
|
597
|
+
],
|
|
598
|
+
{
|
|
599
|
+
variants: {
|
|
600
|
+
variant: {
|
|
601
|
+
primary: "bg-primary text-primary-foreground hover:bg-primary/85",
|
|
602
|
+
secondary: "border border-border bg-secondary text-secondary-foreground hover:border-oca-hairline-strong hover:bg-accent",
|
|
603
|
+
brand: "bg-brand text-brand-foreground hover:bg-oca-orange-deep",
|
|
604
|
+
ghost: "text-foreground hover:bg-accent",
|
|
605
|
+
danger: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
606
|
+
link: "h-auto rounded-none px-0 text-foreground underline decoration-foreground/35 underline-offset-4 hover:decoration-foreground",
|
|
607
|
+
onInk: "bg-white text-oca-ink hover:bg-white/90",
|
|
608
|
+
onInkOutline: "border border-white/20 text-white hover:bg-white/10"
|
|
609
|
+
},
|
|
610
|
+
size: {
|
|
611
|
+
sm: "h-9 px-4 text-sm",
|
|
612
|
+
md: "h-11 px-5 text-[0.9375rem]",
|
|
613
|
+
lg: "h-14 px-7 text-[1.0625rem]",
|
|
614
|
+
icon: "size-10",
|
|
615
|
+
"icon-sm": "size-8"
|
|
616
|
+
}
|
|
617
|
+
},
|
|
618
|
+
compoundVariants: [{ variant: "link", className: "h-auto px-0" }],
|
|
619
|
+
defaultVariants: { variant: "primary", size: "md" }
|
|
620
|
+
}
|
|
621
|
+
);
|
|
622
|
+
var Button = forwardRef(function Button2({ className, variant, size, asChild = false, loading = false, disabled, children, type, ...props }, ref) {
|
|
623
|
+
const Comp = asChild ? Slot : "button";
|
|
624
|
+
return /* @__PURE__ */ jsx(
|
|
625
|
+
Comp,
|
|
626
|
+
{
|
|
627
|
+
ref,
|
|
628
|
+
"data-ui": "button",
|
|
629
|
+
className: cn(buttonVariants({ variant, size }), className),
|
|
630
|
+
disabled: asChild ? void 0 : disabled || loading,
|
|
631
|
+
"aria-busy": loading || void 0,
|
|
632
|
+
type: asChild ? void 0 : type ?? "button",
|
|
633
|
+
...props,
|
|
634
|
+
children: asChild ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
635
|
+
loading ? /* @__PURE__ */ jsx(Spinner, { className: "size-[1.1em]" }) : null,
|
|
636
|
+
children
|
|
637
|
+
] })
|
|
638
|
+
}
|
|
639
|
+
);
|
|
640
|
+
});
|
|
641
|
+
createContext(false);
|
|
642
|
+
var NOTICE_KIND = {
|
|
643
|
+
neutral: "neutral",
|
|
644
|
+
info: "neutral",
|
|
645
|
+
success: "neutral",
|
|
646
|
+
brand: "brand",
|
|
647
|
+
warning: "brand",
|
|
648
|
+
danger: "danger"
|
|
649
|
+
};
|
|
650
|
+
function Notice({
|
|
651
|
+
tone = "neutral",
|
|
652
|
+
title,
|
|
653
|
+
children,
|
|
654
|
+
action,
|
|
655
|
+
role,
|
|
656
|
+
className
|
|
657
|
+
}) {
|
|
658
|
+
const kind = NOTICE_KIND[tone];
|
|
659
|
+
return /* @__PURE__ */ jsxs(
|
|
660
|
+
"div",
|
|
661
|
+
{
|
|
662
|
+
role: role ?? (tone === "danger" || tone === "warning" ? "alert" : "note"),
|
|
663
|
+
"data-tone": kind,
|
|
664
|
+
className: cn(
|
|
665
|
+
"flex flex-col gap-3 rounded-2xl border border-border bg-card px-5 py-4 sm:flex-row sm:items-start sm:justify-between",
|
|
666
|
+
kind === "danger" && "border-[color-mix(in_oklab,var(--destructive)_40%,var(--border))]",
|
|
667
|
+
className
|
|
668
|
+
),
|
|
669
|
+
children: [
|
|
670
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 gap-3", children: [
|
|
671
|
+
kind !== "neutral" ? /* @__PURE__ */ jsx(
|
|
672
|
+
"span",
|
|
673
|
+
{
|
|
674
|
+
"aria-hidden": true,
|
|
675
|
+
className: cn(
|
|
676
|
+
"mt-[0.45rem] size-2 shrink-0 rounded-full",
|
|
677
|
+
kind === "brand" ? "bg-oca-orange" : "bg-destructive"
|
|
678
|
+
)
|
|
679
|
+
}
|
|
680
|
+
) : null,
|
|
681
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-1", children: [
|
|
682
|
+
title ? /* @__PURE__ */ jsx("p", { className: cn("text-[0.9375rem] font-medium", kind === "danger" && "text-destructive"), children: title }) : null,
|
|
683
|
+
children ? /* @__PURE__ */ jsx("div", { className: "text-[0.9375rem] leading-relaxed text-muted-foreground", children }) : null
|
|
684
|
+
] })
|
|
685
|
+
] }),
|
|
686
|
+
action ? /* @__PURE__ */ jsx("div", { className: "shrink-0", children: action }) : null
|
|
687
|
+
]
|
|
688
|
+
}
|
|
689
|
+
);
|
|
690
|
+
}
|
|
691
|
+
async function wipeIfUnchanged(expected) {
|
|
692
|
+
try {
|
|
693
|
+
if (await navigator.clipboard.readText() !== expected) return;
|
|
694
|
+
} catch {
|
|
695
|
+
}
|
|
696
|
+
try {
|
|
697
|
+
await navigator.clipboard.writeText("");
|
|
698
|
+
} catch {
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
function useCopy(timeoutMs = 1600) {
|
|
702
|
+
const [copied, setCopied] = useState(false);
|
|
703
|
+
const t = useRef(null);
|
|
704
|
+
const wipe = useRef(null);
|
|
705
|
+
useEffect(
|
|
706
|
+
() => () => {
|
|
707
|
+
if (t.current) clearTimeout(t.current);
|
|
708
|
+
},
|
|
709
|
+
[]
|
|
710
|
+
);
|
|
711
|
+
const copy = useCallback(
|
|
712
|
+
async (text, opts = {}) => {
|
|
713
|
+
try {
|
|
714
|
+
await navigator.clipboard.writeText(text);
|
|
715
|
+
setCopied(true);
|
|
716
|
+
if (t.current) clearTimeout(t.current);
|
|
717
|
+
t.current = setTimeout(() => setCopied(false), timeoutMs);
|
|
718
|
+
if (opts.clearAfter && opts.clearAfter > 0) {
|
|
719
|
+
if (wipe.current) clearTimeout(wipe.current);
|
|
720
|
+
wipe.current = setTimeout(() => void wipeIfUnchanged(text), opts.clearAfter);
|
|
721
|
+
}
|
|
722
|
+
return true;
|
|
723
|
+
} catch {
|
|
724
|
+
setCopied(false);
|
|
725
|
+
return false;
|
|
726
|
+
}
|
|
727
|
+
},
|
|
728
|
+
[timeoutMs]
|
|
729
|
+
);
|
|
730
|
+
return { copied, copy };
|
|
731
|
+
}
|
|
732
|
+
function CopyButton({ value, label = "Copy", clearAfter, onCopied, className }) {
|
|
733
|
+
const { copied, copy } = useCopy();
|
|
734
|
+
const done = copied ? clearAfter ? `Copied. Cleared in ${Math.round(clearAfter / 1e3)} seconds` : "Copied" : "";
|
|
735
|
+
return /* @__PURE__ */ jsxs(
|
|
736
|
+
"button",
|
|
737
|
+
{
|
|
738
|
+
type: "button",
|
|
739
|
+
onClick: async () => {
|
|
740
|
+
if (await copy(typeof value === "function" ? value() : value, { clearAfter })) onCopied?.();
|
|
741
|
+
},
|
|
742
|
+
"aria-label": copied ? "Copied" : label,
|
|
743
|
+
title: label,
|
|
744
|
+
className: cn(
|
|
745
|
+
"inline-flex size-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
|
|
746
|
+
className
|
|
747
|
+
),
|
|
748
|
+
children: [
|
|
749
|
+
copied ? /* @__PURE__ */ jsx(Check, { className: "size-4 text-success" }) : /* @__PURE__ */ jsx(Copy, { className: "size-4" }),
|
|
750
|
+
/* @__PURE__ */ jsx("span", { "aria-live": "polite", className: "sr-only", children: done })
|
|
751
|
+
]
|
|
752
|
+
}
|
|
753
|
+
);
|
|
754
|
+
}
|
|
755
|
+
var LANG_NAME = {
|
|
756
|
+
ts: "TypeScript",
|
|
757
|
+
typescript: "TypeScript",
|
|
758
|
+
tsx: "TSX",
|
|
759
|
+
js: "JavaScript",
|
|
760
|
+
javascript: "JavaScript",
|
|
761
|
+
jsx: "JSX",
|
|
762
|
+
mjs: "JavaScript",
|
|
763
|
+
json: "JSON",
|
|
764
|
+
jsonc: "JSON",
|
|
765
|
+
bash: "Shell",
|
|
766
|
+
sh: "Shell",
|
|
767
|
+
shell: "Shell",
|
|
768
|
+
zsh: "Shell",
|
|
769
|
+
console: "Terminal",
|
|
770
|
+
terminal: "Terminal",
|
|
771
|
+
python: "Python",
|
|
772
|
+
py: "Python",
|
|
773
|
+
yaml: "YAML",
|
|
774
|
+
yml: "YAML",
|
|
775
|
+
diff: "Diff",
|
|
776
|
+
text: "Text"
|
|
777
|
+
};
|
|
778
|
+
function languageName(lang) {
|
|
779
|
+
return lang ? LANG_NAME[lang.toLowerCase()] ?? lang : void 0;
|
|
780
|
+
}
|
|
781
|
+
function forClipboard(text, lang) {
|
|
782
|
+
if (grammarOf(lang) !== "shell") return text;
|
|
783
|
+
const lines = text.split("\n");
|
|
784
|
+
if (!lines.some((l) => l.startsWith("$ "))) return text;
|
|
785
|
+
return lines.filter((l) => l.startsWith("$ ")).map((l) => l.slice(2)).join("\n");
|
|
786
|
+
}
|
|
787
|
+
function linesFromDom(pre) {
|
|
788
|
+
if (!pre) return null;
|
|
789
|
+
const lines = pre.querySelectorAll("[data-line]");
|
|
790
|
+
if (lines.length === 0) return pre.textContent ?? "";
|
|
791
|
+
return Array.from(lines).filter((l) => l.getAttribute("data-diff") !== "remove").map((l) => l.textContent ?? "").join("\n");
|
|
792
|
+
}
|
|
793
|
+
function prepare(code, lang, marks, diff) {
|
|
794
|
+
const d = diff ? readDiff(code) : null;
|
|
795
|
+
const src = d ? d.code : code.replace(/\r?\n$/, "");
|
|
796
|
+
const lines = highlight(src, lang === "diff" ? void 0 : lang);
|
|
797
|
+
const kept = d ? src.split("\n").filter((_, i) => d.diff.get(i + 1) !== "remove") : null;
|
|
798
|
+
return {
|
|
799
|
+
html: linesToHtml(lines, { highlight: parseLineRanges(marks), diff: d?.diff }),
|
|
800
|
+
copy: kept ? kept.join("\n") : src,
|
|
801
|
+
lines: lines.length,
|
|
802
|
+
diff: !!d
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
function Well({
|
|
806
|
+
preRef,
|
|
807
|
+
html,
|
|
808
|
+
children,
|
|
809
|
+
lang,
|
|
810
|
+
lines,
|
|
811
|
+
maxLines,
|
|
812
|
+
diff,
|
|
813
|
+
lineNumbers
|
|
814
|
+
}) {
|
|
815
|
+
const foldable = maxLines !== void 0 && lines > maxLines + 2;
|
|
816
|
+
const [open, setOpen] = useState(false);
|
|
817
|
+
const folded = foldable && !open;
|
|
818
|
+
const lined = html !== void 0;
|
|
819
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
820
|
+
/* @__PURE__ */ jsx(
|
|
821
|
+
"div",
|
|
822
|
+
{
|
|
823
|
+
className: cn(folded && "overflow-hidden"),
|
|
824
|
+
style: folded ? { maxHeight: `calc(${maxLines} * 1.625em + 2rem)` } : void 0,
|
|
825
|
+
children: /* @__PURE__ */ jsx(ScrollFade, { fade: "var(--oca-code-surface)", children: /* @__PURE__ */ jsx(
|
|
826
|
+
"pre",
|
|
827
|
+
{
|
|
828
|
+
ref: preRef,
|
|
829
|
+
"data-diff": diff ? "" : void 0,
|
|
830
|
+
"data-line-numbers": lineNumbers ? "" : void 0,
|
|
831
|
+
className: cn(
|
|
832
|
+
"oca-code w-max min-w-full py-4 font-mono text-[0.875rem] leading-[1.625] text-oca-ink-muted [font-variant-ligatures:none]",
|
|
833
|
+
!lined && "px-5"
|
|
834
|
+
),
|
|
835
|
+
children: lined ? /* @__PURE__ */ jsx("code", { className: "block", "data-lang": lang, dangerouslySetInnerHTML: { __html: html } }) : /* @__PURE__ */ jsx("code", { className: "block", "data-lang": lang, children })
|
|
836
|
+
}
|
|
837
|
+
) })
|
|
838
|
+
}
|
|
839
|
+
),
|
|
840
|
+
foldable ? /* @__PURE__ */ jsx(
|
|
841
|
+
"div",
|
|
842
|
+
{
|
|
843
|
+
className: cn("flex justify-center px-5 pb-4", folded && "absolute inset-x-0 bottom-0 pt-16"),
|
|
844
|
+
style: folded ? { background: "linear-gradient(to top, var(--oca-code-surface) 40%, transparent)" } : void 0,
|
|
845
|
+
children: /* @__PURE__ */ jsx(
|
|
846
|
+
"button",
|
|
847
|
+
{
|
|
848
|
+
type: "button",
|
|
849
|
+
onClick: () => setOpen((v) => !v),
|
|
850
|
+
"aria-expanded": open,
|
|
851
|
+
className: "rounded-full border border-white/20 px-4 py-1.5 text-[0.8125rem] text-white transition-colors hover:bg-white/10",
|
|
852
|
+
children: open ? "Show less" : `Show all ${lines} lines`
|
|
853
|
+
}
|
|
854
|
+
)
|
|
855
|
+
}
|
|
856
|
+
) : null
|
|
857
|
+
] });
|
|
858
|
+
}
|
|
859
|
+
var FRAME = "overflow-hidden rounded-[1.25rem] border border-[var(--oca-code-line)] bg-[var(--oca-code-surface)]";
|
|
860
|
+
var COPY_ON_INK = "text-oca-ink-subtle hover:bg-white/10 hover:text-white";
|
|
861
|
+
function CodeBlock({
|
|
862
|
+
code,
|
|
863
|
+
html,
|
|
864
|
+
children,
|
|
865
|
+
lang,
|
|
866
|
+
caption,
|
|
867
|
+
copy = true,
|
|
868
|
+
clearAfter,
|
|
869
|
+
maxLines,
|
|
870
|
+
highlight: marks,
|
|
871
|
+
diff,
|
|
872
|
+
lineNumbers,
|
|
873
|
+
actions,
|
|
874
|
+
className
|
|
875
|
+
}) {
|
|
876
|
+
const preRef = useRef(null);
|
|
877
|
+
const isDiff = diff || lang === "diff";
|
|
878
|
+
const markKey = typeof marks === "string" ? marks : marks?.join(",");
|
|
879
|
+
const prepared = useMemo(
|
|
880
|
+
() => html === void 0 && children === void 0 && code !== void 0 ? prepare(code, lang, markKey, !!isDiff) : null,
|
|
881
|
+
[code, html, children, lang, markKey, isDiff]
|
|
882
|
+
);
|
|
883
|
+
const markup = prepared?.html ?? html;
|
|
884
|
+
const lines = prepared?.lines ?? (html !== void 0 ? html.split("\n").length : code?.split("\n").length ?? 0);
|
|
885
|
+
const read = () => forClipboard(prepared?.copy ?? linesFromDom(preRef.current) ?? code ?? "", lang);
|
|
886
|
+
return /* @__PURE__ */ jsxs("figure", { className: cn(FRAME, className), children: [
|
|
887
|
+
/* @__PURE__ */ jsxs("figcaption", { className: "flex h-11 items-center justify-between gap-3 border-b border-[var(--oca-code-line)] pl-5 pr-2", children: [
|
|
888
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-[0.8125rem] text-oca-ink-subtle", children: caption ?? languageName(lang) ?? "Code" }),
|
|
889
|
+
/* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [
|
|
890
|
+
actions,
|
|
891
|
+
copy ? /* @__PURE__ */ jsx(CopyButton, { value: read, label: "Copy code", clearAfter, className: COPY_ON_INK }) : null
|
|
892
|
+
] })
|
|
893
|
+
] }),
|
|
894
|
+
/* @__PURE__ */ jsx(
|
|
895
|
+
Well,
|
|
896
|
+
{
|
|
897
|
+
preRef,
|
|
898
|
+
html: markup,
|
|
899
|
+
lang,
|
|
900
|
+
lines,
|
|
901
|
+
maxLines,
|
|
902
|
+
diff: prepared ? prepared.diff : isDiff,
|
|
903
|
+
lineNumbers,
|
|
904
|
+
children
|
|
905
|
+
}
|
|
906
|
+
)
|
|
907
|
+
] });
|
|
908
|
+
}
|
|
909
|
+
var tabListeners = /* @__PURE__ */ new Map();
|
|
910
|
+
var tabMemory = /* @__PURE__ */ new Map();
|
|
911
|
+
var storeKey = (k) => `oca-code-tab:${k}`;
|
|
912
|
+
function readTab(key) {
|
|
913
|
+
if (tabMemory.has(key)) return tabMemory.get(key);
|
|
914
|
+
try {
|
|
915
|
+
return window.localStorage.getItem(storeKey(key));
|
|
916
|
+
} catch {
|
|
917
|
+
return null;
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
function writeTab(key, value) {
|
|
921
|
+
tabMemory.set(key, value);
|
|
922
|
+
try {
|
|
923
|
+
window.localStorage.setItem(storeKey(key), value);
|
|
924
|
+
} catch {
|
|
925
|
+
}
|
|
926
|
+
tabListeners.get(key)?.forEach((l) => l());
|
|
927
|
+
}
|
|
928
|
+
function useSyncedTab(key) {
|
|
929
|
+
const subscribe = useCallback(
|
|
930
|
+
(cb) => {
|
|
931
|
+
if (!key) return () => {
|
|
932
|
+
};
|
|
933
|
+
const set = tabListeners.get(key) ?? /* @__PURE__ */ new Set();
|
|
934
|
+
set.add(cb);
|
|
935
|
+
tabListeners.set(key, set);
|
|
936
|
+
return () => {
|
|
937
|
+
set.delete(cb);
|
|
938
|
+
};
|
|
939
|
+
},
|
|
940
|
+
[key]
|
|
941
|
+
);
|
|
942
|
+
const value = useSyncExternalStore(
|
|
943
|
+
subscribe,
|
|
944
|
+
() => key ? readTab(key) : null,
|
|
945
|
+
() => null
|
|
946
|
+
);
|
|
947
|
+
return [value, (v) => key && writeTab(key, v)];
|
|
948
|
+
}
|
|
949
|
+
function CodeTabs({
|
|
950
|
+
items,
|
|
951
|
+
syncKey,
|
|
952
|
+
defaultValue,
|
|
953
|
+
maxLines,
|
|
954
|
+
className
|
|
955
|
+
}) {
|
|
956
|
+
const [synced, setSynced] = useSyncedTab(syncKey);
|
|
957
|
+
const [local, setLocal] = useState(null);
|
|
958
|
+
const labels = items.map((it) => it.label);
|
|
959
|
+
const pick = [local, synced, defaultValue].find((v) => !!v && labels.includes(v)) ?? labels[0] ?? "";
|
|
960
|
+
const active = items.find((it) => it.label === pick);
|
|
961
|
+
const prepared = useMemo(() => items.map((it) => prepare(it.code, it.lang, void 0, it.lang === "diff")), [items]);
|
|
962
|
+
return /* @__PURE__ */ jsxs(
|
|
963
|
+
TabsPrimitive.Root,
|
|
964
|
+
{
|
|
965
|
+
value: pick,
|
|
966
|
+
onValueChange: (v) => {
|
|
967
|
+
setLocal(v);
|
|
968
|
+
setSynced(v);
|
|
969
|
+
},
|
|
970
|
+
className: cn(FRAME, className),
|
|
971
|
+
children: [
|
|
972
|
+
/* @__PURE__ */ jsxs("div", { className: "flex h-11 items-center justify-between gap-3 border-b border-[var(--oca-code-line)] pl-2 pr-2", children: [
|
|
973
|
+
/* @__PURE__ */ jsx(ScrollFade, { fade: "var(--oca-code-surface)", className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx(TabsPrimitive.List, { "aria-label": "Versions", className: "flex w-max items-center gap-0.5", children: items.map((it) => /* @__PURE__ */ jsx(
|
|
974
|
+
TabsPrimitive.Trigger,
|
|
975
|
+
{
|
|
976
|
+
value: it.label,
|
|
977
|
+
className: cn(
|
|
978
|
+
"relative inline-flex h-11 items-center whitespace-nowrap px-3 text-[0.8125rem] text-oca-ink-subtle outline-none transition-colors",
|
|
979
|
+
"hover:text-white focus-visible:text-white focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
|
|
980
|
+
"data-[state=active]:text-white",
|
|
981
|
+
"after:absolute after:inset-x-3 after:bottom-0 after:h-0.5 after:rounded-full after:bg-transparent data-[state=active]:after:bg-oca-orange"
|
|
982
|
+
),
|
|
983
|
+
children: it.label
|
|
984
|
+
},
|
|
985
|
+
it.label
|
|
986
|
+
)) }) }),
|
|
987
|
+
active ? /* @__PURE__ */ jsx(
|
|
988
|
+
CopyButton,
|
|
989
|
+
{
|
|
990
|
+
value: () => forClipboard(prepared[items.indexOf(active)]?.copy ?? active.code, active.lang),
|
|
991
|
+
label: `Copy ${active.label}`,
|
|
992
|
+
className: COPY_ON_INK
|
|
993
|
+
}
|
|
994
|
+
) : null
|
|
995
|
+
] }),
|
|
996
|
+
items.map((it, i) => /* @__PURE__ */ jsx(TabsPrimitive.Content, { value: it.label, className: "outline-none", tabIndex: -1, children: /* @__PURE__ */ jsx(
|
|
997
|
+
Well,
|
|
998
|
+
{
|
|
999
|
+
html: prepared[i].html,
|
|
1000
|
+
lang: it.lang,
|
|
1001
|
+
lines: prepared[i].lines,
|
|
1002
|
+
maxLines,
|
|
1003
|
+
diff: prepared[i].diff
|
|
1004
|
+
}
|
|
1005
|
+
) }, it.label))
|
|
1006
|
+
]
|
|
1007
|
+
}
|
|
1008
|
+
);
|
|
1009
|
+
}
|
|
1010
|
+
function InstallTabs({ pkg, dev = false, className }) {
|
|
1011
|
+
const items = [
|
|
1012
|
+
{ label: "npm", code: `npm install ${dev ? "--save-dev " : ""}${pkg}`, lang: "bash" },
|
|
1013
|
+
{ label: "yarn", code: `yarn add ${dev ? "--dev " : ""}${pkg}`, lang: "bash" },
|
|
1014
|
+
{ label: "pnpm", code: `pnpm add ${dev ? "--save-dev " : ""}${pkg}`, lang: "bash" }
|
|
1015
|
+
];
|
|
1016
|
+
return /* @__PURE__ */ jsx(CodeTabs, { items, syncKey: "package-manager", className });
|
|
1017
|
+
}
|
|
1018
|
+
var GOOD_DOT = "border-border bg-card text-foreground before:size-1.5 before:shrink-0 before:rounded-full before:bg-success before:content-['']";
|
|
1019
|
+
var badgeVariants = cva(
|
|
1020
|
+
"inline-flex h-6 shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full border px-2.5 text-[0.8125rem] font-medium leading-none",
|
|
1021
|
+
{
|
|
1022
|
+
variants: {
|
|
1023
|
+
tone: {
|
|
1024
|
+
neutral: "border-border bg-card text-foreground",
|
|
1025
|
+
muted: "border-transparent bg-muted text-muted-foreground",
|
|
1026
|
+
brand: "border-transparent bg-[color-mix(in_oklab,var(--oca-orange)_9%,var(--card))] text-oca-accent-ink",
|
|
1027
|
+
danger: "border-transparent bg-[color-mix(in_oklab,var(--destructive)_12%,var(--card))] text-destructive",
|
|
1028
|
+
// A good state is a neutral pill with a green dot, not a green pill.
|
|
1029
|
+
success: GOOD_DOT,
|
|
1030
|
+
// Aliases kept so older call sites keep compiling: attention is
|
|
1031
|
+
// the brand accent, information is neutral.
|
|
1032
|
+
warning: "border-transparent bg-[color-mix(in_oklab,var(--oca-orange)_9%,var(--card))] text-oca-accent-ink",
|
|
1033
|
+
info: "border-border bg-card text-foreground",
|
|
1034
|
+
// Inverted in dark mode, where ink would sit on a card of nearly its own colour.
|
|
1035
|
+
ink: "border-transparent bg-oca-ink text-oca-ink-foreground dark:bg-foreground dark:text-background",
|
|
1036
|
+
onInk: "border-white/15 bg-white/5 text-white/90"
|
|
1037
|
+
}
|
|
1038
|
+
},
|
|
1039
|
+
defaultVariants: { tone: "neutral" }
|
|
1040
|
+
}
|
|
1041
|
+
);
|
|
1042
|
+
function Badge({ className, tone, ...props }) {
|
|
1043
|
+
return /* @__PURE__ */ jsx("span", { "data-ui": "badge", className: cn(badgeVariants({ tone }), className), ...props });
|
|
1044
|
+
}
|
|
1045
|
+
var WORD = {
|
|
1046
|
+
live: "Live",
|
|
1047
|
+
testing: "In testing",
|
|
1048
|
+
"not-yet": "Not yet",
|
|
1049
|
+
paused: "Paused",
|
|
1050
|
+
good: "Good",
|
|
1051
|
+
caution: "Caution",
|
|
1052
|
+
refused: "Refused"
|
|
1053
|
+
};
|
|
1054
|
+
var TONE = {
|
|
1055
|
+
live: "success",
|
|
1056
|
+
testing: "brand",
|
|
1057
|
+
"not-yet": "muted",
|
|
1058
|
+
paused: "muted",
|
|
1059
|
+
good: "success",
|
|
1060
|
+
caution: "brand",
|
|
1061
|
+
refused: "danger"
|
|
1062
|
+
};
|
|
1063
|
+
function StatusBadge({ status, className, ...props }) {
|
|
1064
|
+
return /* @__PURE__ */ jsx(Badge, { tone: TONE[status], "data-status": status, className: cn(className), ...props, children: WORD[status] });
|
|
1065
|
+
}
|
|
1066
|
+
var isInternal = (href) => href.startsWith("/") || href.startsWith("#");
|
|
1067
|
+
function DocLink({ href, className, children, ...rest }) {
|
|
1068
|
+
return isInternal(href) ? /* @__PURE__ */ jsx(Link, { href, className, ...rest, children }) : /* @__PURE__ */ jsx("a", { href, className, ...rest, children });
|
|
1069
|
+
}
|
|
1070
|
+
var CALLOUT_TONE = { note: "neutral", warning: "brand", danger: "danger" };
|
|
1071
|
+
function Callout({
|
|
1072
|
+
tone = "note",
|
|
1073
|
+
title,
|
|
1074
|
+
children,
|
|
1075
|
+
className
|
|
1076
|
+
}) {
|
|
1077
|
+
return /* @__PURE__ */ jsx(
|
|
1078
|
+
Notice,
|
|
1079
|
+
{
|
|
1080
|
+
tone: CALLOUT_TONE[tone],
|
|
1081
|
+
title,
|
|
1082
|
+
role: "note",
|
|
1083
|
+
className: cn("my-6 [&_p]:my-0 [&_p]:text-[0.9375rem] [&_p]:leading-relaxed [&_p+p]:mt-3", className),
|
|
1084
|
+
children
|
|
1085
|
+
}
|
|
1086
|
+
);
|
|
1087
|
+
}
|
|
1088
|
+
function Step({ title, id, children }) {
|
|
1089
|
+
return /* @__PURE__ */ jsxs("li", { className: "relative pb-8 pl-11 last:pb-0 [counter-increment:oca-step]", children: [
|
|
1090
|
+
/* @__PURE__ */ jsx(
|
|
1091
|
+
"span",
|
|
1092
|
+
{
|
|
1093
|
+
"aria-hidden": true,
|
|
1094
|
+
className: "absolute left-0 top-0 flex size-7 items-center justify-center rounded-full border border-oca-hairline-strong bg-card text-[0.8125rem] oca-tabular text-foreground before:content-[counter(oca-step)]"
|
|
1095
|
+
}
|
|
1096
|
+
),
|
|
1097
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "absolute bottom-1 left-[0.8125rem] top-9 w-px bg-border" }),
|
|
1098
|
+
/* @__PURE__ */ jsx("h3", { id, className: "scroll-mt-28 pt-0.5 text-[1.0625rem] font-medium leading-snug tracking-[-0.008em] text-foreground", children: title }),
|
|
1099
|
+
/* @__PURE__ */ jsx("div", { className: "mt-2 text-muted-foreground [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", children })
|
|
1100
|
+
] });
|
|
1101
|
+
}
|
|
1102
|
+
function Steps({ children, className }) {
|
|
1103
|
+
return /* @__PURE__ */ jsx("ol", { className: cn("not-prose my-8 flex flex-col [counter-reset:oca-step] [&>li:last-child>span:nth-child(2)]:hidden", className), children });
|
|
1104
|
+
}
|
|
1105
|
+
function LinkCard({
|
|
1106
|
+
href,
|
|
1107
|
+
title,
|
|
1108
|
+
description,
|
|
1109
|
+
icon,
|
|
1110
|
+
meta,
|
|
1111
|
+
className
|
|
1112
|
+
}) {
|
|
1113
|
+
const Arrow = isInternal(href) ? ArrowRight : ArrowUpRight;
|
|
1114
|
+
return /* @__PURE__ */ jsxs(
|
|
1115
|
+
DocLink,
|
|
1116
|
+
{
|
|
1117
|
+
href,
|
|
1118
|
+
className: cn(
|
|
1119
|
+
"group flex h-full flex-col gap-3 rounded-[1.25rem] border border-border bg-card p-5 transition-colors hover:border-oca-hairline-strong",
|
|
1120
|
+
className
|
|
1121
|
+
),
|
|
1122
|
+
children: [
|
|
1123
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-start justify-between gap-3", children: [
|
|
1124
|
+
icon ? /* @__PURE__ */ jsx("span", { className: "flex size-9 shrink-0 items-center justify-center rounded-xl bg-muted text-foreground [&_svg]:size-[1.125rem]", children: icon }) : /* @__PURE__ */ jsx("span", { className: "text-[1rem] font-medium leading-snug text-foreground", children: title }),
|
|
1125
|
+
/* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-2", children: [
|
|
1126
|
+
meta,
|
|
1127
|
+
/* @__PURE__ */ jsx(Arrow, { "aria-hidden": true, className: "size-4 text-muted-foreground transition-transform group-hover:translate-x-0.5 group-hover:text-foreground" })
|
|
1128
|
+
] })
|
|
1129
|
+
] }),
|
|
1130
|
+
icon ? /* @__PURE__ */ jsx("span", { className: "text-[1rem] font-medium leading-snug text-foreground", children: title }) : null,
|
|
1131
|
+
description ? /* @__PURE__ */ jsx("span", { className: "text-[0.9375rem] leading-relaxed text-muted-foreground", children: description }) : null
|
|
1132
|
+
]
|
|
1133
|
+
}
|
|
1134
|
+
);
|
|
1135
|
+
}
|
|
1136
|
+
function CardGrid({ columns = 2, children, className }) {
|
|
1137
|
+
return /* @__PURE__ */ jsx("div", { className: cn("not-prose my-6 grid grid-cols-1 gap-3 sm:grid-cols-2", columns === 3 && "lg:grid-cols-3", className), children });
|
|
1138
|
+
}
|
|
1139
|
+
function MdxTable({ className, ...props }) {
|
|
1140
|
+
return /* @__PURE__ */ jsx("div", { className: "not-prose my-6 overflow-hidden rounded-2xl border border-border bg-card", children: /* @__PURE__ */ jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsx(
|
|
1141
|
+
"table",
|
|
1142
|
+
{
|
|
1143
|
+
className: cn(
|
|
1144
|
+
"w-full border-collapse text-left text-[0.875rem] leading-relaxed",
|
|
1145
|
+
"[&_th]:whitespace-nowrap [&_th]:border-b [&_th]:border-oca-hairline-strong [&_th]:bg-oca-table-head [&_th]:px-4 [&_th]:py-2.5 [&_th]:text-[0.8125rem] [&_th]:font-medium [&_th]:text-foreground",
|
|
1146
|
+
"[&_td]:border-t [&_td]:border-border [&_td]:px-4 [&_td]:py-2.5 [&_td]:align-top [&_td]:text-muted-foreground [&_tbody_tr:first-child_td]:border-t-0",
|
|
1147
|
+
"[&_td_code]:bg-transparent [&_td_code]:p-0 [&_td_code]:text-foreground [&_td:first-child]:text-foreground",
|
|
1148
|
+
"[&_[align=center]]:text-center [&_[align=right]]:text-right",
|
|
1149
|
+
// On a phone a cell keeps a readable width; the table scrolls instead of crushing it.
|
|
1150
|
+
"max-sm:[&_td]:min-w-[9rem]",
|
|
1151
|
+
className
|
|
1152
|
+
),
|
|
1153
|
+
...props
|
|
1154
|
+
}
|
|
1155
|
+
) }) });
|
|
1156
|
+
}
|
|
1157
|
+
function ApiTable({
|
|
1158
|
+
rows,
|
|
1159
|
+
caption,
|
|
1160
|
+
nameHeader = "Name",
|
|
1161
|
+
className
|
|
1162
|
+
}) {
|
|
1163
|
+
const hasDefault = rows.some((r) => r.default !== void 0);
|
|
1164
|
+
const marks = (r) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1165
|
+
r.required ? /* @__PURE__ */ jsx("span", { className: "text-[0.75rem] text-oca-accent-ink", children: "Required" }) : null,
|
|
1166
|
+
r.deprecated ? /* @__PURE__ */ jsx(Badge, { tone: "muted", children: "Deprecated" }) : null,
|
|
1167
|
+
r.status ? /* @__PURE__ */ jsx(StatusBadge, { status: r.status }) : null
|
|
1168
|
+
] });
|
|
1169
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("not-prose my-6", className), children: [
|
|
1170
|
+
/* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-2xl border border-border bg-card max-sm:hidden", children: /* @__PURE__ */ jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse text-left text-[0.875rem]", children: [
|
|
1171
|
+
caption ? /* @__PURE__ */ jsx("caption", { className: "sr-only", children: caption }) : null,
|
|
1172
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b border-oca-hairline-strong bg-oca-table-head text-[0.8125rem]", children: [
|
|
1173
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: nameHeader }),
|
|
1174
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: "Type" }),
|
|
1175
|
+
hasDefault ? /* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: "Default" }) : null,
|
|
1176
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: "Description" })
|
|
1177
|
+
] }) }),
|
|
1178
|
+
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-border", children: rows.map((r) => /* @__PURE__ */ jsxs("tr", { className: "align-top", children: [
|
|
1179
|
+
/* @__PURE__ */ jsx("th", { scope: "row", className: "px-4 py-3 text-left font-normal", children: /* @__PURE__ */ jsxs("span", { className: "flex flex-col items-start gap-1", children: [
|
|
1180
|
+
/* @__PURE__ */ jsx("code", { className: cn("font-mono text-[0.8125rem] text-foreground", r.deprecated && "line-through decoration-oca-subtle"), children: r.name }),
|
|
1181
|
+
marks(r)
|
|
1182
|
+
] }) }),
|
|
1183
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-3 font-mono text-[0.8125rem] text-muted-foreground", children: r.type ?? "\u2014" }),
|
|
1184
|
+
hasDefault ? /* @__PURE__ */ jsx("td", { className: "px-4 py-3 font-mono text-[0.8125rem] text-muted-foreground", children: r.default ?? "\u2014" }) : null,
|
|
1185
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-3 leading-relaxed text-muted-foreground", children: r.description })
|
|
1186
|
+
] }, r.name)) })
|
|
1187
|
+
] }) }) }),
|
|
1188
|
+
/* @__PURE__ */ jsx("ul", { "aria-label": caption, className: "divide-y divide-border rounded-2xl border border-border bg-card sm:hidden", children: rows.map((r) => /* @__PURE__ */ jsxs("li", { className: "flex flex-col gap-1.5 px-4 py-3.5", children: [
|
|
1189
|
+
/* @__PURE__ */ jsxs("span", { className: "flex flex-wrap items-baseline gap-x-2 gap-y-1", children: [
|
|
1190
|
+
/* @__PURE__ */ jsx("code", { className: cn("font-mono text-[0.875rem] text-foreground", r.deprecated && "line-through decoration-oca-subtle"), children: r.name }),
|
|
1191
|
+
r.type ? /* @__PURE__ */ jsx("code", { className: "break-all font-mono text-[0.8125rem] text-muted-foreground", children: r.type }) : null
|
|
1192
|
+
] }),
|
|
1193
|
+
/* @__PURE__ */ jsx("span", { className: "flex flex-wrap items-center gap-2 empty:hidden", children: marks(r) }),
|
|
1194
|
+
r.description ? /* @__PURE__ */ jsx("span", { className: "text-[0.875rem] leading-relaxed text-muted-foreground", children: r.description }) : null,
|
|
1195
|
+
r.default !== void 0 ? /* @__PURE__ */ jsxs("span", { className: "text-[0.8125rem] text-muted-foreground", children: [
|
|
1196
|
+
"Default ",
|
|
1197
|
+
/* @__PURE__ */ jsx("code", { className: "font-mono text-foreground", children: r.default })
|
|
1198
|
+
] }) : null
|
|
1199
|
+
] }, r.name)) })
|
|
1200
|
+
] });
|
|
1201
|
+
}
|
|
1202
|
+
function useDarkMode() {
|
|
1203
|
+
const [dark, setDark] = useState(false);
|
|
1204
|
+
useEffect(() => {
|
|
1205
|
+
const root = document.documentElement;
|
|
1206
|
+
const read = () => setDark(root.classList.contains("dark"));
|
|
1207
|
+
read();
|
|
1208
|
+
const mo = new MutationObserver(read);
|
|
1209
|
+
mo.observe(root, { attributes: true, attributeFilter: ["class"] });
|
|
1210
|
+
return () => mo.disconnect();
|
|
1211
|
+
}, []);
|
|
1212
|
+
return dark;
|
|
1213
|
+
}
|
|
1214
|
+
function mermaidTheme(el) {
|
|
1215
|
+
const css = getComputedStyle(el);
|
|
1216
|
+
const v = (name) => css.getPropertyValue(name).trim();
|
|
1217
|
+
const card = v("--card");
|
|
1218
|
+
const muted = v("--muted");
|
|
1219
|
+
const text = v("--foreground");
|
|
1220
|
+
const subtle = v("--muted-foreground");
|
|
1221
|
+
const line = v("--input");
|
|
1222
|
+
const hair = v("--oca-hairline-strong");
|
|
1223
|
+
return {
|
|
1224
|
+
background: "transparent",
|
|
1225
|
+
fontFamily: css.fontFamily,
|
|
1226
|
+
fontSize: "14px",
|
|
1227
|
+
textColor: text,
|
|
1228
|
+
mainBkg: card,
|
|
1229
|
+
primaryColor: card,
|
|
1230
|
+
primaryTextColor: text,
|
|
1231
|
+
primaryBorderColor: hair,
|
|
1232
|
+
secondaryColor: muted,
|
|
1233
|
+
secondaryTextColor: text,
|
|
1234
|
+
secondaryBorderColor: hair,
|
|
1235
|
+
tertiaryColor: muted,
|
|
1236
|
+
tertiaryTextColor: text,
|
|
1237
|
+
tertiaryBorderColor: hair,
|
|
1238
|
+
nodeBorder: hair,
|
|
1239
|
+
lineColor: line,
|
|
1240
|
+
edgeLabelBackground: card,
|
|
1241
|
+
clusterBkg: muted,
|
|
1242
|
+
clusterBorder: hair,
|
|
1243
|
+
titleColor: text,
|
|
1244
|
+
noteBkgColor: muted,
|
|
1245
|
+
noteTextColor: text,
|
|
1246
|
+
noteBorderColor: hair,
|
|
1247
|
+
actorBkg: card,
|
|
1248
|
+
actorBorder: hair,
|
|
1249
|
+
actorTextColor: text,
|
|
1250
|
+
actorLineColor: line,
|
|
1251
|
+
signalColor: text,
|
|
1252
|
+
signalTextColor: text,
|
|
1253
|
+
labelBoxBkgColor: card,
|
|
1254
|
+
labelBoxBorderColor: hair,
|
|
1255
|
+
labelTextColor: text,
|
|
1256
|
+
loopTextColor: subtle,
|
|
1257
|
+
activationBkgColor: muted,
|
|
1258
|
+
activationBorderColor: hair,
|
|
1259
|
+
sequenceNumberColor: card
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1262
|
+
function naturalSize(svg) {
|
|
1263
|
+
const w = svg.match(/viewBox="[\d.-]+ [\d.-]+ ([\d.]+) [\d.]+"/)?.[1];
|
|
1264
|
+
if (!w) return svg;
|
|
1265
|
+
return svg.replace(/<svg([^>]*?)\swidth="100%"/, `<svg$1 width="${Math.ceil(Number(w))}"`).replace(/max-width:\s*[\d.]+px;?/, "");
|
|
1266
|
+
}
|
|
1267
|
+
function Diagram({ chart, caption, load, className }) {
|
|
1268
|
+
const ref = useRef(null);
|
|
1269
|
+
const dark = useDarkMode();
|
|
1270
|
+
const raw = useId();
|
|
1271
|
+
const [svg, setSvg] = useState(null);
|
|
1272
|
+
const [failed, setFailed] = useState(false);
|
|
1273
|
+
useEffect(() => {
|
|
1274
|
+
let live = true;
|
|
1275
|
+
const el = ref.current;
|
|
1276
|
+
if (!el) return;
|
|
1277
|
+
(async () => {
|
|
1278
|
+
try {
|
|
1279
|
+
const mod = await load();
|
|
1280
|
+
const mermaid = "default" in mod ? mod.default : mod;
|
|
1281
|
+
mermaid.initialize({ startOnLoad: false, securityLevel: "strict", theme: "base", themeVariables: mermaidTheme(el) });
|
|
1282
|
+
const { svg: drawn } = await mermaid.render(`oca-diagram-${raw.replace(/[^a-zA-Z0-9]/g, "")}-${dark ? "d" : "l"}`, chart);
|
|
1283
|
+
if (live) {
|
|
1284
|
+
setSvg(naturalSize(drawn));
|
|
1285
|
+
setFailed(false);
|
|
1286
|
+
}
|
|
1287
|
+
} catch {
|
|
1288
|
+
if (live) setFailed(true);
|
|
1289
|
+
}
|
|
1290
|
+
})();
|
|
1291
|
+
return () => {
|
|
1292
|
+
live = false;
|
|
1293
|
+
};
|
|
1294
|
+
}, [chart, dark, load, raw]);
|
|
1295
|
+
if (failed) return /* @__PURE__ */ jsx(CodeBlock, { code: chart, caption: "Diagram (shown as its source)", className: cn("my-6", className) });
|
|
1296
|
+
return /* @__PURE__ */ jsxs("figure", { ref, className: cn("not-prose my-6 overflow-hidden rounded-[1.25rem] border border-border bg-card", className), children: [
|
|
1297
|
+
svg ? /* @__PURE__ */ jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsx(
|
|
1298
|
+
"div",
|
|
1299
|
+
{
|
|
1300
|
+
className: "flex w-max min-w-full justify-center p-6 [&_svg]:h-auto [&_svg]:max-w-none",
|
|
1301
|
+
role: "img",
|
|
1302
|
+
"aria-label": typeof caption === "string" ? caption : "Diagram",
|
|
1303
|
+
dangerouslySetInnerHTML: { __html: svg }
|
|
1304
|
+
}
|
|
1305
|
+
) }) : /* @__PURE__ */ jsx("div", { role: "status", "aria-label": "Drawing the diagram", className: "p-6", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-40 w-full rounded-xl" }) }),
|
|
1306
|
+
caption ? /* @__PURE__ */ jsx("figcaption", { className: "border-t border-border px-5 py-3 text-[0.8125rem] text-muted-foreground", children: caption }) : null
|
|
1307
|
+
] });
|
|
1308
|
+
}
|
|
1309
|
+
var HEADING = {
|
|
1310
|
+
h1: "oca-display-3 mb-4 text-foreground",
|
|
1311
|
+
h2: "mb-3 mt-12 text-[1.375rem] font-medium leading-tight tracking-[-0.015em] text-foreground md:text-[1.5rem]",
|
|
1312
|
+
h3: "mb-2 mt-9 text-[1.125rem] font-medium leading-snug tracking-[-0.01em] text-foreground",
|
|
1313
|
+
h4: "mb-2 mt-7 text-[1rem] font-medium leading-snug text-foreground"
|
|
1314
|
+
};
|
|
1315
|
+
function DocsHeading({
|
|
1316
|
+
as: Tag,
|
|
1317
|
+
id,
|
|
1318
|
+
children,
|
|
1319
|
+
className,
|
|
1320
|
+
...props
|
|
1321
|
+
}) {
|
|
1322
|
+
return /* @__PURE__ */ jsxs(Tag, { id, className: cn("group scroll-mt-28", HEADING[Tag], className), ...props, children: [
|
|
1323
|
+
/* @__PURE__ */ jsx("span", { "data-heading-text": "", children }),
|
|
1324
|
+
id && Tag !== "h1" ? /* @__PURE__ */ jsxs(
|
|
1325
|
+
"a",
|
|
1326
|
+
{
|
|
1327
|
+
href: `#${id}`,
|
|
1328
|
+
className: "ml-2 inline-block rounded-md px-1 align-baseline text-[0.85em] font-normal text-oca-subtle no-underline opacity-0 transition-opacity hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100",
|
|
1329
|
+
children: [
|
|
1330
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "#" }),
|
|
1331
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Link to this section" })
|
|
1332
|
+
]
|
|
1333
|
+
}
|
|
1334
|
+
) : null
|
|
1335
|
+
] });
|
|
1336
|
+
}
|
|
1337
|
+
function codeText(node) {
|
|
1338
|
+
if (typeof node === "string") return node;
|
|
1339
|
+
if (typeof node === "number") return String(node);
|
|
1340
|
+
if (Array.isArray(node)) return node.map(codeText).join("");
|
|
1341
|
+
if (isValidElement(node)) return codeText(node.props.children);
|
|
1342
|
+
return "";
|
|
1343
|
+
}
|
|
1344
|
+
function codeLang(node) {
|
|
1345
|
+
const child = Children.toArray(node)[0];
|
|
1346
|
+
if (!isValidElement(child)) return void 0;
|
|
1347
|
+
const cls = child.props.className ?? "";
|
|
1348
|
+
return cls.match(/language-([\w+-]+)/)?.[1];
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
// src/family/index.ts
|
|
1352
|
+
var OCHK_IO = "https://ochk.io";
|
|
1353
|
+
var DOCS_HREF = `${OCHK_IO}/docs`;
|
|
1354
|
+
function protocol(slug, verb, line, kinds) {
|
|
1355
|
+
return {
|
|
1356
|
+
slug,
|
|
1357
|
+
label: slug,
|
|
1358
|
+
href: `${OCHK_IO}/${slug}`,
|
|
1359
|
+
group: "protocol",
|
|
1360
|
+
line,
|
|
1361
|
+
status: "live",
|
|
1362
|
+
verb,
|
|
1363
|
+
pageHref: `${OCHK_IO}/${slug}`,
|
|
1364
|
+
toolHref: `https://${slug}.ochk.io`,
|
|
1365
|
+
specHref: `https://github.com/orangecheck/oc-${slug}-protocol`,
|
|
1366
|
+
kinds
|
|
1367
|
+
};
|
|
1368
|
+
}
|
|
1369
|
+
var PROTOCOLS = [
|
|
1370
|
+
protocol("attest", "identity", "Show that an address holds bitcoin, and for how long.", "30078"),
|
|
1371
|
+
protocol("lock", "confidentiality", "Encrypt to a Bitcoin address, so only its holder can open it.", "30078"),
|
|
1372
|
+
protocol("vote", "legitimacy", "Polls weighed in sats, that anyone can tally.", "30080\u201330082"),
|
|
1373
|
+
protocol("stamp", "provenance", "Prove who signed something, and when.", "30083"),
|
|
1374
|
+
protocol("agent", "authority", "Give software scoped, revocable permission to act for you.", "30083\u201330086"),
|
|
1375
|
+
protocol("pledge", "commitment", "Make a promise with bitcoin behind it, on a public record.", "30078")
|
|
1376
|
+
];
|
|
1377
|
+
var PROTOCOL_ORDER = PROTOCOLS.map((p) => p.slug);
|
|
1378
|
+
var FAMILY = [
|
|
1379
|
+
{
|
|
1380
|
+
slug: "home",
|
|
1381
|
+
label: "ochk.io",
|
|
1382
|
+
href: OCHK_IO,
|
|
1383
|
+
group: "orangecheck",
|
|
1384
|
+
line: "The open protocols, and the company behind them.",
|
|
1385
|
+
status: "live"
|
|
1386
|
+
},
|
|
1387
|
+
{
|
|
1388
|
+
slug: "me",
|
|
1389
|
+
label: "ochk.app",
|
|
1390
|
+
href: "https://ochk.app",
|
|
1391
|
+
group: "orangecheck",
|
|
1392
|
+
line: "One account, with Bitcoin behind it.",
|
|
1393
|
+
status: "testing"
|
|
1394
|
+
},
|
|
1395
|
+
{
|
|
1396
|
+
slug: "docs",
|
|
1397
|
+
label: "docs",
|
|
1398
|
+
href: DOCS_HREF,
|
|
1399
|
+
group: "orangecheck",
|
|
1400
|
+
line: "Specs, SDKs and guides for every protocol.",
|
|
1401
|
+
status: "live"
|
|
1402
|
+
},
|
|
1403
|
+
...PROTOCOLS,
|
|
1404
|
+
{
|
|
1405
|
+
slug: "vault",
|
|
1406
|
+
label: "vault",
|
|
1407
|
+
href: "https://vault.ochk.io",
|
|
1408
|
+
group: "app",
|
|
1409
|
+
line: "A password manager, encrypted in your browser.",
|
|
1410
|
+
status: "live",
|
|
1411
|
+
protocols: ["lock"]
|
|
1412
|
+
},
|
|
1413
|
+
{
|
|
1414
|
+
slug: "chat",
|
|
1415
|
+
label: "chat",
|
|
1416
|
+
href: "https://chat.ochk.io",
|
|
1417
|
+
group: "app",
|
|
1418
|
+
line: "Messages only the holder of a Bitcoin address can read.",
|
|
1419
|
+
status: "testing",
|
|
1420
|
+
protocols: ["lock"]
|
|
1421
|
+
},
|
|
1422
|
+
{
|
|
1423
|
+
slug: "cosign",
|
|
1424
|
+
label: "cosign",
|
|
1425
|
+
href: "https://cosign.ochk.io",
|
|
1426
|
+
group: "app",
|
|
1427
|
+
line: "Builders find co-founders and backers.",
|
|
1428
|
+
status: "testing",
|
|
1429
|
+
// Signs in with an orangecheck account and a wallet; uses none of the six directly.
|
|
1430
|
+
protocols: []
|
|
1431
|
+
},
|
|
1432
|
+
{
|
|
1433
|
+
slug: "me-demo",
|
|
1434
|
+
// "demo", not the made-up app's own name, so nobody takes it for ours.
|
|
1435
|
+
label: "demo",
|
|
1436
|
+
href: "https://me-demo.ochk.io",
|
|
1437
|
+
group: "app",
|
|
1438
|
+
line: "Lumen Notes, a made-up app that signs in with orangecheck.",
|
|
1439
|
+
status: "live"
|
|
1440
|
+
},
|
|
1441
|
+
{
|
|
1442
|
+
slug: "globe",
|
|
1443
|
+
label: "globe",
|
|
1444
|
+
href: "https://globe.ochk.io",
|
|
1445
|
+
group: "public-good",
|
|
1446
|
+
line: "The Bitcoin network, live, on a globe.",
|
|
1447
|
+
status: "live"
|
|
1448
|
+
},
|
|
1449
|
+
{
|
|
1450
|
+
slug: "btc",
|
|
1451
|
+
label: "btc",
|
|
1452
|
+
href: "https://btc.ochk.io",
|
|
1453
|
+
group: "public-good",
|
|
1454
|
+
line: "A free desk for reading the Bitcoin market.",
|
|
1455
|
+
status: "live"
|
|
1456
|
+
}
|
|
1457
|
+
];
|
|
1458
|
+
var BY_SLUG = new Map(FAMILY.map((s) => [s.slug, s]));
|
|
1459
|
+
function protocolSite(slug) {
|
|
1460
|
+
return BY_SLUG.get(slug);
|
|
1461
|
+
}
|
|
1462
|
+
[
|
|
1463
|
+
{
|
|
1464
|
+
href: `${OCHK_IO}/protocols`,
|
|
1465
|
+
label: "Protocols",
|
|
1466
|
+
children: PROTOCOLS.map((p) => ({ href: p.pageHref, label: p.label, description: p.line }))
|
|
1467
|
+
},
|
|
1468
|
+
{ href: `${OCHK_IO}/apps`, label: "Apps" },
|
|
1469
|
+
{ href: DOCS_HREF, label: "Docs" },
|
|
1470
|
+
{ href: `${OCHK_IO}/trust`, label: "Trust" },
|
|
1471
|
+
{ href: `${OCHK_IO}/about`, label: "About" }
|
|
1472
|
+
];
|
|
1473
|
+
var CARD = "group relative flex h-full flex-col rounded-[1.25rem] border border-border bg-card p-6 transition-colors hover:border-oca-hairline-strong md:p-7 has-[a:focus-visible]:ring-2 has-[a:focus-visible]:ring-ring has-[a:focus-visible]:ring-offset-2 has-[a:focus-visible]:ring-offset-background";
|
|
1474
|
+
var STRETCH = 'outline-none after:absolute after:inset-0 after:rounded-[1.25rem] after:content-[""]';
|
|
1475
|
+
var pad = (n) => String(n + 1).padStart(2, "0");
|
|
1476
|
+
function ProtocolGrid({
|
|
1477
|
+
protocols = PROTOCOL_ORDER,
|
|
1478
|
+
link = "page",
|
|
1479
|
+
className
|
|
1480
|
+
}) {
|
|
1481
|
+
return /* @__PURE__ */ jsx("ul", { className: cn("grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 md:gap-5", className), children: protocols.map((slug) => {
|
|
1482
|
+
const p = protocolSite(slug);
|
|
1483
|
+
const i = PROTOCOL_ORDER.indexOf(slug);
|
|
1484
|
+
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("div", { className: cn(CARD, "gap-4"), children: [
|
|
1485
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
1486
|
+
/* @__PURE__ */ jsxs("span", { className: "oca-numeral", children: [
|
|
1487
|
+
pad(i),
|
|
1488
|
+
" ",
|
|
1489
|
+
/* @__PURE__ */ jsx("span", { className: "ml-1.5 capitalize", children: p.verb })
|
|
1490
|
+
] }),
|
|
1491
|
+
p.status !== "live" ? /* @__PURE__ */ jsx(StatusBadge, { status: p.status }) : null
|
|
1492
|
+
] }),
|
|
1493
|
+
/* @__PURE__ */ jsx("h3", { className: "oca-display-3", children: /* @__PURE__ */ jsx(
|
|
1494
|
+
"a",
|
|
1495
|
+
{
|
|
1496
|
+
href: link === "tool" ? p.toolHref : link === "docs" ? `${DOCS_HREF}/${p.slug}` : p.pageHref,
|
|
1497
|
+
className: STRETCH,
|
|
1498
|
+
children: p.label
|
|
1499
|
+
}
|
|
1500
|
+
) }),
|
|
1501
|
+
/* @__PURE__ */ jsx("p", { className: "oca-body", children: p.line }),
|
|
1502
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-auto flex items-center justify-between gap-3 pt-2 text-[0.875rem] text-muted-foreground", children: [
|
|
1503
|
+
/* @__PURE__ */ jsxs("span", { className: "oca-tabular", children: [
|
|
1504
|
+
"Nostr kind ",
|
|
1505
|
+
p.kinds
|
|
1506
|
+
] }),
|
|
1507
|
+
link === "tool" ? /* @__PURE__ */ jsx(
|
|
1508
|
+
ArrowUpRight,
|
|
1509
|
+
{
|
|
1510
|
+
"aria-hidden": true,
|
|
1511
|
+
className: "size-4 transition-transform duration-200 group-hover:-translate-y-0.5 group-hover:translate-x-0.5 group-hover:text-foreground"
|
|
1512
|
+
}
|
|
1513
|
+
) : /* @__PURE__ */ jsx(
|
|
1514
|
+
ArrowRight,
|
|
1515
|
+
{
|
|
1516
|
+
"aria-hidden": true,
|
|
1517
|
+
className: "size-4 transition-transform duration-200 group-hover:translate-x-0.5 group-hover:text-foreground"
|
|
1518
|
+
}
|
|
1519
|
+
)
|
|
1520
|
+
] })
|
|
1521
|
+
] }) }, slug);
|
|
1522
|
+
}) });
|
|
1523
|
+
}
|
|
1524
|
+
function SpecCard({
|
|
1525
|
+
protocol: protocol2,
|
|
1526
|
+
version,
|
|
1527
|
+
license,
|
|
1528
|
+
vectors,
|
|
1529
|
+
size = "md",
|
|
1530
|
+
className
|
|
1531
|
+
}) {
|
|
1532
|
+
const p = protocolSite(protocol2);
|
|
1533
|
+
const repo = `oc-${p.slug}-protocol`;
|
|
1534
|
+
const facts = [
|
|
1535
|
+
["Version", version],
|
|
1536
|
+
...license ? [["Licence", license]] : [],
|
|
1537
|
+
["Nostr kind", p.kinds],
|
|
1538
|
+
...vectors !== void 0 ? [["Test vectors", String(vectors)]] : []
|
|
1539
|
+
];
|
|
1540
|
+
if (size === "sm") {
|
|
1541
|
+
return /* @__PURE__ */ jsxs(
|
|
1542
|
+
"a",
|
|
1543
|
+
{
|
|
1544
|
+
href: p.specHref,
|
|
1545
|
+
className: cn(
|
|
1546
|
+
"group flex flex-wrap items-center gap-x-4 gap-y-1 rounded-2xl border border-border bg-card px-4 py-3 text-[0.875rem] transition-colors hover:border-oca-hairline-strong",
|
|
1547
|
+
className
|
|
1548
|
+
),
|
|
1549
|
+
children: [
|
|
1550
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-[0.8125rem] text-foreground", children: repo }),
|
|
1551
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: facts.map(([k, v]) => k === "Version" ? `v${v}` : k === "Nostr kind" ? `kind ${v}` : v).join(" \xB7 ") }),
|
|
1552
|
+
/* @__PURE__ */ jsxs("span", { className: "ml-auto flex items-center gap-1 text-muted-foreground group-hover:text-foreground", children: [
|
|
1553
|
+
"Read the spec ",
|
|
1554
|
+
/* @__PURE__ */ jsx(ArrowUpRight, { "aria-hidden": true, className: "size-4" })
|
|
1555
|
+
] })
|
|
1556
|
+
]
|
|
1557
|
+
}
|
|
1558
|
+
);
|
|
1559
|
+
}
|
|
1560
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-6 rounded-[1.25rem] border border-border bg-card p-6 md:p-8", className), children: [
|
|
1561
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4", children: [
|
|
1562
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-1.5", children: [
|
|
1563
|
+
/* @__PURE__ */ jsx("p", { className: "text-[0.875rem] text-muted-foreground", children: "The spec" }),
|
|
1564
|
+
/* @__PURE__ */ jsx("h3", { className: "oca-title break-all font-mono text-[1.0625rem] tracking-normal", children: repo })
|
|
1565
|
+
] }),
|
|
1566
|
+
p.status !== "live" ? /* @__PURE__ */ jsx(StatusBadge, { status: p.status }) : null
|
|
1567
|
+
] }),
|
|
1568
|
+
/* @__PURE__ */ jsx("dl", { className: "grid grid-cols-2 gap-x-6 gap-y-4 sm:grid-cols-4", children: facts.map(([k, v]) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1569
|
+
/* @__PURE__ */ jsx("dt", { className: "text-[0.8125rem] text-muted-foreground", children: k }),
|
|
1570
|
+
/* @__PURE__ */ jsx("dd", { className: "oca-tabular text-[1.0625rem]", children: v })
|
|
1571
|
+
] }, k)) }),
|
|
1572
|
+
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { asChild: true, variant: "secondary", size: "sm", children: /* @__PURE__ */ jsxs("a", { href: p.specHref, children: [
|
|
1573
|
+
"Read the spec ",
|
|
1574
|
+
/* @__PURE__ */ jsx(ArrowUpRight, { "aria-hidden": true })
|
|
1575
|
+
] }) }) })
|
|
1576
|
+
] });
|
|
1577
|
+
}
|
|
1578
|
+
var LINK = "text-foreground underline decoration-foreground/35 underline-offset-4 transition-colors hover:decoration-foreground";
|
|
1579
|
+
function TextLink({
|
|
1580
|
+
href,
|
|
1581
|
+
children,
|
|
1582
|
+
external,
|
|
1583
|
+
className
|
|
1584
|
+
}) {
|
|
1585
|
+
const internal = href.startsWith("/") && !href.startsWith("/api/") && !href.startsWith("/.well-known/");
|
|
1586
|
+
const offsite = external ?? /^https?:\/\//.test(href);
|
|
1587
|
+
if (internal && !offsite) {
|
|
1588
|
+
return /* @__PURE__ */ jsx(Link, { href, className: cn(LINK, className), children });
|
|
1589
|
+
}
|
|
1590
|
+
return /* @__PURE__ */ jsxs("a", { href, className: cn(LINK, className), ...offsite ? { target: "_blank", rel: "noreferrer" } : {}, children: [
|
|
1591
|
+
children,
|
|
1592
|
+
offsite ? /* @__PURE__ */ jsx("span", { className: "sr-only", children: " (opens in a new tab)" }) : null
|
|
1593
|
+
] });
|
|
1594
|
+
}
|
|
1595
|
+
function createMdxComponents({ mermaid } = {}) {
|
|
1596
|
+
function Pre(props) {
|
|
1597
|
+
if (props["data-oca-code"] !== void 0) {
|
|
1598
|
+
return /* @__PURE__ */ jsx(
|
|
1599
|
+
CodeBlock,
|
|
1600
|
+
{
|
|
1601
|
+
html: props["data-html"] ?? "",
|
|
1602
|
+
lang: props["data-lang"],
|
|
1603
|
+
caption: props["data-title"],
|
|
1604
|
+
diff: props["data-diff"] !== void 0,
|
|
1605
|
+
lineNumbers: props["data-line-numbers"] !== void 0,
|
|
1606
|
+
className: "my-6"
|
|
1607
|
+
}
|
|
1608
|
+
);
|
|
1609
|
+
}
|
|
1610
|
+
const lang = codeLang(props.children);
|
|
1611
|
+
const code = codeText(props.children);
|
|
1612
|
+
if (lang === "mermaid" && mermaid) return /* @__PURE__ */ jsx(Diagram, { chart: code, load: mermaid });
|
|
1613
|
+
return /* @__PURE__ */ jsx(
|
|
1614
|
+
CodeBlock,
|
|
1615
|
+
{
|
|
1616
|
+
code,
|
|
1617
|
+
lang: lang === "mermaid" ? void 0 : lang,
|
|
1618
|
+
caption: lang === "mermaid" ? "Diagram source" : void 0,
|
|
1619
|
+
className: "my-6"
|
|
1620
|
+
}
|
|
1621
|
+
);
|
|
1622
|
+
}
|
|
1623
|
+
function A({ href, children, ...rest }) {
|
|
1624
|
+
if (!href || href.startsWith("#")) {
|
|
1625
|
+
return /* @__PURE__ */ jsx("a", { href, ...rest, className: "text-foreground underline decoration-foreground/35 underline-offset-4 hover:decoration-foreground", children });
|
|
1626
|
+
}
|
|
1627
|
+
return /* @__PURE__ */ jsx(TextLink, { href, children });
|
|
1628
|
+
}
|
|
1629
|
+
const heading = (as) => function Heading(props) {
|
|
1630
|
+
return /* @__PURE__ */ jsx(DocsHeading, { as, ...props });
|
|
1631
|
+
};
|
|
1632
|
+
return {
|
|
1633
|
+
h1: heading("h1"),
|
|
1634
|
+
h2: heading("h2"),
|
|
1635
|
+
h3: heading("h3"),
|
|
1636
|
+
h4: heading("h4"),
|
|
1637
|
+
p: ({ className, ...props }) => /* @__PURE__ */ jsx("p", { className: cn("my-4 text-[1rem] leading-[1.75] text-muted-foreground md:text-[1.0625rem]", className), ...props }),
|
|
1638
|
+
a: A,
|
|
1639
|
+
strong: (props) => /* @__PURE__ */ jsx("strong", { className: "font-medium text-foreground", ...props }),
|
|
1640
|
+
ul: ({ className, ...props }) => /* @__PURE__ */ jsx(
|
|
1641
|
+
"ul",
|
|
1642
|
+
{
|
|
1643
|
+
className: cn(
|
|
1644
|
+
"my-4 list-disc space-y-1.5 pl-5 text-[1rem] leading-[1.7] text-muted-foreground marker:text-oca-subtle md:text-[1.0625rem]",
|
|
1645
|
+
className
|
|
1646
|
+
),
|
|
1647
|
+
...props
|
|
1648
|
+
}
|
|
1649
|
+
),
|
|
1650
|
+
ol: ({ className, ...props }) => /* @__PURE__ */ jsx(
|
|
1651
|
+
"ol",
|
|
1652
|
+
{
|
|
1653
|
+
className: cn(
|
|
1654
|
+
"my-4 list-decimal space-y-1.5 pl-5 text-[1rem] leading-[1.7] text-muted-foreground marker:text-oca-subtle md:text-[1.0625rem]",
|
|
1655
|
+
className
|
|
1656
|
+
),
|
|
1657
|
+
...props
|
|
1658
|
+
}
|
|
1659
|
+
),
|
|
1660
|
+
li: ({ className, ...props }) => /* @__PURE__ */ jsx("li", { className: cn("pl-1 [&>p]:my-1 [&>ul]:my-1.5 [&>ol]:my-1.5", className), ...props }),
|
|
1661
|
+
blockquote: ({ children }) => /* @__PURE__ */ jsx(Callout, { children }),
|
|
1662
|
+
hr: () => /* @__PURE__ */ jsx("hr", { className: "my-10 border-border" }),
|
|
1663
|
+
table: MdxTable,
|
|
1664
|
+
code: ({ className, ...props }) => /* @__PURE__ */ jsx(
|
|
1665
|
+
"code",
|
|
1666
|
+
{
|
|
1667
|
+
className: cn("break-words rounded-md bg-muted px-1.5 py-0.5 font-mono text-[0.875em] text-foreground", className),
|
|
1668
|
+
...props
|
|
1669
|
+
}
|
|
1670
|
+
),
|
|
1671
|
+
pre: Pre,
|
|
1672
|
+
img: ({ className, alt = "", ...props }) => /* @__PURE__ */ jsx("img", { alt, loading: "lazy", className: cn("my-6 h-auto max-w-full rounded-2xl border border-border", className), ...props }),
|
|
1673
|
+
Callout,
|
|
1674
|
+
Steps,
|
|
1675
|
+
Step,
|
|
1676
|
+
LinkCard,
|
|
1677
|
+
CardGrid,
|
|
1678
|
+
ApiTable,
|
|
1679
|
+
CodeBlock,
|
|
1680
|
+
CodeTabs,
|
|
1681
|
+
InstallTabs,
|
|
1682
|
+
SpecCard,
|
|
1683
|
+
ProtocolGrid,
|
|
1684
|
+
StatusBadge,
|
|
1685
|
+
...mermaid ? { Diagram: (p) => /* @__PURE__ */ jsx(Diagram, { ...p, load: mermaid }) } : {}
|
|
1686
|
+
};
|
|
1687
|
+
}
|
|
1688
|
+
var mdxComponents = createMdxComponents();
|
|
1689
|
+
|
|
1690
|
+
export { createMdxComponents, mdxComponents };
|
|
1691
|
+
//# sourceMappingURL=mdx.mjs.map
|
|
1692
|
+
//# sourceMappingURL=mdx.mjs.map
|