@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/index.js
CHANGED
|
@@ -20,7 +20,7 @@ var PopoverPrimitive = require('@radix-ui/react-popover');
|
|
|
20
20
|
var TooltipPrimitive = require('@radix-ui/react-tooltip');
|
|
21
21
|
var TabsPrimitive = require('@radix-ui/react-tabs');
|
|
22
22
|
var QRCode = require('qrcode');
|
|
23
|
-
var
|
|
23
|
+
var Link8 = require('next/link');
|
|
24
24
|
var nextThemes = require('next-themes');
|
|
25
25
|
|
|
26
26
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -55,7 +55,7 @@ var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitiv
|
|
|
55
55
|
var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
|
|
56
56
|
var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
|
|
57
57
|
var QRCode__default = /*#__PURE__*/_interopDefault(QRCode);
|
|
58
|
-
var
|
|
58
|
+
var Link8__default = /*#__PURE__*/_interopDefault(Link8);
|
|
59
59
|
|
|
60
60
|
// src/tokens/index.ts
|
|
61
61
|
var APP_ATTRIBUTE = "data-oc-app";
|
|
@@ -397,6 +397,20 @@ function CardContent({ className, ...props }) {
|
|
|
397
397
|
function CardFooter({ className, ...props }) {
|
|
398
398
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mt-6 flex flex-wrap items-center gap-3", className), ...props });
|
|
399
399
|
}
|
|
400
|
+
function sharedContext(name, initial) {
|
|
401
|
+
const key = /* @__PURE__ */ Symbol.for(`@orangecheck/app-design/${name}`);
|
|
402
|
+
const store = globalThis;
|
|
403
|
+
return store[key] ?? (store[key] = react.createContext(initial));
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// src/lib/density.ts
|
|
407
|
+
var DensityContext = sharedContext("density", "comfortable");
|
|
408
|
+
function DensityProvider({ density, children }) {
|
|
409
|
+
return react.createElement(DensityContext.Provider, { value: density }, children);
|
|
410
|
+
}
|
|
411
|
+
function useDensity() {
|
|
412
|
+
return react.useContext(DensityContext);
|
|
413
|
+
}
|
|
400
414
|
var fieldBase = [
|
|
401
415
|
"w-full rounded-xl border border-input bg-card text-foreground placeholder:text-oca-subtle",
|
|
402
416
|
"text-base md:text-[0.9375rem] outline-none transition-[border-color,box-shadow]",
|
|
@@ -404,8 +418,24 @@ var fieldBase = [
|
|
|
404
418
|
"disabled:cursor-not-allowed disabled:opacity-55",
|
|
405
419
|
"aria-[invalid=true]:border-destructive aria-[invalid=true]:focus:ring-[color-mix(in_oklab,var(--destructive)_14%,transparent)]"
|
|
406
420
|
];
|
|
407
|
-
var
|
|
408
|
-
|
|
421
|
+
var FIELD_SIZE = {
|
|
422
|
+
md: "h-11 px-3.5",
|
|
423
|
+
sm: "h-9 rounded-[0.625rem] px-3 md:text-[0.875rem]"
|
|
424
|
+
};
|
|
425
|
+
var Input = react.forwardRef(function Input2({ className, type = "text", size, ...props }, ref) {
|
|
426
|
+
const density = useDensity();
|
|
427
|
+
const s = size ?? (density === "compact" ? "sm" : "md");
|
|
428
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
429
|
+
"input",
|
|
430
|
+
{
|
|
431
|
+
ref,
|
|
432
|
+
type,
|
|
433
|
+
"data-ui": "input",
|
|
434
|
+
"data-size": s,
|
|
435
|
+
className: cn(fieldBase, FIELD_SIZE[s], className),
|
|
436
|
+
...props
|
|
437
|
+
}
|
|
438
|
+
);
|
|
409
439
|
});
|
|
410
440
|
var Textarea = react.forwardRef(
|
|
411
441
|
function Textarea2({ className, ...props }, ref) {
|
|
@@ -462,15 +492,29 @@ function Field({ label, hint, optional, error, children, className, hideLabel, a
|
|
|
462
492
|
error ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, role: "alert", className: "text-[0.8125rem] leading-snug text-destructive", children: error }) : null
|
|
463
493
|
] });
|
|
464
494
|
}
|
|
465
|
-
var
|
|
495
|
+
var SelectFieldContext = sharedContext("select-field", null);
|
|
496
|
+
function Select({
|
|
497
|
+
id,
|
|
498
|
+
"aria-describedby": describedBy,
|
|
499
|
+
"aria-invalid": invalid,
|
|
500
|
+
...props
|
|
501
|
+
}) {
|
|
502
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SelectFieldContext.Provider, { value: { id, "aria-describedby": describedBy, "aria-invalid": invalid }, children: /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Root, { ...props }) });
|
|
503
|
+
}
|
|
466
504
|
var SelectGroup = SelectPrimitive__namespace.Group;
|
|
467
505
|
var SelectValue = SelectPrimitive__namespace.Value;
|
|
468
|
-
var SelectTrigger = react.forwardRef(function SelectTrigger2({ className, children, ...props }, ref) {
|
|
506
|
+
var SelectTrigger = react.forwardRef(function SelectTrigger2({ className, children, size, ...props }, ref) {
|
|
507
|
+
const density = useDensity();
|
|
508
|
+
const field = react.useContext(SelectFieldContext);
|
|
509
|
+
const s = size ?? (density === "compact" ? "sm" : "md");
|
|
469
510
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
470
511
|
SelectPrimitive__namespace.Trigger,
|
|
471
512
|
{
|
|
472
513
|
ref,
|
|
473
|
-
|
|
514
|
+
id: field?.id,
|
|
515
|
+
"aria-describedby": field?.["aria-describedby"],
|
|
516
|
+
"aria-invalid": field?.["aria-invalid"],
|
|
517
|
+
className: cn(fieldBase, FIELD_SIZE[s], "flex items-center justify-between gap-2 text-left", className),
|
|
474
518
|
...props,
|
|
475
519
|
children: [
|
|
476
520
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children }),
|
|
@@ -1786,6 +1830,7 @@ function useActiveHeading(ids) {
|
|
|
1786
1830
|
const [active, setActive] = react.useState(ids[0]);
|
|
1787
1831
|
const key = ids.join("|");
|
|
1788
1832
|
react.useEffect(() => {
|
|
1833
|
+
setActive(key.split("|")[0] || void 0);
|
|
1789
1834
|
const els = key.split("|").map((id) => document.getElementById(id)).filter((el) => el !== null);
|
|
1790
1835
|
if (els.length === 0 || typeof IntersectionObserver === "undefined") return;
|
|
1791
1836
|
const io = new IntersectionObserver(
|
|
@@ -1878,7 +1923,563 @@ function StepGrid({ items, look = "cards", className }) {
|
|
|
1878
1923
|
] }) }, i)
|
|
1879
1924
|
) });
|
|
1880
1925
|
}
|
|
1881
|
-
var
|
|
1926
|
+
var KIND = {
|
|
1927
|
+
package: "text-oca-code-package",
|
|
1928
|
+
tag: "text-oca-code-tag",
|
|
1929
|
+
link: "text-oca-code-link"
|
|
1930
|
+
};
|
|
1931
|
+
function PackageCard({ items, className }) {
|
|
1932
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1933
|
+
"div",
|
|
1934
|
+
{
|
|
1935
|
+
className: cn(
|
|
1936
|
+
"grid gap-x-10 gap-y-7 rounded-[1.25rem] border border-oca-ink-line bg-oca-ink-card p-6 text-oca-ink-foreground md:grid-cols-2 md:p-9",
|
|
1937
|
+
className
|
|
1938
|
+
),
|
|
1939
|
+
children: items.map((it, i) => {
|
|
1940
|
+
const code = /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[0.9375rem]", KIND[it.kind ?? "package"]), children: it.code });
|
|
1941
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col gap-1.5", children: [
|
|
1942
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[1.125rem] font-semibold tracking-[-0.01em] text-oca-ink-title", children: it.title }),
|
|
1943
|
+
it.href ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: it.href, className: "w-fit underline decoration-transparent underline-offset-4 hover:decoration-current", children: code }) : code,
|
|
1944
|
+
it.note ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-[0.9375rem] leading-relaxed text-oca-ink-subtle", children: [
|
|
1945
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, children: "// " }),
|
|
1946
|
+
it.note
|
|
1947
|
+
] }) : null
|
|
1948
|
+
] }, i);
|
|
1949
|
+
})
|
|
1950
|
+
}
|
|
1951
|
+
);
|
|
1952
|
+
}
|
|
1953
|
+
|
|
1954
|
+
// src/code/highlight.ts
|
|
1955
|
+
var TOKEN_CLASS = {
|
|
1956
|
+
keyword: "oca-k",
|
|
1957
|
+
string: "oca-s",
|
|
1958
|
+
number: "oca-n",
|
|
1959
|
+
function: "oca-f",
|
|
1960
|
+
type: "oca-y",
|
|
1961
|
+
property: "oca-p",
|
|
1962
|
+
comment: "oca-c",
|
|
1963
|
+
tag: "oca-g",
|
|
1964
|
+
url: "oca-u"
|
|
1965
|
+
};
|
|
1966
|
+
var ALIASES = {
|
|
1967
|
+
ts: "js",
|
|
1968
|
+
typescript: "js",
|
|
1969
|
+
tsx: "js",
|
|
1970
|
+
js: "js",
|
|
1971
|
+
javascript: "js",
|
|
1972
|
+
jsx: "js",
|
|
1973
|
+
mjs: "js",
|
|
1974
|
+
cjs: "js",
|
|
1975
|
+
json: "json",
|
|
1976
|
+
jsonc: "json",
|
|
1977
|
+
json5: "json",
|
|
1978
|
+
bash: "shell",
|
|
1979
|
+
sh: "shell",
|
|
1980
|
+
shell: "shell",
|
|
1981
|
+
zsh: "shell",
|
|
1982
|
+
console: "shell",
|
|
1983
|
+
terminal: "shell",
|
|
1984
|
+
py: "python",
|
|
1985
|
+
python: "python",
|
|
1986
|
+
yaml: "yaml",
|
|
1987
|
+
yml: "yaml",
|
|
1988
|
+
diff: "diff"
|
|
1989
|
+
};
|
|
1990
|
+
var CODE_LANGS = Object.keys(ALIASES);
|
|
1991
|
+
function grammarOf(lang) {
|
|
1992
|
+
return lang && ALIASES[lang.toLowerCase()] || "plain";
|
|
1993
|
+
}
|
|
1994
|
+
function collector() {
|
|
1995
|
+
const tokens = [];
|
|
1996
|
+
const emit2 = (text, kind) => {
|
|
1997
|
+
if (!text) return;
|
|
1998
|
+
const last = tokens[tokens.length - 1];
|
|
1999
|
+
if (last && last.kind === kind) last.text += text;
|
|
2000
|
+
else tokens.push(kind ? { text, kind } : { text });
|
|
2001
|
+
};
|
|
2002
|
+
return { emit: emit2, tokens };
|
|
2003
|
+
}
|
|
2004
|
+
function at(re, src, i) {
|
|
2005
|
+
re.lastIndex = i;
|
|
2006
|
+
const m = re.exec(src);
|
|
2007
|
+
return m ? m[0] : null;
|
|
2008
|
+
}
|
|
2009
|
+
var WS = /[ \t]+/y;
|
|
2010
|
+
var NEWLINE = /\r?\n/y;
|
|
2011
|
+
var JS_KEYWORDS = new Set(
|
|
2012
|
+
"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(" ")
|
|
2013
|
+
);
|
|
2014
|
+
var JS_CONSTANTS = /* @__PURE__ */ new Set(["true", "false", "null", "undefined", "NaN", "Infinity"]);
|
|
2015
|
+
var TS_PRIMITIVES = /* @__PURE__ */ new Set(["string", "number", "boolean", "bigint", "symbol", "object", "unknown", "any", "never"]);
|
|
2016
|
+
var isConstant = (m) => /^[A-Z][A-Z\d_]+$/.test(m) && (m.includes("_") || m.length > 4);
|
|
2017
|
+
var JS_LINE_COMMENT = /\/\/[^\n]*/y;
|
|
2018
|
+
var JS_BLOCK_COMMENT = /\/\*[\s\S]*?(?:\*\/|$)/y;
|
|
2019
|
+
var JS_TEMPLATE = /`(?:\\[\s\S]|[^\\`])*`?/y;
|
|
2020
|
+
var JS_STRING = /'(?:\\.|[^\\'\n])*'?|"(?:\\.|[^\\"\n])*"?/y;
|
|
2021
|
+
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;
|
|
2022
|
+
var JS_IDENT = /[A-Za-z_$][\w$]*/y;
|
|
2023
|
+
var JS_DECORATOR = /@[A-Za-z_$][\w$.]*/y;
|
|
2024
|
+
var JS_CALL_AFTER = /\s*(?:<[\w$\s,.[\]|&'"]*>)?\s*\(/y;
|
|
2025
|
+
var JS_TAG = /<\/?(?=[A-Za-z])/y;
|
|
2026
|
+
var JS_TAG_NAME = /[A-Za-z][\w$.:-]*/y;
|
|
2027
|
+
var JS_PUNCT = /=>|\.\.\.|[{}()[\];,.<>=+\-*/%!?:&|^~#]/y;
|
|
2028
|
+
var JSX_BEFORE = /* @__PURE__ */ new Set(["(", ",", "=", "?", ":", "{", "[", ";", ">", "&&", "||", "=>", "return"]);
|
|
2029
|
+
function scanJs(src, emit2, jsx50) {
|
|
2030
|
+
let i = 0;
|
|
2031
|
+
let prev = "";
|
|
2032
|
+
let tagDepth = 0;
|
|
2033
|
+
let braceInTag = 0;
|
|
2034
|
+
const sig = (t) => {
|
|
2035
|
+
prev = t;
|
|
2036
|
+
};
|
|
2037
|
+
while (i < src.length) {
|
|
2038
|
+
let m;
|
|
2039
|
+
if ((m = at(WS, src, i)) || (m = at(NEWLINE, src, i))) {
|
|
2040
|
+
emit2(m);
|
|
2041
|
+
i += m.length;
|
|
2042
|
+
continue;
|
|
2043
|
+
}
|
|
2044
|
+
if ((m = at(JS_LINE_COMMENT, src, i)) || (m = at(JS_BLOCK_COMMENT, src, i))) {
|
|
2045
|
+
emit2(m, "comment");
|
|
2046
|
+
i += m.length;
|
|
2047
|
+
continue;
|
|
2048
|
+
}
|
|
2049
|
+
if ((m = at(JS_TEMPLATE, src, i)) || (m = at(JS_STRING, src, i))) {
|
|
2050
|
+
emit2(m, "string");
|
|
2051
|
+
i += m.length;
|
|
2052
|
+
sig('"');
|
|
2053
|
+
continue;
|
|
2054
|
+
}
|
|
2055
|
+
if (jsx50 && tagDepth === 0 && (m = at(JS_TAG, src, i)) && (prev === "" || JSX_BEFORE.has(prev))) {
|
|
2056
|
+
const name = at(JS_TAG_NAME, src, i + m.length);
|
|
2057
|
+
if (name) {
|
|
2058
|
+
emit2(m);
|
|
2059
|
+
emit2(name, "tag");
|
|
2060
|
+
i += m.length + name.length;
|
|
2061
|
+
tagDepth = 1;
|
|
2062
|
+
braceInTag = 0;
|
|
2063
|
+
sig("tag");
|
|
2064
|
+
continue;
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
if (jsx50 && tagDepth > 0 && braceInTag === 0) {
|
|
2068
|
+
if (src.startsWith("/>", i) || src[i] === ">") {
|
|
2069
|
+
const close = src[i] === ">" ? ">" : "/>";
|
|
2070
|
+
emit2(close);
|
|
2071
|
+
i += close.length;
|
|
2072
|
+
tagDepth = 0;
|
|
2073
|
+
sig(">");
|
|
2074
|
+
continue;
|
|
2075
|
+
}
|
|
2076
|
+
if ((m = at(JS_IDENT, src, i)) && /^\s*=/.test(src.slice(i + m.length, i + m.length + 4))) {
|
|
2077
|
+
emit2(m, "property");
|
|
2078
|
+
i += m.length;
|
|
2079
|
+
continue;
|
|
2080
|
+
}
|
|
2081
|
+
if (m = at(JS_IDENT, src, i)) {
|
|
2082
|
+
emit2(m, "property");
|
|
2083
|
+
i += m.length;
|
|
2084
|
+
continue;
|
|
2085
|
+
}
|
|
2086
|
+
if (src[i] === "{") braceInTag = 1;
|
|
2087
|
+
} else if (jsx50 && tagDepth > 0 && braceInTag > 0) {
|
|
2088
|
+
if (src[i] === "{") braceInTag++;
|
|
2089
|
+
else if (src[i] === "}") braceInTag--;
|
|
2090
|
+
}
|
|
2091
|
+
if (m = at(JS_DECORATOR, src, i)) {
|
|
2092
|
+
emit2(m, "function");
|
|
2093
|
+
i += m.length;
|
|
2094
|
+
sig("@");
|
|
2095
|
+
continue;
|
|
2096
|
+
}
|
|
2097
|
+
if (m = at(JS_IDENT, src, i)) {
|
|
2098
|
+
const end = i + m.length;
|
|
2099
|
+
let kind;
|
|
2100
|
+
if (prev !== "." && JS_CONSTANTS.has(m)) kind = "number";
|
|
2101
|
+
else if (prev !== "." && JS_KEYWORDS.has(m)) kind = "keyword";
|
|
2102
|
+
else if (at(JS_CALL_AFTER, src, end) !== null) kind = "function";
|
|
2103
|
+
else if (prev !== "." && TS_PRIMITIVES.has(m)) kind = "type";
|
|
2104
|
+
else if (isConstant(m)) kind = "number";
|
|
2105
|
+
else if (/^[A-Z]/.test(m)) kind = "type";
|
|
2106
|
+
emit2(m, kind);
|
|
2107
|
+
i = end;
|
|
2108
|
+
sig(kind === "keyword" ? m : "id");
|
|
2109
|
+
continue;
|
|
2110
|
+
}
|
|
2111
|
+
if (m = at(JS_NUMBER, src, i)) {
|
|
2112
|
+
emit2(m, "number");
|
|
2113
|
+
i += m.length;
|
|
2114
|
+
sig("0");
|
|
2115
|
+
continue;
|
|
2116
|
+
}
|
|
2117
|
+
if (m = at(JS_PUNCT, src, i)) {
|
|
2118
|
+
emit2(m);
|
|
2119
|
+
i += m.length;
|
|
2120
|
+
sig(m === "." ? "." : m);
|
|
2121
|
+
continue;
|
|
2122
|
+
}
|
|
2123
|
+
emit2(src[i]);
|
|
2124
|
+
i++;
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
var JSON_STRING = /"(?:\\.|[^\\"\n])*"?/y;
|
|
2128
|
+
var JSON_KEY_AFTER = /\s*:/y;
|
|
2129
|
+
var JSON_NUMBER = /-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/y;
|
|
2130
|
+
var JSON_WORD = /true|false|null/y;
|
|
2131
|
+
function scanJson(src, emit2) {
|
|
2132
|
+
let i = 0;
|
|
2133
|
+
while (i < src.length) {
|
|
2134
|
+
let m;
|
|
2135
|
+
if ((m = at(JS_LINE_COMMENT, src, i)) || (m = at(JS_BLOCK_COMMENT, src, i))) {
|
|
2136
|
+
emit2(m, "comment");
|
|
2137
|
+
} else if (m = at(JSON_STRING, src, i)) {
|
|
2138
|
+
emit2(m, at(JSON_KEY_AFTER, src, i + m.length) !== null ? "property" : "string");
|
|
2139
|
+
} else if ((m = at(JSON_NUMBER, src, i)) || (m = at(JSON_WORD, src, i))) {
|
|
2140
|
+
emit2(m, "number");
|
|
2141
|
+
} else {
|
|
2142
|
+
m = src[i];
|
|
2143
|
+
emit2(m);
|
|
2144
|
+
}
|
|
2145
|
+
i += m.length;
|
|
2146
|
+
}
|
|
2147
|
+
}
|
|
2148
|
+
var SH_KEYWORDS = new Set(
|
|
2149
|
+
"if then else elif fi for in do done case esac while until function return export local select time".split(" ")
|
|
2150
|
+
);
|
|
2151
|
+
var SH_PROMPT = /\$ (?=\S)/y;
|
|
2152
|
+
var SH_COMMENT = /#[^\n]*/y;
|
|
2153
|
+
var SH_SINGLE = /'[^']*'?/y;
|
|
2154
|
+
var SH_DOUBLE = /"(?:\\.|[^\\"])*"?/y;
|
|
2155
|
+
var SH_VAR = /\$(?:\{[^}\n]*\}?|[A-Za-z_][\w]*|[@*#?$!\d])/y;
|
|
2156
|
+
var SH_URL = /https?:\/\/[^\s'"`)]+/y;
|
|
2157
|
+
var SH_FLAG = /--?[A-Za-z][\w-]*/y;
|
|
2158
|
+
var SH_ASSIGN = /[A-Za-z_][\w]*(?==)/y;
|
|
2159
|
+
var SH_VALUE = /=[^\s|&;()<>'"`$]*/y;
|
|
2160
|
+
var SH_WORD = /[^\s|&;()<>'"`$#]+/y;
|
|
2161
|
+
var SH_OPERATOR = /\|\||&&|[|;&]|\$\(|[()<>]/y;
|
|
2162
|
+
function scanShell(src, emit2) {
|
|
2163
|
+
let i = 0;
|
|
2164
|
+
let command = true;
|
|
2165
|
+
let lineStart = true;
|
|
2166
|
+
while (i < src.length) {
|
|
2167
|
+
let m;
|
|
2168
|
+
if (m = at(NEWLINE, src, i)) {
|
|
2169
|
+
emit2(m);
|
|
2170
|
+
i += m.length;
|
|
2171
|
+
command = !/\\\s*$/.test(src.slice(0, i - m.length));
|
|
2172
|
+
lineStart = true;
|
|
2173
|
+
continue;
|
|
2174
|
+
}
|
|
2175
|
+
if (m = at(WS, src, i)) {
|
|
2176
|
+
emit2(m);
|
|
2177
|
+
i += m.length;
|
|
2178
|
+
continue;
|
|
2179
|
+
}
|
|
2180
|
+
if (lineStart && (m = at(SH_PROMPT, src, i))) {
|
|
2181
|
+
emit2(m, "comment");
|
|
2182
|
+
i += m.length;
|
|
2183
|
+
lineStart = false;
|
|
2184
|
+
continue;
|
|
2185
|
+
}
|
|
2186
|
+
lineStart = false;
|
|
2187
|
+
if ((m = at(SH_COMMENT, src, i)) && (i === 0 || /\s/.test(src[i - 1]))) {
|
|
2188
|
+
emit2(m, "comment");
|
|
2189
|
+
i += m.length;
|
|
2190
|
+
continue;
|
|
2191
|
+
}
|
|
2192
|
+
if ((m = at(SH_SINGLE, src, i)) || (m = at(SH_DOUBLE, src, i))) {
|
|
2193
|
+
emit2(m, "string");
|
|
2194
|
+
i += m.length;
|
|
2195
|
+
command = false;
|
|
2196
|
+
continue;
|
|
2197
|
+
}
|
|
2198
|
+
if (m = at(SH_OPERATOR, src, i)) {
|
|
2199
|
+
emit2(m);
|
|
2200
|
+
i += m.length;
|
|
2201
|
+
command = m !== ")" && m !== ">" && m !== "<";
|
|
2202
|
+
continue;
|
|
2203
|
+
}
|
|
2204
|
+
if (m = at(SH_VAR, src, i)) {
|
|
2205
|
+
emit2(m, "type");
|
|
2206
|
+
i += m.length;
|
|
2207
|
+
command = false;
|
|
2208
|
+
continue;
|
|
2209
|
+
}
|
|
2210
|
+
if (m = at(SH_URL, src, i)) {
|
|
2211
|
+
emit2(m, "url");
|
|
2212
|
+
i += m.length;
|
|
2213
|
+
command = false;
|
|
2214
|
+
continue;
|
|
2215
|
+
}
|
|
2216
|
+
if (command && (m = at(SH_ASSIGN, src, i))) {
|
|
2217
|
+
emit2(m, "property");
|
|
2218
|
+
i += m.length;
|
|
2219
|
+
const v = at(SH_VALUE, src, i);
|
|
2220
|
+
emit2(v);
|
|
2221
|
+
i += v.length;
|
|
2222
|
+
continue;
|
|
2223
|
+
}
|
|
2224
|
+
if ((m = at(SH_FLAG, src, i)) && !command) {
|
|
2225
|
+
emit2(m, "keyword");
|
|
2226
|
+
i += m.length;
|
|
2227
|
+
continue;
|
|
2228
|
+
}
|
|
2229
|
+
if (m = at(SH_WORD, src, i)) {
|
|
2230
|
+
if (command && SH_KEYWORDS.has(m)) emit2(m, "keyword");
|
|
2231
|
+
else if (command) {
|
|
2232
|
+
emit2(m, "function");
|
|
2233
|
+
command = m === "sudo" || m === "npx" || m === "env" || m === "time";
|
|
2234
|
+
i += m.length;
|
|
2235
|
+
continue;
|
|
2236
|
+
} else emit2(m);
|
|
2237
|
+
i += m.length;
|
|
2238
|
+
continue;
|
|
2239
|
+
}
|
|
2240
|
+
emit2(src[i]);
|
|
2241
|
+
i++;
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
var PY_KEYWORDS = new Set(
|
|
2245
|
+
"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(" ")
|
|
2246
|
+
);
|
|
2247
|
+
var PY_CONSTANTS = /* @__PURE__ */ new Set(["True", "False", "None"]);
|
|
2248
|
+
var PY_TYPES = /* @__PURE__ */ new Set(["int", "str", "bool", "float", "bytes", "list", "dict", "tuple", "set", "object"]);
|
|
2249
|
+
var PY_COMMENT = /#[^\n]*/y;
|
|
2250
|
+
var PY_TRIPLE = /[rRbBuUfF]{0,2}(?:"""[\s\S]*?(?:"""|$)|'''[\s\S]*?(?:'''|$))/y;
|
|
2251
|
+
var PY_STRING = /[rRbBuUfF]{0,2}(?:'(?:\\.|[^\\'\n])*'?|"(?:\\.|[^\\"\n])*"?)/y;
|
|
2252
|
+
var PY_NUMBER = /(?:0[xX][\da-fA-F_]+|\d[\d_]*(?:\.[\d_]*)?(?:[eE][+-]?\d+)?j?)/y;
|
|
2253
|
+
var PY_IDENT = /[A-Za-z_]\w*/y;
|
|
2254
|
+
var PY_DECORATOR = /@[A-Za-z_][\w.]*/y;
|
|
2255
|
+
var PY_CALL_AFTER = /\s*\(/y;
|
|
2256
|
+
function scanPython(src, emit2) {
|
|
2257
|
+
let i = 0;
|
|
2258
|
+
let prev = "";
|
|
2259
|
+
while (i < src.length) {
|
|
2260
|
+
let m;
|
|
2261
|
+
if ((m = at(WS, src, i)) || (m = at(NEWLINE, src, i))) {
|
|
2262
|
+
emit2(m);
|
|
2263
|
+
i += m.length;
|
|
2264
|
+
continue;
|
|
2265
|
+
}
|
|
2266
|
+
if (m = at(PY_COMMENT, src, i)) {
|
|
2267
|
+
emit2(m, "comment");
|
|
2268
|
+
} else if ((m = at(PY_TRIPLE, src, i)) || (m = at(PY_STRING, src, i))) {
|
|
2269
|
+
if (/^[A-Za-z]+$/.test(m)) {
|
|
2270
|
+
emit2(m);
|
|
2271
|
+
} else emit2(m, "string");
|
|
2272
|
+
prev = '"';
|
|
2273
|
+
} else if (m = at(PY_DECORATOR, src, i)) {
|
|
2274
|
+
emit2(m, "function");
|
|
2275
|
+
prev = "@";
|
|
2276
|
+
} else if (m = at(PY_IDENT, src, i)) {
|
|
2277
|
+
let kind;
|
|
2278
|
+
if (PY_CONSTANTS.has(m)) kind = "number";
|
|
2279
|
+
else if (prev !== "." && PY_KEYWORDS.has(m)) kind = "keyword";
|
|
2280
|
+
else if (prev === "def" || at(PY_CALL_AFTER, src, i + m.length) !== null) kind = "function";
|
|
2281
|
+
else if (prev === "class" || /^[A-Z][a-z]/.test(m) || PY_TYPES.has(m)) kind = "type";
|
|
2282
|
+
else if (isConstant(m)) kind = "number";
|
|
2283
|
+
emit2(m, kind);
|
|
2284
|
+
prev = kind === "keyword" ? m : "id";
|
|
2285
|
+
} else if (m = at(PY_NUMBER, src, i)) {
|
|
2286
|
+
emit2(m, "number");
|
|
2287
|
+
prev = "0";
|
|
2288
|
+
} else {
|
|
2289
|
+
m = src[i];
|
|
2290
|
+
emit2(m);
|
|
2291
|
+
prev = m;
|
|
2292
|
+
}
|
|
2293
|
+
i += m.length;
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
var YAML_KEY = /[ \t]*(?:- )?[\w.$/-]+(?=[ \t]*:(?:\s|$))/y;
|
|
2297
|
+
var YAML_VALUE_WORD = /(?:true|false|null|yes|no|~|-?\d+(?:\.\d+)?)(?=\s*(?:#|$))/y;
|
|
2298
|
+
function scanYaml(src, emit2) {
|
|
2299
|
+
let i = 0;
|
|
2300
|
+
let lineStart = true;
|
|
2301
|
+
while (i < src.length) {
|
|
2302
|
+
let m;
|
|
2303
|
+
if (m = at(NEWLINE, src, i)) {
|
|
2304
|
+
emit2(m);
|
|
2305
|
+
i += m.length;
|
|
2306
|
+
lineStart = true;
|
|
2307
|
+
continue;
|
|
2308
|
+
}
|
|
2309
|
+
if (lineStart && (m = at(YAML_KEY, src, i))) {
|
|
2310
|
+
const dash = m.match(/^([ \t]*(?:- )?)/)[1];
|
|
2311
|
+
emit2(dash);
|
|
2312
|
+
emit2(m.slice(dash.length), "property");
|
|
2313
|
+
i += m.length;
|
|
2314
|
+
lineStart = false;
|
|
2315
|
+
continue;
|
|
2316
|
+
}
|
|
2317
|
+
lineStart = false;
|
|
2318
|
+
if ((m = at(SH_COMMENT, src, i)) && (i === 0 || /\s/.test(src[i - 1]))) emit2(m, "comment");
|
|
2319
|
+
else if ((m = at(SH_SINGLE, src, i)) || (m = at(JSON_STRING, src, i))) emit2(m, "string");
|
|
2320
|
+
else if (m = at(YAML_VALUE_WORD, src, i)) emit2(m, "number");
|
|
2321
|
+
else if (m = at(SH_URL, src, i)) emit2(m, "url");
|
|
2322
|
+
else {
|
|
2323
|
+
m = src[i];
|
|
2324
|
+
emit2(m);
|
|
2325
|
+
}
|
|
2326
|
+
i += m.length;
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2329
|
+
function toLines(tokens) {
|
|
2330
|
+
const lines = [[]];
|
|
2331
|
+
for (const t of tokens) {
|
|
2332
|
+
const parts = t.text.split(/\r?\n/);
|
|
2333
|
+
parts.forEach((part, j) => {
|
|
2334
|
+
if (j > 0) lines.push([]);
|
|
2335
|
+
if (part) lines[lines.length - 1].push(t.kind ? { text: part, kind: t.kind } : { text: part });
|
|
2336
|
+
});
|
|
2337
|
+
}
|
|
2338
|
+
return lines;
|
|
2339
|
+
}
|
|
2340
|
+
function highlight(code, lang) {
|
|
2341
|
+
const src = code.replace(/\r?\n$/, "");
|
|
2342
|
+
const grammar = grammarOf(lang);
|
|
2343
|
+
const { emit: emit2, tokens } = collector();
|
|
2344
|
+
const name = (lang ?? "").toLowerCase();
|
|
2345
|
+
switch (grammar) {
|
|
2346
|
+
case "js":
|
|
2347
|
+
scanJs(src, emit2, name === "tsx" || name === "jsx");
|
|
2348
|
+
break;
|
|
2349
|
+
case "json":
|
|
2350
|
+
scanJson(src, emit2);
|
|
2351
|
+
break;
|
|
2352
|
+
case "shell":
|
|
2353
|
+
scanShell(src, emit2);
|
|
2354
|
+
break;
|
|
2355
|
+
case "python":
|
|
2356
|
+
scanPython(src, emit2);
|
|
2357
|
+
break;
|
|
2358
|
+
case "yaml":
|
|
2359
|
+
scanYaml(src, emit2);
|
|
2360
|
+
break;
|
|
2361
|
+
default:
|
|
2362
|
+
emit2(src);
|
|
2363
|
+
}
|
|
2364
|
+
return toLines(tokens);
|
|
2365
|
+
}
|
|
2366
|
+
function readDiff(code) {
|
|
2367
|
+
const diff = /* @__PURE__ */ new Map();
|
|
2368
|
+
const lines = code.replace(/\r?\n$/, "").split(/\r?\n/);
|
|
2369
|
+
const out = lines.map((line, i) => {
|
|
2370
|
+
const c = line[0];
|
|
2371
|
+
if (c === "+" || c === "-") {
|
|
2372
|
+
diff.set(i + 1, c === "+" ? "add" : "remove");
|
|
2373
|
+
return line.slice(1);
|
|
2374
|
+
}
|
|
2375
|
+
return c === " " ? line.slice(1) : line;
|
|
2376
|
+
});
|
|
2377
|
+
return { code: out.join("\n"), diff };
|
|
2378
|
+
}
|
|
2379
|
+
function parseLineRanges(spec) {
|
|
2380
|
+
if (!spec) return /* @__PURE__ */ new Set();
|
|
2381
|
+
if (typeof spec !== "string") return new Set(spec);
|
|
2382
|
+
const out = /* @__PURE__ */ new Set();
|
|
2383
|
+
for (const part of spec.split(",")) {
|
|
2384
|
+
const m = part.trim().match(/^(\d+)(?:\s*-\s*(\d+))?$/);
|
|
2385
|
+
if (!m) continue;
|
|
2386
|
+
const a = Number(m[1]);
|
|
2387
|
+
const b = m[2] ? Number(m[2]) : a;
|
|
2388
|
+
for (let n = Math.min(a, b); n <= Math.max(a, b) && n - a < 1e4; n++) out.add(n);
|
|
2389
|
+
}
|
|
2390
|
+
return out;
|
|
2391
|
+
}
|
|
2392
|
+
function parseCodeMeta(meta) {
|
|
2393
|
+
if (!meta) return {};
|
|
2394
|
+
const out = {};
|
|
2395
|
+
const title = meta.match(/(?:title|filename)=(?:"([^"]*)"|'([^']*)'|(\S+))/);
|
|
2396
|
+
if (title) out.title = title[1] ?? title[2] ?? title[3];
|
|
2397
|
+
const lines = meta.match(/\{([\d,\s-]+)\}/);
|
|
2398
|
+
if (lines) out.highlight = lines[1].replace(/\s+/g, "");
|
|
2399
|
+
const rest = meta.replace(/(?:title|filename)=(?:"[^"]*"|'[^']*'|\S+)/, "");
|
|
2400
|
+
if (/\bdiff\b/.test(rest)) out.diff = true;
|
|
2401
|
+
if (/\b(?:showLineNumbers|lineNumbers|numbers)\b/.test(rest)) out.lineNumbers = true;
|
|
2402
|
+
return out;
|
|
2403
|
+
}
|
|
2404
|
+
var ESCAPE = { "&": "&", "<": "<", ">": ">", '"': """ };
|
|
2405
|
+
function escapeHtml(s) {
|
|
2406
|
+
return s.replace(/[&<>"]/g, (c) => ESCAPE[c]);
|
|
2407
|
+
}
|
|
2408
|
+
function linesToHtml(lines, marks = {}) {
|
|
2409
|
+
return lines.map((line, i) => {
|
|
2410
|
+
const n = i + 1;
|
|
2411
|
+
const attrs = [
|
|
2412
|
+
'data-line=""',
|
|
2413
|
+
marks.highlight?.has(n) ? 'data-mark=""' : "",
|
|
2414
|
+
marks.diff?.has(n) ? `data-diff="${marks.diff.get(n)}"` : ""
|
|
2415
|
+
].filter(Boolean).join(" ");
|
|
2416
|
+
const body = line.map((t) => t.kind ? `<span class="${TOKEN_CLASS[t.kind]}">${escapeHtml(t.text)}</span>` : escapeHtml(t.text)).join("");
|
|
2417
|
+
return `<span ${attrs}>${body}</span>`;
|
|
2418
|
+
}).join("\n");
|
|
2419
|
+
}
|
|
2420
|
+
function highlightToHtml(code, lang, opts = {}) {
|
|
2421
|
+
const d = opts.diff ? readDiff(code) : null;
|
|
2422
|
+
return linesToHtml(highlight(d ? d.code : code, lang), {
|
|
2423
|
+
highlight: parseLineRanges(opts.highlight),
|
|
2424
|
+
diff: d?.diff
|
|
2425
|
+
});
|
|
2426
|
+
}
|
|
2427
|
+
|
|
2428
|
+
// src/format/index.ts
|
|
2429
|
+
var EXPLORER = "https://mempool.space";
|
|
2430
|
+
function explorerUrl(kind, value, network = "mainnet") {
|
|
2431
|
+
const net = network === "mainnet" ? "" : `/${network}`;
|
|
2432
|
+
return `${EXPLORER}${net}/${kind}/${encodeURIComponent(String(value))}`;
|
|
2433
|
+
}
|
|
2434
|
+
function shortenMiddle(value, head = 8, tail = 6) {
|
|
2435
|
+
return value.length <= head + tail + 1 ? value : `${value.slice(0, head)}\u2026${value.slice(-tail)}`;
|
|
2436
|
+
}
|
|
2437
|
+
function formatBlockHeight(height) {
|
|
2438
|
+
return Math.trunc(height).toLocaleString("en-US");
|
|
2439
|
+
}
|
|
2440
|
+
function blocksToDuration(blocks, minutesPerBlock = 10) {
|
|
2441
|
+
const minutes = Math.max(0, Math.round(blocks * minutesPerBlock));
|
|
2442
|
+
if (minutes < 60) return `about ${minutes} minute${minutes === 1 ? "" : "s"}`;
|
|
2443
|
+
const units = [
|
|
2444
|
+
[60 * 24 * 7, "week"],
|
|
2445
|
+
[60 * 24, "day"],
|
|
2446
|
+
[60, "hour"],
|
|
2447
|
+
[1, "minute"]
|
|
2448
|
+
];
|
|
2449
|
+
const parts = [];
|
|
2450
|
+
let rest = minutes;
|
|
2451
|
+
for (const [size, word] of units) {
|
|
2452
|
+
const n = Math.floor(rest / size);
|
|
2453
|
+
if (n > 0 && parts.length < 2) {
|
|
2454
|
+
parts.push(`${n} ${word}${n === 1 ? "" : "s"}`);
|
|
2455
|
+
rest -= n * size;
|
|
2456
|
+
} else if (parts.length > 0) break;
|
|
2457
|
+
}
|
|
2458
|
+
return `about ${parts.join(" ")}`;
|
|
2459
|
+
}
|
|
2460
|
+
var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
2461
|
+
function formatUtc(at2, opts = {}) {
|
|
2462
|
+
const d = typeof at2 === "number" ? new Date(at2 * 1e3) : new Date(at2);
|
|
2463
|
+
if (Number.isNaN(d.getTime())) return "\u2014";
|
|
2464
|
+
const day = `${d.getUTCDate()} ${MONTHS[d.getUTCMonth()]} ${d.getUTCFullYear()}`;
|
|
2465
|
+
if (opts.date) return day;
|
|
2466
|
+
const hh = String(d.getUTCHours()).padStart(2, "0");
|
|
2467
|
+
const mm = String(d.getUTCMinutes()).padStart(2, "0");
|
|
2468
|
+
return `${day}, ${hh}:${mm} UTC`;
|
|
2469
|
+
}
|
|
2470
|
+
function formatBytes(bytes) {
|
|
2471
|
+
if (!Number.isFinite(bytes) || bytes < 0) return "\u2014";
|
|
2472
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
2473
|
+
const units = ["KB", "MB", "GB", "TB"];
|
|
2474
|
+
let v = bytes / 1024;
|
|
2475
|
+
let u = 0;
|
|
2476
|
+
while (v >= 1024 && u < units.length - 1) {
|
|
2477
|
+
v /= 1024;
|
|
2478
|
+
u++;
|
|
2479
|
+
}
|
|
2480
|
+
return `${v < 10 ? v.toFixed(1).replace(/\.0$/, "") : Math.round(v)} ${units[u]}`;
|
|
2481
|
+
}
|
|
2482
|
+
var ShellContext = sharedContext("shell-place", {});
|
|
1882
2483
|
function useShellPlace() {
|
|
1883
2484
|
return react.useContext(ShellContext);
|
|
1884
2485
|
}
|
|
@@ -1901,26 +2502,30 @@ function PageHeader({
|
|
|
1901
2502
|
] });
|
|
1902
2503
|
}
|
|
1903
2504
|
var InStatGrid = react.createContext(false);
|
|
1904
|
-
function StatCard({ label, value, hint, className }) {
|
|
2505
|
+
function StatCard({ label, value, hint, size, className }) {
|
|
1905
2506
|
const inGrid = react.useContext(InStatGrid);
|
|
2507
|
+
const density = useDensity();
|
|
2508
|
+
const sm = (size ?? (density === "compact" ? "sm" : "md")) === "sm";
|
|
1906
2509
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1907
2510
|
"div",
|
|
1908
2511
|
{
|
|
1909
2512
|
"data-ui": "stat",
|
|
1910
2513
|
className: cn(
|
|
1911
|
-
"
|
|
2514
|
+
"border border-border bg-card",
|
|
2515
|
+
sm ? "rounded-2xl p-4" : "rounded-[1.25rem] p-5 md:p-6",
|
|
1912
2516
|
// In a grid, label, value and hint each share a row with their
|
|
1913
2517
|
// neighbours, so values line up whatever wraps above them.
|
|
1914
2518
|
inGrid ? "row-span-3 grid grid-rows-subgrid gap-1.5" : "flex flex-col gap-2",
|
|
1915
2519
|
className
|
|
1916
2520
|
),
|
|
1917
2521
|
children: [
|
|
1918
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.
|
|
2522
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("leading-snug text-muted-foreground", sm ? "text-[0.8125rem]" : "text-[0.875rem]"), children: label }),
|
|
1919
2523
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1920
2524
|
"span",
|
|
1921
2525
|
{
|
|
1922
2526
|
className: cn(
|
|
1923
|
-
"break-words oca-tabular
|
|
2527
|
+
"break-words oca-tabular leading-tight tracking-[-0.02em]",
|
|
2528
|
+
sm ? "text-[1.25rem]" : "text-[1.5rem] md:text-[1.75rem]",
|
|
1924
2529
|
inGrid && "self-end"
|
|
1925
2530
|
),
|
|
1926
2531
|
children: value
|
|
@@ -1982,6 +2587,7 @@ function StatGrid({ columns, empty, isEmpty, className, children, ...props }) {
|
|
|
1982
2587
|
const items = react.Children.toArray(children).filter(react.isValidElement);
|
|
1983
2588
|
const n = items.length;
|
|
1984
2589
|
const allZero = n > 0 && items.every((el) => "raw" in el.props && (el.props.raw === 0 || el.props.raw === null));
|
|
2590
|
+
const compact = useDensity() === "compact";
|
|
1985
2591
|
if (isEmpty ?? allZero) return /* @__PURE__ */ jsxRuntime.jsx(EmptyLine, { className, children: empty ?? "Nothing here yet." });
|
|
1986
2592
|
const lg = columns ?? statColumns(n);
|
|
1987
2593
|
const md = lg > 4 ? 3 : lg;
|
|
@@ -1991,7 +2597,8 @@ function StatGrid({ columns, empty, isEmpty, className, children, ...props }) {
|
|
|
1991
2597
|
"div",
|
|
1992
2598
|
{
|
|
1993
2599
|
className: cn(
|
|
1994
|
-
"grid
|
|
2600
|
+
"grid",
|
|
2601
|
+
compact ? "gap-2.5 md:gap-3" : "gap-3 md:gap-4",
|
|
1995
2602
|
n === 1 ? "grid-cols-1" : "grid-cols-2",
|
|
1996
2603
|
MD_COLS[md],
|
|
1997
2604
|
LG_COLS[lg],
|
|
@@ -2010,11 +2617,40 @@ function StatGrid({ columns, empty, isEmpty, className, children, ...props }) {
|
|
|
2010
2617
|
}
|
|
2011
2618
|
) });
|
|
2012
2619
|
}
|
|
2013
|
-
function KeyValueList({
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2620
|
+
function KeyValueList({
|
|
2621
|
+
items,
|
|
2622
|
+
dense,
|
|
2623
|
+
className
|
|
2624
|
+
}) {
|
|
2625
|
+
const density = useDensity();
|
|
2626
|
+
const tight = dense ?? density === "compact";
|
|
2627
|
+
return (
|
|
2628
|
+
// The rows go side by side when the list itself is wide enough, wherever it sits: a narrow card stacks them.
|
|
2629
|
+
/* @__PURE__ */ jsxRuntime.jsx("dl", { className: cn("@container divide-y divide-border border border-border bg-card", tight ? "rounded-2xl" : "rounded-[1.25rem]", className), children: items.map((it, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2630
|
+
"div",
|
|
2631
|
+
{
|
|
2632
|
+
className: cn(
|
|
2633
|
+
"flex flex-col gap-1 @md:flex-row @md:items-baseline",
|
|
2634
|
+
tight ? "px-4 py-2.5 @md:gap-5" : "px-5 py-3.5 @md:gap-6"
|
|
2635
|
+
),
|
|
2636
|
+
children: [
|
|
2637
|
+
/* @__PURE__ */ jsxRuntime.jsx("dt", { className: cn("shrink-0 text-muted-foreground", tight ? "text-[0.8125rem] @md:w-36" : "text-[0.875rem] @md:w-48"), children: it.label }),
|
|
2638
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2639
|
+
"dd",
|
|
2640
|
+
{
|
|
2641
|
+
className: cn(
|
|
2642
|
+
"min-w-0 break-words",
|
|
2643
|
+
tight ? "text-[0.875rem]" : "text-[0.9375rem]",
|
|
2644
|
+
it.mono && (tight ? "font-mono text-[0.8125rem]" : "font-mono text-[0.875rem]")
|
|
2645
|
+
),
|
|
2646
|
+
children: it.value
|
|
2647
|
+
}
|
|
2648
|
+
)
|
|
2649
|
+
]
|
|
2650
|
+
},
|
|
2651
|
+
i
|
|
2652
|
+
)) })
|
|
2653
|
+
);
|
|
2018
2654
|
}
|
|
2019
2655
|
function DataTable({
|
|
2020
2656
|
columns,
|
|
@@ -2023,8 +2659,11 @@ function DataTable({
|
|
|
2023
2659
|
empty,
|
|
2024
2660
|
caption,
|
|
2025
2661
|
phone = "cards",
|
|
2662
|
+
dense,
|
|
2026
2663
|
className
|
|
2027
2664
|
}) {
|
|
2665
|
+
const density = useDensity();
|
|
2666
|
+
const tight = dense ?? density === "compact";
|
|
2028
2667
|
if (rows.length === 0 && empty) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: empty });
|
|
2029
2668
|
const primary = columns.find((c) => c.primary) ?? columns[0];
|
|
2030
2669
|
const right = (c) => c.numeric || c.align === "end";
|
|
@@ -2032,11 +2671,12 @@ function DataTable({
|
|
|
2032
2671
|
"div",
|
|
2033
2672
|
{
|
|
2034
2673
|
className: cn(
|
|
2035
|
-
"overflow-hidden
|
|
2674
|
+
"overflow-hidden border border-border bg-card",
|
|
2675
|
+
tight ? "rounded-2xl" : "rounded-[1.25rem]",
|
|
2036
2676
|
phone === "cards" && "max-sm:hidden",
|
|
2037
2677
|
className
|
|
2038
2678
|
),
|
|
2039
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full border-collapse text-left text-[0.9375rem]", children: [
|
|
2679
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: cn("w-full border-collapse text-left", tight ? "text-[0.875rem]" : "text-[0.9375rem]"), children: [
|
|
2040
2680
|
caption ? /* @__PURE__ */ jsxRuntime.jsx("caption", { className: "sr-only", children: caption }) : null,
|
|
2041
2681
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "border-b border-border", children: columns.map((c) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2042
2682
|
"th",
|
|
@@ -2044,7 +2684,8 @@ function DataTable({
|
|
|
2044
2684
|
scope: "col",
|
|
2045
2685
|
style: { width: c.width, minWidth: c.minWidth },
|
|
2046
2686
|
className: cn(
|
|
2047
|
-
"whitespace-nowrap
|
|
2687
|
+
"whitespace-nowrap text-[0.8125rem] font-medium text-muted-foreground",
|
|
2688
|
+
tight ? "px-4 py-2.5" : "px-5 py-3",
|
|
2048
2689
|
right(c) && "text-right",
|
|
2049
2690
|
c.wide && "hidden md:table-cell"
|
|
2050
2691
|
),
|
|
@@ -2057,7 +2698,8 @@ function DataTable({
|
|
|
2057
2698
|
{
|
|
2058
2699
|
style: { minWidth: c.minWidth },
|
|
2059
2700
|
className: cn(
|
|
2060
|
-
"
|
|
2701
|
+
"align-middle",
|
|
2702
|
+
tight ? "px-4 py-2" : "px-5 py-3.5",
|
|
2061
2703
|
right(c) && "text-right",
|
|
2062
2704
|
c.numeric && "whitespace-nowrap oca-tabular",
|
|
2063
2705
|
c.wide && "hidden md:table-cell"
|
|
@@ -2077,8 +2719,12 @@ function DataTable({
|
|
|
2077
2719
|
"ul",
|
|
2078
2720
|
{
|
|
2079
2721
|
"aria-label": caption,
|
|
2080
|
-
className: cn(
|
|
2081
|
-
|
|
2722
|
+
className: cn(
|
|
2723
|
+
"divide-y divide-border border border-border bg-card sm:hidden",
|
|
2724
|
+
tight ? "rounded-2xl" : "rounded-[1.25rem]",
|
|
2725
|
+
className
|
|
2726
|
+
),
|
|
2727
|
+
children: rows.map((r, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: cn("flex flex-col gap-2.5 px-4", tight ? "py-3" : "py-4"), children: [
|
|
2082
2728
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 break-words text-[0.9375rem] font-medium", children: primary?.cell(r) }),
|
|
2083
2729
|
rest.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("dl", { className: "grid grid-cols-[minmax(5.5rem,auto)_minmax(0,1fr)] gap-x-4 gap-y-1.5 text-[0.875rem]", children: rest.map((c) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "contents", children: [
|
|
2084
2730
|
/* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-muted-foreground", children: c.header }),
|
|
@@ -2125,13 +2771,14 @@ function Notice({
|
|
|
2125
2771
|
title,
|
|
2126
2772
|
children,
|
|
2127
2773
|
action,
|
|
2774
|
+
role,
|
|
2128
2775
|
className
|
|
2129
2776
|
}) {
|
|
2130
2777
|
const kind = NOTICE_KIND[tone];
|
|
2131
2778
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2132
2779
|
"div",
|
|
2133
2780
|
{
|
|
2134
|
-
role: tone === "danger" || tone === "warning" ? "alert" : "note",
|
|
2781
|
+
role: role ?? (tone === "danger" || tone === "warning" ? "alert" : "note"),
|
|
2135
2782
|
"data-tone": kind,
|
|
2136
2783
|
className: cn(
|
|
2137
2784
|
"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",
|
|
@@ -2181,45 +2828,66 @@ function LoadingBlock({
|
|
|
2181
2828
|
}
|
|
2182
2829
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "status", "aria-label": label, className: cn("flex flex-col gap-3", className), children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-16 rounded-2xl" }, i)) });
|
|
2183
2830
|
}
|
|
2184
|
-
function
|
|
2185
|
-
|
|
2831
|
+
async function wipeIfUnchanged(expected) {
|
|
2832
|
+
try {
|
|
2833
|
+
if (await navigator.clipboard.readText() !== expected) return;
|
|
2834
|
+
} catch {
|
|
2835
|
+
}
|
|
2836
|
+
try {
|
|
2837
|
+
await navigator.clipboard.writeText("");
|
|
2838
|
+
} catch {
|
|
2839
|
+
}
|
|
2186
2840
|
}
|
|
2187
2841
|
function useCopy(timeoutMs = 1600) {
|
|
2188
2842
|
const [copied, setCopied] = react.useState(false);
|
|
2189
2843
|
const t = react.useRef(null);
|
|
2190
|
-
react.
|
|
2191
|
-
|
|
2192
|
-
|
|
2844
|
+
const wipe = react.useRef(null);
|
|
2845
|
+
react.useEffect(
|
|
2846
|
+
() => () => {
|
|
2847
|
+
if (t.current) clearTimeout(t.current);
|
|
2848
|
+
},
|
|
2849
|
+
[]
|
|
2850
|
+
);
|
|
2193
2851
|
const copy = react.useCallback(
|
|
2194
|
-
async (text) => {
|
|
2852
|
+
async (text, opts = {}) => {
|
|
2195
2853
|
try {
|
|
2196
2854
|
await navigator.clipboard.writeText(text);
|
|
2197
2855
|
setCopied(true);
|
|
2198
2856
|
if (t.current) clearTimeout(t.current);
|
|
2199
2857
|
t.current = setTimeout(() => setCopied(false), timeoutMs);
|
|
2858
|
+
if (opts.clearAfter && opts.clearAfter > 0) {
|
|
2859
|
+
if (wipe.current) clearTimeout(wipe.current);
|
|
2860
|
+
wipe.current = setTimeout(() => void wipeIfUnchanged(text), opts.clearAfter);
|
|
2861
|
+
}
|
|
2862
|
+
return true;
|
|
2200
2863
|
} catch {
|
|
2201
2864
|
setCopied(false);
|
|
2865
|
+
return false;
|
|
2202
2866
|
}
|
|
2203
2867
|
},
|
|
2204
2868
|
[timeoutMs]
|
|
2205
2869
|
);
|
|
2206
2870
|
return { copied, copy };
|
|
2207
2871
|
}
|
|
2208
|
-
function CopyButton({ value, label = "Copy", className }) {
|
|
2872
|
+
function CopyButton({ value, label = "Copy", clearAfter, onCopied, className }) {
|
|
2209
2873
|
const { copied, copy } = useCopy();
|
|
2874
|
+
const done2 = copied ? clearAfter ? `Copied. Cleared in ${Math.round(clearAfter / 1e3)} seconds` : "Copied" : "";
|
|
2210
2875
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2211
2876
|
"button",
|
|
2212
2877
|
{
|
|
2213
2878
|
type: "button",
|
|
2214
|
-
onClick: () =>
|
|
2879
|
+
onClick: async () => {
|
|
2880
|
+
if (await copy(typeof value === "function" ? value() : value, { clearAfter })) onCopied?.();
|
|
2881
|
+
},
|
|
2215
2882
|
"aria-label": copied ? "Copied" : label,
|
|
2883
|
+
title: label,
|
|
2216
2884
|
className: cn(
|
|
2217
2885
|
"inline-flex size-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
|
|
2218
2886
|
className
|
|
2219
2887
|
),
|
|
2220
2888
|
children: [
|
|
2221
2889
|
copied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "size-4 text-success" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "size-4" }),
|
|
2222
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-live": "polite", className: "sr-only", children:
|
|
2890
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-live": "polite", className: "sr-only", children: done2 })
|
|
2223
2891
|
]
|
|
2224
2892
|
}
|
|
2225
2893
|
);
|
|
@@ -2230,12 +2898,27 @@ function HashChip({
|
|
|
2230
2898
|
tail = 6,
|
|
2231
2899
|
copy = true,
|
|
2232
2900
|
href,
|
|
2901
|
+
explorer,
|
|
2902
|
+
network = "mainnet",
|
|
2233
2903
|
className
|
|
2234
2904
|
}) {
|
|
2235
|
-
const shown =
|
|
2905
|
+
const shown = shortenMiddle(value, head, tail);
|
|
2906
|
+
const link = href ?? (explorer ? explorerUrl(explorer, value, network) : void 0);
|
|
2907
|
+
const offsite = !!link && /^https?:\/\//.test(link);
|
|
2236
2908
|
const text = /* @__PURE__ */ jsxRuntime.jsx("span", { title: value, className: "font-mono text-[0.875rem]", children: shown });
|
|
2237
2909
|
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("inline-flex max-w-full items-center gap-1", className), children: [
|
|
2238
|
-
|
|
2910
|
+
link ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2911
|
+
"a",
|
|
2912
|
+
{
|
|
2913
|
+
href: link,
|
|
2914
|
+
...offsite ? { target: "_blank", rel: "noreferrer" } : {},
|
|
2915
|
+
className: "underline decoration-foreground/35 underline-offset-4 hover:decoration-foreground",
|
|
2916
|
+
children: [
|
|
2917
|
+
text,
|
|
2918
|
+
offsite ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: " (opens in a new tab)" }) : null
|
|
2919
|
+
]
|
|
2920
|
+
}
|
|
2921
|
+
) : text,
|
|
2239
2922
|
copy ? /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value, label: "Copy full value" }) : null
|
|
2240
2923
|
] });
|
|
2241
2924
|
}
|
|
@@ -2289,96 +2972,269 @@ function ActivityList({ items, empty, className }) {
|
|
|
2289
2972
|
return /* @__PURE__ */ jsxRuntime.jsx("li", { children: it.href ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: it.href, className: "block transition-colors hover:bg-accent/60", children: body }) : body }, it.id);
|
|
2290
2973
|
}) });
|
|
2291
2974
|
}
|
|
2292
|
-
var
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2975
|
+
var LANG_NAME = {
|
|
2976
|
+
ts: "TypeScript",
|
|
2977
|
+
typescript: "TypeScript",
|
|
2978
|
+
tsx: "TSX",
|
|
2979
|
+
js: "JavaScript",
|
|
2980
|
+
javascript: "JavaScript",
|
|
2981
|
+
jsx: "JSX",
|
|
2982
|
+
mjs: "JavaScript",
|
|
2983
|
+
json: "JSON",
|
|
2984
|
+
jsonc: "JSON",
|
|
2985
|
+
bash: "Shell",
|
|
2986
|
+
sh: "Shell",
|
|
2987
|
+
shell: "Shell",
|
|
2988
|
+
zsh: "Shell",
|
|
2989
|
+
console: "Terminal",
|
|
2990
|
+
terminal: "Terminal",
|
|
2991
|
+
python: "Python",
|
|
2992
|
+
py: "Python",
|
|
2993
|
+
yaml: "YAML",
|
|
2994
|
+
yml: "YAML",
|
|
2995
|
+
diff: "Diff",
|
|
2996
|
+
text: "Text"
|
|
2296
2997
|
};
|
|
2297
|
-
function
|
|
2298
|
-
return
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2998
|
+
function languageName(lang) {
|
|
2999
|
+
return lang ? LANG_NAME[lang.toLowerCase()] ?? lang : void 0;
|
|
3000
|
+
}
|
|
3001
|
+
function forClipboard(text, lang) {
|
|
3002
|
+
if (grammarOf(lang) !== "shell") return text;
|
|
3003
|
+
const lines = text.split("\n");
|
|
3004
|
+
if (!lines.some((l) => l.startsWith("$ "))) return text;
|
|
3005
|
+
return lines.filter((l) => l.startsWith("$ ")).map((l) => l.slice(2)).join("\n");
|
|
3006
|
+
}
|
|
3007
|
+
function linesFromDom(pre) {
|
|
3008
|
+
if (!pre) return null;
|
|
3009
|
+
const lines = pre.querySelectorAll("[data-line]");
|
|
3010
|
+
if (lines.length === 0) return pre.textContent ?? "";
|
|
3011
|
+
return Array.from(lines).filter((l) => l.getAttribute("data-diff") !== "remove").map((l) => l.textContent ?? "").join("\n");
|
|
3012
|
+
}
|
|
3013
|
+
function prepare(code, lang, marks, diff) {
|
|
3014
|
+
const d = diff ? readDiff(code) : null;
|
|
3015
|
+
const src = d ? d.code : code.replace(/\r?\n$/, "");
|
|
3016
|
+
const lines = highlight(src, lang === "diff" ? void 0 : lang);
|
|
3017
|
+
const kept = d ? src.split("\n").filter((_, i) => d.diff.get(i + 1) !== "remove") : null;
|
|
3018
|
+
return {
|
|
3019
|
+
html: linesToHtml(lines, { highlight: parseLineRanges(marks), diff: d?.diff }),
|
|
3020
|
+
copy: kept ? kept.join("\n") : src,
|
|
3021
|
+
lines: lines.length,
|
|
3022
|
+
diff: !!d
|
|
3023
|
+
};
|
|
3024
|
+
}
|
|
3025
|
+
function Well({
|
|
3026
|
+
preRef,
|
|
3027
|
+
html,
|
|
3028
|
+
children,
|
|
3029
|
+
lang,
|
|
3030
|
+
lines,
|
|
3031
|
+
maxLines,
|
|
3032
|
+
diff,
|
|
3033
|
+
lineNumbers
|
|
3034
|
+
}) {
|
|
3035
|
+
const foldable = maxLines !== void 0 && lines > maxLines + 2;
|
|
3036
|
+
const [open, setOpen] = react.useState(false);
|
|
3037
|
+
const folded = foldable && !open;
|
|
3038
|
+
const lined = html !== void 0;
|
|
3039
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
3040
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3041
|
+
"div",
|
|
3042
|
+
{
|
|
3043
|
+
className: cn(folded && "overflow-hidden"),
|
|
3044
|
+
style: folded ? { maxHeight: `calc(${maxLines} * 1.625em + 2rem)` } : void 0,
|
|
3045
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--oca-code-surface)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3046
|
+
"pre",
|
|
3047
|
+
{
|
|
3048
|
+
ref: preRef,
|
|
3049
|
+
"data-diff": diff ? "" : void 0,
|
|
3050
|
+
"data-line-numbers": lineNumbers ? "" : void 0,
|
|
3051
|
+
className: cn(
|
|
3052
|
+
"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]",
|
|
3053
|
+
!lined && "px-5"
|
|
3054
|
+
),
|
|
3055
|
+
children: lined ? /* @__PURE__ */ jsxRuntime.jsx("code", { className: "block", "data-lang": lang, dangerouslySetInnerHTML: { __html: html } }) : /* @__PURE__ */ jsxRuntime.jsx("code", { className: "block", "data-lang": lang, children })
|
|
3056
|
+
}
|
|
3057
|
+
) })
|
|
3058
|
+
}
|
|
3059
|
+
),
|
|
3060
|
+
foldable ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3061
|
+
"div",
|
|
3062
|
+
{
|
|
3063
|
+
className: cn("flex justify-center px-5 pb-4", folded && "absolute inset-x-0 bottom-0 pt-16"),
|
|
3064
|
+
style: folded ? { background: "linear-gradient(to top, var(--oca-code-surface) 40%, transparent)" } : void 0,
|
|
3065
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3066
|
+
"button",
|
|
3067
|
+
{
|
|
3068
|
+
type: "button",
|
|
3069
|
+
onClick: () => setOpen((v) => !v),
|
|
3070
|
+
"aria-expanded": open,
|
|
3071
|
+
className: "rounded-full border border-white/20 px-4 py-1.5 text-[0.8125rem] text-white transition-colors hover:bg-white/10",
|
|
3072
|
+
children: open ? "Show less" : `Show all ${lines} lines`
|
|
3073
|
+
}
|
|
3074
|
+
)
|
|
3075
|
+
}
|
|
3076
|
+
) : null
|
|
3077
|
+
] });
|
|
2318
3078
|
}
|
|
3079
|
+
var FRAME = "overflow-hidden rounded-[1.25rem] border border-[var(--oca-code-line)] bg-[var(--oca-code-surface)]";
|
|
3080
|
+
var COPY_ON_INK = "text-oca-ink-subtle hover:bg-white/10 hover:text-white";
|
|
2319
3081
|
function CodeBlock({
|
|
2320
3082
|
code,
|
|
3083
|
+
html,
|
|
3084
|
+
children,
|
|
3085
|
+
lang,
|
|
2321
3086
|
caption,
|
|
2322
3087
|
copy = true,
|
|
3088
|
+
clearAfter,
|
|
2323
3089
|
maxLines,
|
|
3090
|
+
highlight: marks,
|
|
3091
|
+
diff,
|
|
3092
|
+
lineNumbers,
|
|
3093
|
+
actions,
|
|
2324
3094
|
className
|
|
2325
3095
|
}) {
|
|
2326
|
-
const
|
|
2327
|
-
const
|
|
2328
|
-
const
|
|
2329
|
-
const
|
|
3096
|
+
const preRef = react.useRef(null);
|
|
3097
|
+
const isDiff = diff || lang === "diff";
|
|
3098
|
+
const markKey = typeof marks === "string" ? marks : marks?.join(",");
|
|
3099
|
+
const prepared = react.useMemo(
|
|
3100
|
+
() => html === void 0 && children === void 0 && code !== void 0 ? prepare(code, lang, markKey, !!isDiff) : null,
|
|
3101
|
+
[code, html, children, lang, markKey, isDiff]
|
|
3102
|
+
);
|
|
3103
|
+
const markup = prepared?.html ?? html;
|
|
3104
|
+
const lines = prepared?.lines ?? (html !== void 0 ? html.split("\n").length : code?.split("\n").length ?? 0);
|
|
3105
|
+
const read = () => forClipboard(prepared?.copy ?? linesFromDom(preRef.current) ?? code ?? "", lang);
|
|
3106
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("figure", { className: cn(FRAME, className), children: [
|
|
3107
|
+
/* @__PURE__ */ jsxRuntime.jsxs("figcaption", { className: "flex h-11 items-center justify-between gap-3 border-b border-[var(--oca-code-line)] pl-5 pr-2", children: [
|
|
3108
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[0.8125rem] text-oca-ink-subtle", children: caption ?? languageName(lang) ?? "Code" }),
|
|
3109
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [
|
|
3110
|
+
actions,
|
|
3111
|
+
copy ? /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: read, label: "Copy code", clearAfter, className: COPY_ON_INK }) : null
|
|
3112
|
+
] })
|
|
3113
|
+
] }),
|
|
3114
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3115
|
+
Well,
|
|
3116
|
+
{
|
|
3117
|
+
preRef,
|
|
3118
|
+
html: markup,
|
|
3119
|
+
lang,
|
|
3120
|
+
lines,
|
|
3121
|
+
maxLines,
|
|
3122
|
+
diff: prepared ? prepared.diff : isDiff,
|
|
3123
|
+
lineNumbers,
|
|
3124
|
+
children
|
|
3125
|
+
}
|
|
3126
|
+
)
|
|
3127
|
+
] });
|
|
3128
|
+
}
|
|
3129
|
+
var tabListeners = /* @__PURE__ */ new Map();
|
|
3130
|
+
var tabMemory = /* @__PURE__ */ new Map();
|
|
3131
|
+
var storeKey = (k) => `oca-code-tab:${k}`;
|
|
3132
|
+
function readTab(key) {
|
|
3133
|
+
if (tabMemory.has(key)) return tabMemory.get(key);
|
|
3134
|
+
try {
|
|
3135
|
+
return window.localStorage.getItem(storeKey(key));
|
|
3136
|
+
} catch {
|
|
3137
|
+
return null;
|
|
3138
|
+
}
|
|
3139
|
+
}
|
|
3140
|
+
function writeTab(key, value) {
|
|
3141
|
+
tabMemory.set(key, value);
|
|
3142
|
+
try {
|
|
3143
|
+
window.localStorage.setItem(storeKey(key), value);
|
|
3144
|
+
} catch {
|
|
3145
|
+
}
|
|
3146
|
+
tabListeners.get(key)?.forEach((l) => l());
|
|
3147
|
+
}
|
|
3148
|
+
function useSyncedTab(key) {
|
|
3149
|
+
const subscribe2 = react.useCallback(
|
|
3150
|
+
(cb) => {
|
|
3151
|
+
if (!key) return () => {
|
|
3152
|
+
};
|
|
3153
|
+
const set = tabListeners.get(key) ?? /* @__PURE__ */ new Set();
|
|
3154
|
+
set.add(cb);
|
|
3155
|
+
tabListeners.set(key, set);
|
|
3156
|
+
return () => {
|
|
3157
|
+
set.delete(cb);
|
|
3158
|
+
};
|
|
3159
|
+
},
|
|
3160
|
+
[key]
|
|
3161
|
+
);
|
|
3162
|
+
const value = react.useSyncExternalStore(
|
|
3163
|
+
subscribe2,
|
|
3164
|
+
() => key ? readTab(key) : null,
|
|
3165
|
+
() => null
|
|
3166
|
+
);
|
|
3167
|
+
return [value, (v) => key && writeTab(key, v)];
|
|
3168
|
+
}
|
|
3169
|
+
function CodeTabs({
|
|
3170
|
+
items,
|
|
3171
|
+
syncKey,
|
|
3172
|
+
defaultValue,
|
|
3173
|
+
maxLines,
|
|
3174
|
+
className
|
|
3175
|
+
}) {
|
|
3176
|
+
const [synced, setSynced] = useSyncedTab(syncKey);
|
|
3177
|
+
const [local, setLocal] = react.useState(null);
|
|
3178
|
+
const labels = items.map((it) => it.label);
|
|
3179
|
+
const pick = [local, synced, defaultValue].find((v) => !!v && labels.includes(v)) ?? labels[0] ?? "";
|
|
3180
|
+
const active = items.find((it) => it.label === pick);
|
|
3181
|
+
const prepared = react.useMemo(() => items.map((it) => prepare(it.code, it.lang, void 0, it.lang === "diff")), [items]);
|
|
2330
3182
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2331
|
-
|
|
3183
|
+
TabsPrimitive__namespace.Root,
|
|
2332
3184
|
{
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
3185
|
+
value: pick,
|
|
3186
|
+
onValueChange: (v) => {
|
|
3187
|
+
setLocal(v);
|
|
3188
|
+
setSynced(v);
|
|
3189
|
+
},
|
|
3190
|
+
className: cn(FRAME, className),
|
|
2337
3191
|
children: [
|
|
2338
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
2339
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
2340
|
-
|
|
2341
|
-
CopyButton,
|
|
2342
|
-
{
|
|
2343
|
-
value: code,
|
|
2344
|
-
label: "Copy code",
|
|
2345
|
-
className: "text-oca-ink-subtle hover:bg-white/10 hover:text-white"
|
|
2346
|
-
}
|
|
2347
|
-
) : null
|
|
2348
|
-
] }),
|
|
2349
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
2350
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2351
|
-
"div",
|
|
2352
|
-
{
|
|
2353
|
-
className: cn(folded && "overflow-hidden"),
|
|
2354
|
-
style: folded ? { maxHeight: `calc(${maxLines} * 1.625em + 2.5rem)` } : void 0,
|
|
2355
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--oca-code-surface)", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "w-max min-w-full p-5 font-mono text-[0.875rem] leading-[1.625] text-oca-ink-muted [font-variant-ligatures:none]", children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: code }) }) })
|
|
2356
|
-
}
|
|
2357
|
-
),
|
|
2358
|
-
foldable ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2359
|
-
"div",
|
|
3192
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-11 items-center justify-between gap-3 border-b border-[var(--oca-code-line)] pl-2 pr-2", children: [
|
|
3193
|
+
/* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--oca-code-surface)", className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(TabsPrimitive__namespace.List, { "aria-label": "Versions", className: "flex w-max items-center gap-0.5", children: items.map((it) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3194
|
+
TabsPrimitive__namespace.Trigger,
|
|
2360
3195
|
{
|
|
3196
|
+
value: it.label,
|
|
2361
3197
|
className: cn(
|
|
2362
|
-
"flex
|
|
2363
|
-
|
|
3198
|
+
"relative inline-flex h-11 items-center whitespace-nowrap px-3 text-[0.8125rem] text-oca-ink-subtle outline-none transition-colors",
|
|
3199
|
+
"hover:text-white focus-visible:text-white focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
|
|
3200
|
+
"data-[state=active]:text-white",
|
|
3201
|
+
"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"
|
|
2364
3202
|
),
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
3203
|
+
children: it.label
|
|
3204
|
+
},
|
|
3205
|
+
it.label
|
|
3206
|
+
)) }) }),
|
|
3207
|
+
active ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3208
|
+
CopyButton,
|
|
3209
|
+
{
|
|
3210
|
+
value: () => forClipboard(prepared[items.indexOf(active)]?.copy ?? active.code, active.lang),
|
|
3211
|
+
label: `Copy ${active.label}`,
|
|
3212
|
+
className: COPY_ON_INK
|
|
2375
3213
|
}
|
|
2376
3214
|
) : null
|
|
2377
|
-
] })
|
|
3215
|
+
] }),
|
|
3216
|
+
items.map((it, i) => /* @__PURE__ */ jsxRuntime.jsx(TabsPrimitive__namespace.Content, { value: it.label, className: "outline-none", tabIndex: -1, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3217
|
+
Well,
|
|
3218
|
+
{
|
|
3219
|
+
html: prepared[i].html,
|
|
3220
|
+
lang: it.lang,
|
|
3221
|
+
lines: prepared[i].lines,
|
|
3222
|
+
maxLines,
|
|
3223
|
+
diff: prepared[i].diff
|
|
3224
|
+
}
|
|
3225
|
+
) }, it.label))
|
|
2378
3226
|
]
|
|
2379
3227
|
}
|
|
2380
3228
|
);
|
|
2381
3229
|
}
|
|
3230
|
+
function InstallTabs({ pkg, dev = false, className }) {
|
|
3231
|
+
const items = [
|
|
3232
|
+
{ label: "npm", code: `npm install ${dev ? "--save-dev " : ""}${pkg}`, lang: "bash" },
|
|
3233
|
+
{ label: "yarn", code: `yarn add ${dev ? "--dev " : ""}${pkg}`, lang: "bash" },
|
|
3234
|
+
{ label: "pnpm", code: `pnpm add ${dev ? "--save-dev " : ""}${pkg}`, lang: "bash" }
|
|
3235
|
+
];
|
|
3236
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CodeTabs, { items, syncKey: "package-manager", className });
|
|
3237
|
+
}
|
|
2382
3238
|
function SplitBar({
|
|
2383
3239
|
segments,
|
|
2384
3240
|
caption,
|
|
@@ -2763,7 +3619,7 @@ function ErrorPage({
|
|
|
2763
3619
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-lead oca-enter [--enter-delay:150ms]", children: detail ?? words.detail }),
|
|
2764
3620
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "oca-enter flex flex-wrap gap-3 [--enter-delay:230ms]", children: actions ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2765
3621
|
server ? /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => window.location.reload(), children: "Try again" }) : null,
|
|
2766
|
-
/* @__PURE__ */ jsxRuntime.jsx(Button, { asChild: true, variant: server ? "secondary" : "primary", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3622
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { asChild: true, variant: server ? "secondary" : "primary", children: /* @__PURE__ */ jsxRuntime.jsx(Link8__default.default, { href: home, children: "Go home" }) })
|
|
2767
3623
|
] }) })
|
|
2768
3624
|
] }),
|
|
2769
3625
|
art !== null ? /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": true, className: "oca-enter hidden justify-center md:col-span-5 md:flex [--enter-delay:120ms]", children: art ?? /* @__PURE__ */ jsxRuntime.jsx(MarkOutline, { className: "w-full max-w-[20rem] text-oca-hairline-strong" }) }) : null
|
|
@@ -2891,7 +3747,7 @@ function TextLink({
|
|
|
2891
3747
|
const internal = href.startsWith("/") && !href.startsWith("/api/") && !href.startsWith("/.well-known/");
|
|
2892
3748
|
const offsite = external ?? /^https?:\/\//.test(href);
|
|
2893
3749
|
if (internal && !offsite) {
|
|
2894
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3750
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Link8__default.default, { href, className: cn(LINK, className), children });
|
|
2895
3751
|
}
|
|
2896
3752
|
return /* @__PURE__ */ jsxRuntime.jsxs("a", { href, className: cn(LINK, className), ...offsite ? { target: "_blank", rel: "noreferrer" } : {}, children: [
|
|
2897
3753
|
children,
|
|
@@ -3079,7 +3935,8 @@ var FAMILY = [
|
|
|
3079
3935
|
group: "app",
|
|
3080
3936
|
line: "Builders find co-founders and backers.",
|
|
3081
3937
|
status: "testing",
|
|
3082
|
-
|
|
3938
|
+
// Signs in with an orangecheck account and a wallet; uses none of the six directly.
|
|
3939
|
+
protocols: []
|
|
3083
3940
|
},
|
|
3084
3941
|
{
|
|
3085
3942
|
slug: "me-demo",
|
|
@@ -3171,19 +4028,32 @@ function ProtocolGrid({
|
|
|
3171
4028
|
] }),
|
|
3172
4029
|
p.status !== "live" ? /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: p.status }) : null
|
|
3173
4030
|
] }),
|
|
3174
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "oca-display-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4031
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "oca-display-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4032
|
+
"a",
|
|
4033
|
+
{
|
|
4034
|
+
href: link === "tool" ? p.toolHref : link === "docs" ? `${DOCS_HREF}/${p.slug}` : p.pageHref,
|
|
4035
|
+
className: STRETCH,
|
|
4036
|
+
children: p.label
|
|
4037
|
+
}
|
|
4038
|
+
) }),
|
|
3175
4039
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-body", children: p.line }),
|
|
3176
4040
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-auto flex items-center justify-between gap-3 pt-2 text-[0.875rem] text-muted-foreground", children: [
|
|
3177
4041
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "oca-tabular", children: [
|
|
3178
4042
|
"Nostr kind ",
|
|
3179
4043
|
p.kinds
|
|
3180
4044
|
] }),
|
|
3181
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4045
|
+
link === "tool" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3182
4046
|
lucideReact.ArrowUpRight,
|
|
3183
4047
|
{
|
|
3184
4048
|
"aria-hidden": true,
|
|
3185
4049
|
className: "size-4 transition-transform duration-200 group-hover:-translate-y-0.5 group-hover:translate-x-0.5 group-hover:text-foreground"
|
|
3186
4050
|
}
|
|
4051
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
4052
|
+
lucideReact.ArrowRight,
|
|
4053
|
+
{
|
|
4054
|
+
"aria-hidden": true,
|
|
4055
|
+
className: "size-4 transition-transform duration-200 group-hover:translate-x-0.5 group-hover:text-foreground"
|
|
4056
|
+
}
|
|
3187
4057
|
)
|
|
3188
4058
|
] })
|
|
3189
4059
|
] }) }, slug);
|
|
@@ -3469,6 +4339,7 @@ function VerifyReport({
|
|
|
3469
4339
|
facts,
|
|
3470
4340
|
notChecked,
|
|
3471
4341
|
actions,
|
|
4342
|
+
as: Heading = "h2",
|
|
3472
4343
|
className
|
|
3473
4344
|
}) {
|
|
3474
4345
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -3479,7 +4350,7 @@ function VerifyReport({
|
|
|
3479
4350
|
children: [
|
|
3480
4351
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col items-start gap-3 p-6 md:p-8", children: [
|
|
3481
4352
|
/* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: verdict }),
|
|
3482
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4353
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { className: "oca-display-3", children: title }),
|
|
3483
4354
|
summary ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-body max-w-[40rem]", children: summary }) : null
|
|
3484
4355
|
] }),
|
|
3485
4356
|
/* @__PURE__ */ jsxRuntime.jsx("ul", { "aria-label": "Checks", className: "divide-y divide-border border-t border-border", children: checks.map((c, i) => {
|
|
@@ -3579,8 +4450,1206 @@ function SignMessage({
|
|
|
3579
4450
|
)
|
|
3580
4451
|
] });
|
|
3581
4452
|
}
|
|
3582
|
-
|
|
3583
|
-
|
|
4453
|
+
var isInternal = (href) => href.startsWith("/") || href.startsWith("#");
|
|
4454
|
+
function DocLink({ href, className, children, ...rest }) {
|
|
4455
|
+
return isInternal(href) ? /* @__PURE__ */ jsxRuntime.jsx(Link8__default.default, { href, className, ...rest, children }) : /* @__PURE__ */ jsxRuntime.jsx("a", { href, className, ...rest, children });
|
|
4456
|
+
}
|
|
4457
|
+
function Breadcrumbs({ items, action, className }) {
|
|
4458
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex min-h-11 items-center justify-between gap-4 sm:min-h-0", className), children: [
|
|
4459
|
+
/* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Breadcrumb", className: "min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "flex min-w-0 items-center gap-1.5 text-[0.875rem] text-muted-foreground", children: items.map((c, i) => {
|
|
4460
|
+
const last = i === items.length - 1;
|
|
4461
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: cn("flex items-center gap-1.5", last ? "min-w-0" : "shrink-0"), children: [
|
|
4462
|
+
c.href && !last ? /* @__PURE__ */ jsxRuntime.jsx(DocLink, { href: c.href, className: "inline-flex min-h-11 items-center transition-colors hover:text-foreground sm:min-h-0", children: c.label }) : /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-current": last ? "page" : void 0, className: cn("truncate", last && "text-foreground"), children: c.label }),
|
|
4463
|
+
!last ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": true, className: "size-3.5 shrink-0 text-oca-subtle" }) : null
|
|
4464
|
+
] }, i);
|
|
4465
|
+
}) }) }),
|
|
4466
|
+
action ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 text-[0.875rem]", children: action }) : null
|
|
4467
|
+
] });
|
|
4468
|
+
}
|
|
4469
|
+
function DocsPager({ prev, next, className }) {
|
|
4470
|
+
if (!prev && !next) return null;
|
|
4471
|
+
const card = (l, dir) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4472
|
+
DocLink,
|
|
4473
|
+
{
|
|
4474
|
+
href: l.href,
|
|
4475
|
+
className: cn(
|
|
4476
|
+
"group flex min-h-20 flex-col justify-center gap-1 rounded-2xl border border-border bg-card px-5 py-4 transition-colors hover:border-oca-hairline-strong",
|
|
4477
|
+
dir === "next" && "items-end text-right sm:col-start-2"
|
|
4478
|
+
),
|
|
4479
|
+
children: [
|
|
4480
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1.5 text-[0.8125rem] text-muted-foreground", children: [
|
|
4481
|
+
dir === "prev" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { "aria-hidden": true, className: "size-3.5" }) : null,
|
|
4482
|
+
dir === "prev" ? "Previous" : "Next",
|
|
4483
|
+
l.section ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, children: "\xB7" }) : null,
|
|
4484
|
+
l.section ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: l.section }) : null,
|
|
4485
|
+
dir === "next" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRight, { "aria-hidden": true, className: "size-3.5" }) : null
|
|
4486
|
+
] }),
|
|
4487
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[1rem] font-medium leading-snug text-foreground", children: l.label })
|
|
4488
|
+
]
|
|
4489
|
+
}
|
|
4490
|
+
);
|
|
4491
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("nav", { "aria-label": "Previous and next page", className: cn("grid grid-cols-1 gap-3 border-t border-border pt-8 sm:grid-cols-2", className), children: [
|
|
4492
|
+
prev ? card(prev, "prev") : null,
|
|
4493
|
+
next ? card(next, "next") : null
|
|
4494
|
+
] });
|
|
4495
|
+
}
|
|
4496
|
+
function useHeadings(selector = "#docs-content", key) {
|
|
4497
|
+
const [items, setItems] = react.useState([]);
|
|
4498
|
+
react.useEffect(() => {
|
|
4499
|
+
const read = () => {
|
|
4500
|
+
const root = document.querySelector(selector);
|
|
4501
|
+
if (!root) return setItems([]);
|
|
4502
|
+
setItems(
|
|
4503
|
+
Array.from(root.querySelectorAll("h2[id], h3[id]")).map((h) => ({
|
|
4504
|
+
id: h.id,
|
|
4505
|
+
// The anchor link's "#" is not part of the name.
|
|
4506
|
+
label: (h.querySelector("[data-heading-text]") ?? h).textContent?.trim() ?? "",
|
|
4507
|
+
level: h.tagName === "H3" ? 3 : 2
|
|
4508
|
+
}))
|
|
4509
|
+
);
|
|
4510
|
+
};
|
|
4511
|
+
const raf = requestAnimationFrame(read);
|
|
4512
|
+
const t = setTimeout(read, 80);
|
|
4513
|
+
return () => {
|
|
4514
|
+
cancelAnimationFrame(raf);
|
|
4515
|
+
clearTimeout(t);
|
|
4516
|
+
};
|
|
4517
|
+
}, [selector, key]);
|
|
4518
|
+
const activeId = useActiveHeading(items.map((i) => i.id));
|
|
4519
|
+
return { items, activeId };
|
|
4520
|
+
}
|
|
4521
|
+
function OnThisPage({
|
|
4522
|
+
items,
|
|
4523
|
+
activeId,
|
|
4524
|
+
title = "On this page",
|
|
4525
|
+
onNavigate,
|
|
4526
|
+
className
|
|
4527
|
+
}) {
|
|
4528
|
+
const id = react.useId();
|
|
4529
|
+
if (items.length === 0) return null;
|
|
4530
|
+
return (
|
|
4531
|
+
// With no visible title (a folded list under its own summary) the name is still "On this page".
|
|
4532
|
+
/* @__PURE__ */ jsxRuntime.jsxs("nav", { "aria-labelledby": title ? id : void 0, "aria-label": title ? void 0 : "On this page", className, children: [
|
|
4533
|
+
title ? /* @__PURE__ */ jsxRuntime.jsx("p", { id, className: "mb-3 text-[0.875rem] font-medium", children: title }) : null,
|
|
4534
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { children: items.map((t) => {
|
|
4535
|
+
const on = t.id === activeId;
|
|
4536
|
+
return /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4537
|
+
"a",
|
|
4538
|
+
{
|
|
4539
|
+
href: `#${t.id}`,
|
|
4540
|
+
onClick: onNavigate,
|
|
4541
|
+
"aria-current": on ? "location" : void 0,
|
|
4542
|
+
className: cn(
|
|
4543
|
+
"block border-l py-1.5 text-[0.875rem] leading-snug transition-colors",
|
|
4544
|
+
t.level === 3 ? "pl-7" : "pl-4",
|
|
4545
|
+
on ? "border-foreground text-foreground" : "border-border text-muted-foreground hover:text-foreground"
|
|
4546
|
+
),
|
|
4547
|
+
children: t.label
|
|
4548
|
+
}
|
|
4549
|
+
) }, t.id);
|
|
4550
|
+
}) })
|
|
4551
|
+
] })
|
|
4552
|
+
);
|
|
4553
|
+
}
|
|
4554
|
+
var CALLOUT_TONE = { note: "neutral", warning: "brand", danger: "danger" };
|
|
4555
|
+
function Callout({
|
|
4556
|
+
tone = "note",
|
|
4557
|
+
title,
|
|
4558
|
+
children,
|
|
4559
|
+
className
|
|
4560
|
+
}) {
|
|
4561
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4562
|
+
Notice,
|
|
4563
|
+
{
|
|
4564
|
+
tone: CALLOUT_TONE[tone],
|
|
4565
|
+
title,
|
|
4566
|
+
role: "note",
|
|
4567
|
+
className: cn("my-6 [&_p]:my-0 [&_p]:text-[0.9375rem] [&_p]:leading-relaxed [&_p+p]:mt-3", className),
|
|
4568
|
+
children
|
|
4569
|
+
}
|
|
4570
|
+
);
|
|
4571
|
+
}
|
|
4572
|
+
function Step({ title, id, children }) {
|
|
4573
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "relative pb-8 pl-11 last:pb-0 [counter-increment:oca-step]", children: [
|
|
4574
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4575
|
+
"span",
|
|
4576
|
+
{
|
|
4577
|
+
"aria-hidden": true,
|
|
4578
|
+
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)]"
|
|
4579
|
+
}
|
|
4580
|
+
),
|
|
4581
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "absolute bottom-1 left-[0.8125rem] top-9 w-px bg-border" }),
|
|
4582
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { id, className: "scroll-mt-28 pt-0.5 text-[1.0625rem] font-medium leading-snug tracking-[-0.008em] text-foreground", children: title }),
|
|
4583
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 text-muted-foreground [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", children })
|
|
4584
|
+
] });
|
|
4585
|
+
}
|
|
4586
|
+
function Steps({ children, className }) {
|
|
4587
|
+
return /* @__PURE__ */ jsxRuntime.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 });
|
|
4588
|
+
}
|
|
4589
|
+
function LinkCard({
|
|
4590
|
+
href,
|
|
4591
|
+
title,
|
|
4592
|
+
description,
|
|
4593
|
+
icon,
|
|
4594
|
+
meta,
|
|
4595
|
+
className
|
|
4596
|
+
}) {
|
|
4597
|
+
const Arrow = isInternal(href) ? lucideReact.ArrowRight : lucideReact.ArrowUpRight;
|
|
4598
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4599
|
+
DocLink,
|
|
4600
|
+
{
|
|
4601
|
+
href,
|
|
4602
|
+
className: cn(
|
|
4603
|
+
"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",
|
|
4604
|
+
className
|
|
4605
|
+
),
|
|
4606
|
+
children: [
|
|
4607
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-start justify-between gap-3", children: [
|
|
4608
|
+
icon ? /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx("span", { className: "text-[1rem] font-medium leading-snug text-foreground", children: title }),
|
|
4609
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex shrink-0 items-center gap-2", children: [
|
|
4610
|
+
meta,
|
|
4611
|
+
/* @__PURE__ */ jsxRuntime.jsx(Arrow, { "aria-hidden": true, className: "size-4 text-muted-foreground transition-transform group-hover:translate-x-0.5 group-hover:text-foreground" })
|
|
4612
|
+
] })
|
|
4613
|
+
] }),
|
|
4614
|
+
icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[1rem] font-medium leading-snug text-foreground", children: title }) : null,
|
|
4615
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.9375rem] leading-relaxed text-muted-foreground", children: description }) : null
|
|
4616
|
+
]
|
|
4617
|
+
}
|
|
4618
|
+
);
|
|
4619
|
+
}
|
|
4620
|
+
function CardGrid({ columns = 2, children, className }) {
|
|
4621
|
+
return /* @__PURE__ */ jsxRuntime.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 });
|
|
4622
|
+
}
|
|
4623
|
+
function MdxTable({ className, ...props }) {
|
|
4624
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "not-prose my-6 overflow-hidden rounded-2xl border border-border bg-card", children: /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4625
|
+
"table",
|
|
4626
|
+
{
|
|
4627
|
+
className: cn(
|
|
4628
|
+
"w-full border-collapse text-left text-[0.875rem] leading-relaxed",
|
|
4629
|
+
"[&_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",
|
|
4630
|
+
"[&_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",
|
|
4631
|
+
"[&_td_code]:bg-transparent [&_td_code]:p-0 [&_td_code]:text-foreground [&_td:first-child]:text-foreground",
|
|
4632
|
+
"[&_[align=center]]:text-center [&_[align=right]]:text-right",
|
|
4633
|
+
// On a phone a cell keeps a readable width; the table scrolls instead of crushing it.
|
|
4634
|
+
"max-sm:[&_td]:min-w-[9rem]",
|
|
4635
|
+
className
|
|
4636
|
+
),
|
|
4637
|
+
...props
|
|
4638
|
+
}
|
|
4639
|
+
) }) });
|
|
4640
|
+
}
|
|
4641
|
+
function ApiTable({
|
|
4642
|
+
rows,
|
|
4643
|
+
caption,
|
|
4644
|
+
nameHeader = "Name",
|
|
4645
|
+
className
|
|
4646
|
+
}) {
|
|
4647
|
+
const hasDefault = rows.some((r) => r.default !== void 0);
|
|
4648
|
+
const marks = (r) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4649
|
+
r.required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.75rem] text-oca-accent-ink", children: "Required" }) : null,
|
|
4650
|
+
r.deprecated ? /* @__PURE__ */ jsxRuntime.jsx(Badge, { tone: "muted", children: "Deprecated" }) : null,
|
|
4651
|
+
r.status ? /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: r.status }) : null
|
|
4652
|
+
] });
|
|
4653
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("not-prose my-6", className), children: [
|
|
4654
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-2xl border border-border bg-card max-sm:hidden", children: /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full border-collapse text-left text-[0.875rem]", children: [
|
|
4655
|
+
caption ? /* @__PURE__ */ jsxRuntime.jsx("caption", { className: "sr-only", children: caption }) : null,
|
|
4656
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b border-oca-hairline-strong bg-oca-table-head text-[0.8125rem]", children: [
|
|
4657
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: nameHeader }),
|
|
4658
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: "Type" }),
|
|
4659
|
+
hasDefault ? /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: "Default" }) : null,
|
|
4660
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: "Description" })
|
|
4661
|
+
] }) }),
|
|
4662
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-border", children: rows.map((r) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "align-top", children: [
|
|
4663
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "row", className: "px-4 py-3 text-left font-normal", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col items-start gap-1", children: [
|
|
4664
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: cn("font-mono text-[0.8125rem] text-foreground", r.deprecated && "line-through decoration-oca-subtle"), children: r.name }),
|
|
4665
|
+
marks(r)
|
|
4666
|
+
] }) }),
|
|
4667
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 font-mono text-[0.8125rem] text-muted-foreground", children: r.type ?? "\u2014" }),
|
|
4668
|
+
hasDefault ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 font-mono text-[0.8125rem] text-muted-foreground", children: r.default ?? "\u2014" }) : null,
|
|
4669
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 leading-relaxed text-muted-foreground", children: r.description })
|
|
4670
|
+
] }, r.name)) })
|
|
4671
|
+
] }) }) }),
|
|
4672
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { "aria-label": caption, className: "divide-y divide-border rounded-2xl border border-border bg-card sm:hidden", children: rows.map((r) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex flex-col gap-1.5 px-4 py-3.5", children: [
|
|
4673
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-wrap items-baseline gap-x-2 gap-y-1", children: [
|
|
4674
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: cn("font-mono text-[0.875rem] text-foreground", r.deprecated && "line-through decoration-oca-subtle"), children: r.name }),
|
|
4675
|
+
r.type ? /* @__PURE__ */ jsxRuntime.jsx("code", { className: "break-all font-mono text-[0.8125rem] text-muted-foreground", children: r.type }) : null
|
|
4676
|
+
] }),
|
|
4677
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex flex-wrap items-center gap-2 empty:hidden", children: marks(r) }),
|
|
4678
|
+
r.description ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.875rem] leading-relaxed text-muted-foreground", children: r.description }) : null,
|
|
4679
|
+
r.default !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[0.8125rem] text-muted-foreground", children: [
|
|
4680
|
+
"Default ",
|
|
4681
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-foreground", children: r.default })
|
|
4682
|
+
] }) : null
|
|
4683
|
+
] }, r.name)) })
|
|
4684
|
+
] });
|
|
4685
|
+
}
|
|
4686
|
+
function useDarkMode() {
|
|
4687
|
+
const [dark, setDark] = react.useState(false);
|
|
4688
|
+
react.useEffect(() => {
|
|
4689
|
+
const root = document.documentElement;
|
|
4690
|
+
const read = () => setDark(root.classList.contains("dark"));
|
|
4691
|
+
read();
|
|
4692
|
+
const mo = new MutationObserver(read);
|
|
4693
|
+
mo.observe(root, { attributes: true, attributeFilter: ["class"] });
|
|
4694
|
+
return () => mo.disconnect();
|
|
4695
|
+
}, []);
|
|
4696
|
+
return dark;
|
|
4697
|
+
}
|
|
4698
|
+
function mermaidTheme(el) {
|
|
4699
|
+
const css = getComputedStyle(el);
|
|
4700
|
+
const v = (name) => css.getPropertyValue(name).trim();
|
|
4701
|
+
const card = v("--card");
|
|
4702
|
+
const muted = v("--muted");
|
|
4703
|
+
const text = v("--foreground");
|
|
4704
|
+
const subtle = v("--muted-foreground");
|
|
4705
|
+
const line = v("--input");
|
|
4706
|
+
const hair = v("--oca-hairline-strong");
|
|
4707
|
+
return {
|
|
4708
|
+
background: "transparent",
|
|
4709
|
+
fontFamily: css.fontFamily,
|
|
4710
|
+
fontSize: "14px",
|
|
4711
|
+
textColor: text,
|
|
4712
|
+
mainBkg: card,
|
|
4713
|
+
primaryColor: card,
|
|
4714
|
+
primaryTextColor: text,
|
|
4715
|
+
primaryBorderColor: hair,
|
|
4716
|
+
secondaryColor: muted,
|
|
4717
|
+
secondaryTextColor: text,
|
|
4718
|
+
secondaryBorderColor: hair,
|
|
4719
|
+
tertiaryColor: muted,
|
|
4720
|
+
tertiaryTextColor: text,
|
|
4721
|
+
tertiaryBorderColor: hair,
|
|
4722
|
+
nodeBorder: hair,
|
|
4723
|
+
lineColor: line,
|
|
4724
|
+
edgeLabelBackground: card,
|
|
4725
|
+
clusterBkg: muted,
|
|
4726
|
+
clusterBorder: hair,
|
|
4727
|
+
titleColor: text,
|
|
4728
|
+
noteBkgColor: muted,
|
|
4729
|
+
noteTextColor: text,
|
|
4730
|
+
noteBorderColor: hair,
|
|
4731
|
+
actorBkg: card,
|
|
4732
|
+
actorBorder: hair,
|
|
4733
|
+
actorTextColor: text,
|
|
4734
|
+
actorLineColor: line,
|
|
4735
|
+
signalColor: text,
|
|
4736
|
+
signalTextColor: text,
|
|
4737
|
+
labelBoxBkgColor: card,
|
|
4738
|
+
labelBoxBorderColor: hair,
|
|
4739
|
+
labelTextColor: text,
|
|
4740
|
+
loopTextColor: subtle,
|
|
4741
|
+
activationBkgColor: muted,
|
|
4742
|
+
activationBorderColor: hair,
|
|
4743
|
+
sequenceNumberColor: card
|
|
4744
|
+
};
|
|
4745
|
+
}
|
|
4746
|
+
function naturalSize(svg) {
|
|
4747
|
+
const w = svg.match(/viewBox="[\d.-]+ [\d.-]+ ([\d.]+) [\d.]+"/)?.[1];
|
|
4748
|
+
if (!w) return svg;
|
|
4749
|
+
return svg.replace(/<svg([^>]*?)\swidth="100%"/, `<svg$1 width="${Math.ceil(Number(w))}"`).replace(/max-width:\s*[\d.]+px;?/, "");
|
|
4750
|
+
}
|
|
4751
|
+
function Diagram({ chart, caption, load, className }) {
|
|
4752
|
+
const ref = react.useRef(null);
|
|
4753
|
+
const dark = useDarkMode();
|
|
4754
|
+
const raw = react.useId();
|
|
4755
|
+
const [svg, setSvg] = react.useState(null);
|
|
4756
|
+
const [failed, setFailed] = react.useState(false);
|
|
4757
|
+
react.useEffect(() => {
|
|
4758
|
+
let live = true;
|
|
4759
|
+
const el = ref.current;
|
|
4760
|
+
if (!el) return;
|
|
4761
|
+
(async () => {
|
|
4762
|
+
try {
|
|
4763
|
+
const mod = await load();
|
|
4764
|
+
const mermaid = "default" in mod ? mod.default : mod;
|
|
4765
|
+
mermaid.initialize({ startOnLoad: false, securityLevel: "strict", theme: "base", themeVariables: mermaidTheme(el) });
|
|
4766
|
+
const { svg: drawn } = await mermaid.render(`oca-diagram-${raw.replace(/[^a-zA-Z0-9]/g, "")}-${dark ? "d" : "l"}`, chart);
|
|
4767
|
+
if (live) {
|
|
4768
|
+
setSvg(naturalSize(drawn));
|
|
4769
|
+
setFailed(false);
|
|
4770
|
+
}
|
|
4771
|
+
} catch {
|
|
4772
|
+
if (live) setFailed(true);
|
|
4773
|
+
}
|
|
4774
|
+
})();
|
|
4775
|
+
return () => {
|
|
4776
|
+
live = false;
|
|
4777
|
+
};
|
|
4778
|
+
}, [chart, dark, load, raw]);
|
|
4779
|
+
if (failed) return /* @__PURE__ */ jsxRuntime.jsx(CodeBlock, { code: chart, caption: "Diagram (shown as its source)", className: cn("my-6", className) });
|
|
4780
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("figure", { ref, className: cn("not-prose my-6 overflow-hidden rounded-[1.25rem] border border-border bg-card", className), children: [
|
|
4781
|
+
svg ? /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4782
|
+
"div",
|
|
4783
|
+
{
|
|
4784
|
+
className: "flex w-max min-w-full justify-center p-6 [&_svg]:h-auto [&_svg]:max-w-none",
|
|
4785
|
+
role: "img",
|
|
4786
|
+
"aria-label": typeof caption === "string" ? caption : "Diagram",
|
|
4787
|
+
dangerouslySetInnerHTML: { __html: svg }
|
|
4788
|
+
}
|
|
4789
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { role: "status", "aria-label": "Drawing the diagram", className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-40 w-full rounded-xl" }) }),
|
|
4790
|
+
caption ? /* @__PURE__ */ jsxRuntime.jsx("figcaption", { className: "border-t border-border px-5 py-3 text-[0.8125rem] text-muted-foreground", children: caption }) : null
|
|
4791
|
+
] });
|
|
4792
|
+
}
|
|
4793
|
+
var HEADING = {
|
|
4794
|
+
h1: "oca-display-3 mb-4 text-foreground",
|
|
4795
|
+
h2: "mb-3 mt-12 text-[1.375rem] font-medium leading-tight tracking-[-0.015em] text-foreground md:text-[1.5rem]",
|
|
4796
|
+
h3: "mb-2 mt-9 text-[1.125rem] font-medium leading-snug tracking-[-0.01em] text-foreground",
|
|
4797
|
+
h4: "mb-2 mt-7 text-[1rem] font-medium leading-snug text-foreground"
|
|
4798
|
+
};
|
|
4799
|
+
function DocsHeading({
|
|
4800
|
+
as: Tag,
|
|
4801
|
+
id,
|
|
4802
|
+
children,
|
|
4803
|
+
className,
|
|
4804
|
+
...props
|
|
4805
|
+
}) {
|
|
4806
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Tag, { id, className: cn("group scroll-mt-28", HEADING[Tag], className), ...props, children: [
|
|
4807
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-heading-text": "", children }),
|
|
4808
|
+
id && Tag !== "h1" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4809
|
+
"a",
|
|
4810
|
+
{
|
|
4811
|
+
href: `#${id}`,
|
|
4812
|
+
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",
|
|
4813
|
+
children: [
|
|
4814
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, children: "#" }),
|
|
4815
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Link to this section" })
|
|
4816
|
+
]
|
|
4817
|
+
}
|
|
4818
|
+
) : null
|
|
4819
|
+
] });
|
|
4820
|
+
}
|
|
4821
|
+
function codeText(node) {
|
|
4822
|
+
if (typeof node === "string") return node;
|
|
4823
|
+
if (typeof node === "number") return String(node);
|
|
4824
|
+
if (Array.isArray(node)) return node.map(codeText).join("");
|
|
4825
|
+
if (react.isValidElement(node)) return codeText(node.props.children);
|
|
4826
|
+
return "";
|
|
4827
|
+
}
|
|
4828
|
+
function codeLang(node) {
|
|
4829
|
+
const child = react.Children.toArray(node)[0];
|
|
4830
|
+
if (!react.isValidElement(child)) return void 0;
|
|
4831
|
+
const cls = child.props.className ?? "";
|
|
4832
|
+
return cls.match(/language-([\w+-]+)/)?.[1];
|
|
4833
|
+
}
|
|
4834
|
+
function useMacKeys() {
|
|
4835
|
+
const [mac, setMac] = react.useState(true);
|
|
4836
|
+
react.useEffect(() => {
|
|
4837
|
+
setMac(/Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent));
|
|
4838
|
+
}, []);
|
|
4839
|
+
return mac;
|
|
4840
|
+
}
|
|
4841
|
+
var typing = (el) => el instanceof HTMLElement && (el.isContentEditable || /^(INPUT|TEXTAREA|SELECT)$/.test(el.tagName));
|
|
4842
|
+
var SearchButton = react.forwardRef(function SearchButton2({ label = "Search", onClick, className }, ref) {
|
|
4843
|
+
const mac = useMacKeys();
|
|
4844
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4845
|
+
"button",
|
|
4846
|
+
{
|
|
4847
|
+
ref,
|
|
4848
|
+
type: "button",
|
|
4849
|
+
onClick,
|
|
4850
|
+
"aria-keyshortcuts": mac ? "Meta+K" : "Control+K",
|
|
4851
|
+
className: cn(
|
|
4852
|
+
"inline-flex size-10 items-center justify-center gap-2 rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
|
|
4853
|
+
"md:h-10 md:w-56 md:justify-start md:border md:border-border md:bg-card md:pl-3.5 md:pr-2 md:hover:border-oca-hairline-strong md:hover:bg-card",
|
|
4854
|
+
className
|
|
4855
|
+
),
|
|
4856
|
+
children: [
|
|
4857
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { "aria-hidden": true, className: "size-[1.125rem] shrink-0 md:size-4" }),
|
|
4858
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only flex-1 text-left text-[0.9375rem] md:not-sr-only", children: label }),
|
|
4859
|
+
/* @__PURE__ */ jsxRuntime.jsx(Kbd, { "aria-hidden": true, className: "hidden md:inline-flex", children: mac ? "\u2318K" : "Ctrl K" })
|
|
4860
|
+
]
|
|
4861
|
+
}
|
|
4862
|
+
);
|
|
4863
|
+
});
|
|
4864
|
+
function SearchDialog({
|
|
4865
|
+
onQuery,
|
|
4866
|
+
open: openProp,
|
|
4867
|
+
onOpenChange,
|
|
4868
|
+
onSelect,
|
|
4869
|
+
button = true,
|
|
4870
|
+
hotkey = true,
|
|
4871
|
+
label = "Search",
|
|
4872
|
+
placeholder = "Search the docs",
|
|
4873
|
+
idle,
|
|
4874
|
+
defaultQuery = "",
|
|
4875
|
+
debounceMs = 120,
|
|
4876
|
+
className
|
|
4877
|
+
}) {
|
|
4878
|
+
const [own, setOwn] = react.useState(false);
|
|
4879
|
+
const open = openProp ?? own;
|
|
4880
|
+
const setOpen = (v) => {
|
|
4881
|
+
if (openProp === void 0) setOwn(v);
|
|
4882
|
+
onOpenChange?.(v);
|
|
4883
|
+
};
|
|
4884
|
+
const [query, setQuery] = react.useState(defaultQuery);
|
|
4885
|
+
const [groups, setGroups] = react.useState([]);
|
|
4886
|
+
const [state, setState] = react.useState("idle");
|
|
4887
|
+
const [active, setActive] = react.useState(0);
|
|
4888
|
+
const listId = react.useId();
|
|
4889
|
+
const listRef = react.useRef(null);
|
|
4890
|
+
const buttonRef = react.useRef(null);
|
|
4891
|
+
const returnTo = react.useRef(null);
|
|
4892
|
+
const flat = react.useMemo(() => groups.flatMap((g) => g.results), [groups]);
|
|
4893
|
+
const latest = react.useRef({ open, setOpen, onQuery });
|
|
4894
|
+
latest.current = { open, setOpen, onQuery };
|
|
4895
|
+
react.useEffect(() => {
|
|
4896
|
+
if (!hotkey) return;
|
|
4897
|
+
const onKey = (e) => {
|
|
4898
|
+
const { open: isOpen, setOpen: set } = latest.current;
|
|
4899
|
+
if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
|
|
4900
|
+
e.preventDefault();
|
|
4901
|
+
set(!isOpen);
|
|
4902
|
+
} else if (e.key === "/" && !isOpen && !typing(e.target)) {
|
|
4903
|
+
e.preventDefault();
|
|
4904
|
+
set(true);
|
|
4905
|
+
}
|
|
4906
|
+
};
|
|
4907
|
+
window.addEventListener("keydown", onKey);
|
|
4908
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
4909
|
+
}, [hotkey]);
|
|
4910
|
+
react.useEffect(() => {
|
|
4911
|
+
const q = query.trim();
|
|
4912
|
+
if (!q) {
|
|
4913
|
+
setGroups([]);
|
|
4914
|
+
setState("idle");
|
|
4915
|
+
return;
|
|
4916
|
+
}
|
|
4917
|
+
const ctl = new AbortController();
|
|
4918
|
+
setState("loading");
|
|
4919
|
+
const t = setTimeout(async () => {
|
|
4920
|
+
try {
|
|
4921
|
+
const out = await latest.current.onQuery(q, ctl.signal);
|
|
4922
|
+
if (ctl.signal.aborted) return;
|
|
4923
|
+
setGroups(out.filter((g) => g.results.length > 0));
|
|
4924
|
+
setActive(0);
|
|
4925
|
+
setState("done");
|
|
4926
|
+
} catch {
|
|
4927
|
+
if (!ctl.signal.aborted) setState("error");
|
|
4928
|
+
}
|
|
4929
|
+
}, debounceMs);
|
|
4930
|
+
return () => {
|
|
4931
|
+
clearTimeout(t);
|
|
4932
|
+
ctl.abort();
|
|
4933
|
+
};
|
|
4934
|
+
}, [query, debounceMs]);
|
|
4935
|
+
react.useEffect(() => {
|
|
4936
|
+
listRef.current?.querySelector('[aria-selected="true"]')?.scrollIntoView({ block: "nearest" });
|
|
4937
|
+
}, [active]);
|
|
4938
|
+
const choose = (r) => {
|
|
4939
|
+
setOpen(false);
|
|
4940
|
+
if (onSelect) onSelect(r);
|
|
4941
|
+
else window.location.assign(r.href);
|
|
4942
|
+
};
|
|
4943
|
+
const optionId = (i) => `${listId}-o${i}`;
|
|
4944
|
+
const showList = state === "done" && flat.length > 0;
|
|
4945
|
+
let index = -1;
|
|
4946
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4947
|
+
button ? /* @__PURE__ */ jsxRuntime.jsx(SearchButton, { ref: buttonRef, label, onClick: () => setOpen(true), className }) : null,
|
|
4948
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Root, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Portal, { children: [
|
|
4949
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Overlay, { className: "oca-animate-fade fixed inset-0 z-50 bg-[rgb(10_10_10/0.38)] backdrop-blur-[2px]" }),
|
|
4950
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4951
|
+
DialogPrimitive__namespace.Content,
|
|
4952
|
+
{
|
|
4953
|
+
"aria-describedby": void 0,
|
|
4954
|
+
onOpenAutoFocus: () => {
|
|
4955
|
+
const el = document.activeElement;
|
|
4956
|
+
returnTo.current = el instanceof HTMLElement && el !== document.body ? el : null;
|
|
4957
|
+
},
|
|
4958
|
+
onCloseAutoFocus: (e) => {
|
|
4959
|
+
const back = returnTo.current?.isConnected ? returnTo.current : buttonRef.current;
|
|
4960
|
+
if (back) {
|
|
4961
|
+
e.preventDefault();
|
|
4962
|
+
back.focus();
|
|
4963
|
+
}
|
|
4964
|
+
},
|
|
4965
|
+
className: "oca-animate-rise fixed left-1/2 top-3 z-50 flex max-h-[calc(100dvh-1.5rem)] w-[calc(100vw-1.5rem)] -translate-x-1/2 flex-col overflow-hidden rounded-[1.5rem] border border-border bg-popover text-popover-foreground shadow-xl outline-none sm:top-[12vh] sm:max-h-[min(36rem,76vh)] sm:w-[min(92vw,40rem)]",
|
|
4966
|
+
children: [
|
|
4967
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Title, { className: "sr-only", children: label }),
|
|
4968
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-14 shrink-0 items-center gap-3 border-b border-border pl-5 pr-3", children: [
|
|
4969
|
+
state === "loading" ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, { className: "size-[1.125rem] text-muted-foreground" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { "aria-hidden": true, className: "size-[1.125rem] shrink-0 text-muted-foreground" }),
|
|
4970
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4971
|
+
"input",
|
|
4972
|
+
{
|
|
4973
|
+
autoFocus: true,
|
|
4974
|
+
value: query,
|
|
4975
|
+
onChange: (e) => setQuery(e.target.value),
|
|
4976
|
+
onKeyDown: (e) => {
|
|
4977
|
+
if (!showList) return;
|
|
4978
|
+
if (e.key === "ArrowDown" || e.key === "ArrowUp") {
|
|
4979
|
+
e.preventDefault();
|
|
4980
|
+
const d = e.key === "ArrowDown" ? 1 : -1;
|
|
4981
|
+
setActive((a) => (a + d + flat.length) % flat.length);
|
|
4982
|
+
} else if (e.key === "Enter" && flat[active]) {
|
|
4983
|
+
e.preventDefault();
|
|
4984
|
+
choose(flat[active]);
|
|
4985
|
+
}
|
|
4986
|
+
},
|
|
4987
|
+
placeholder,
|
|
4988
|
+
role: "combobox",
|
|
4989
|
+
"aria-label": label,
|
|
4990
|
+
"aria-expanded": showList,
|
|
4991
|
+
"aria-controls": listId,
|
|
4992
|
+
"aria-autocomplete": "list",
|
|
4993
|
+
"aria-activedescendant": showList ? optionId(active) : void 0,
|
|
4994
|
+
spellCheck: false,
|
|
4995
|
+
autoComplete: "off",
|
|
4996
|
+
className: "h-full min-w-0 flex-1 bg-transparent text-base text-foreground outline-none placeholder:text-oca-subtle"
|
|
4997
|
+
}
|
|
4998
|
+
),
|
|
4999
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "inline-flex h-8 shrink-0 items-center rounded-md border border-border px-2 text-[0.75rem] text-muted-foreground transition-colors hover:text-foreground", children: [
|
|
5000
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sm:hidden", children: "Close" }),
|
|
5001
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-sm:hidden", "aria-hidden": true, children: "Esc" }),
|
|
5002
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only max-sm:hidden", children: "Close search" })
|
|
5003
|
+
] })
|
|
5004
|
+
] }),
|
|
5005
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { ref: listRef, className: "min-h-0 flex-1 overflow-y-auto overscroll-contain p-2", children: [
|
|
5006
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { id: listId, role: "listbox", "aria-label": "Results", className: cn(!showList && "hidden"), children: groups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-label": typeof g.label === "string" ? g.label : void 0, className: "pb-1", children: [
|
|
5007
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { "aria-hidden": true, className: "px-3 pb-1.5 pt-3 text-[0.8125rem] text-muted-foreground", children: g.label }),
|
|
5008
|
+
g.results.map((r) => {
|
|
5009
|
+
index++;
|
|
5010
|
+
const i = index;
|
|
5011
|
+
const on = i === active;
|
|
5012
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5013
|
+
"a",
|
|
5014
|
+
{
|
|
5015
|
+
id: optionId(i),
|
|
5016
|
+
href: r.href,
|
|
5017
|
+
role: "option",
|
|
5018
|
+
"aria-selected": on,
|
|
5019
|
+
tabIndex: -1,
|
|
5020
|
+
onMouseMove: () => setActive(i),
|
|
5021
|
+
onClick: (e) => {
|
|
5022
|
+
if (e.metaKey || e.ctrlKey || e.shiftKey) return;
|
|
5023
|
+
e.preventDefault();
|
|
5024
|
+
choose(r);
|
|
5025
|
+
},
|
|
5026
|
+
className: cn(
|
|
5027
|
+
"flex items-start gap-3 rounded-xl px-3 py-2.5 transition-colors",
|
|
5028
|
+
on ? "bg-accent" : "hover:bg-accent"
|
|
5029
|
+
),
|
|
5030
|
+
children: [
|
|
5031
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
|
|
5032
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[0.9375rem] font-medium text-foreground", children: r.title }),
|
|
5033
|
+
r.section ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[0.8125rem] text-muted-foreground", children: r.section }) : null,
|
|
5034
|
+
r.excerptHtml ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5035
|
+
"span",
|
|
5036
|
+
{
|
|
5037
|
+
className: "line-clamp-2 text-[0.875rem] leading-snug text-muted-foreground [&_mark]:rounded-sm [&_mark]:bg-[color-mix(in_oklab,var(--oca-orange)_22%,transparent)] [&_mark]:px-0.5 [&_mark]:text-foreground",
|
|
5038
|
+
dangerouslySetInnerHTML: { __html: r.excerptHtml }
|
|
5039
|
+
}
|
|
5040
|
+
) : r.excerpt ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-2 text-[0.875rem] leading-snug text-muted-foreground", children: r.excerpt }) : null
|
|
5041
|
+
] }),
|
|
5042
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.CornerDownLeft, { "aria-hidden": true, className: cn("mt-1 size-4 shrink-0 text-muted-foreground", !on && "invisible") })
|
|
5043
|
+
]
|
|
5044
|
+
},
|
|
5045
|
+
r.id
|
|
5046
|
+
);
|
|
5047
|
+
})
|
|
5048
|
+
] }, gi)) }),
|
|
5049
|
+
state === "idle" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-6 text-[0.9375rem] text-muted-foreground", children: idle ?? "Type a word: a protocol, a function, an error." }) : null,
|
|
5050
|
+
state === "done" && flat.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("p", { role: "status", className: "px-3 py-6 text-[0.9375rem] text-muted-foreground", children: [
|
|
5051
|
+
"No results for \u201C",
|
|
5052
|
+
query.trim(),
|
|
5053
|
+
"\u201D."
|
|
5054
|
+
] }) : null,
|
|
5055
|
+
state === "error" ? /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", className: "px-3 py-6 text-[0.9375rem] text-muted-foreground", children: "Search is not available right now. Try again in a moment." }) : null
|
|
5056
|
+
] }),
|
|
5057
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { "aria-hidden": true, className: "hidden shrink-0 items-center gap-4 border-t border-border px-5 py-2.5 text-[0.75rem] text-muted-foreground sm:flex", children: [
|
|
5058
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1.5", children: [
|
|
5059
|
+
/* @__PURE__ */ jsxRuntime.jsx(Kbd, { children: "\u2191" }),
|
|
5060
|
+
/* @__PURE__ */ jsxRuntime.jsx(Kbd, { children: "\u2193" }),
|
|
5061
|
+
" to move"
|
|
5062
|
+
] }),
|
|
5063
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1.5", children: [
|
|
5064
|
+
/* @__PURE__ */ jsxRuntime.jsx(Kbd, { children: "\u21B5" }),
|
|
5065
|
+
" to open"
|
|
5066
|
+
] }),
|
|
5067
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1.5", children: [
|
|
5068
|
+
/* @__PURE__ */ jsxRuntime.jsx(Kbd, { children: "esc" }),
|
|
5069
|
+
" to close"
|
|
5070
|
+
] })
|
|
5071
|
+
] }),
|
|
5072
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-live": "polite", className: "sr-only", children: state === "done" ? `${flat.length} result${flat.length === 1 ? "" : "s"}` : "" })
|
|
5073
|
+
]
|
|
5074
|
+
}
|
|
5075
|
+
)
|
|
5076
|
+
] }) })
|
|
5077
|
+
] });
|
|
5078
|
+
}
|
|
5079
|
+
function pretty(content) {
|
|
5080
|
+
try {
|
|
5081
|
+
return JSON.stringify(JSON.parse(content), null, 2);
|
|
5082
|
+
} catch {
|
|
5083
|
+
return null;
|
|
5084
|
+
}
|
|
5085
|
+
}
|
|
5086
|
+
function download(content, filename, mime) {
|
|
5087
|
+
const url = URL.createObjectURL(new Blob([content], { type: mime }));
|
|
5088
|
+
const a = document.createElement("a");
|
|
5089
|
+
a.href = url;
|
|
5090
|
+
a.download = filename;
|
|
5091
|
+
document.body.appendChild(a);
|
|
5092
|
+
a.click();
|
|
5093
|
+
a.remove();
|
|
5094
|
+
setTimeout(() => URL.revokeObjectURL(url), 0);
|
|
5095
|
+
}
|
|
5096
|
+
var BAR_BUTTON = "inline-flex h-7 items-center gap-1.5 rounded-full px-2.5 text-[0.75rem] text-oca-ink-subtle transition-colors hover:bg-white/10 hover:text-white";
|
|
5097
|
+
function ArtifactView({
|
|
5098
|
+
content,
|
|
5099
|
+
title,
|
|
5100
|
+
filename,
|
|
5101
|
+
mime,
|
|
5102
|
+
defaultView = "formatted",
|
|
5103
|
+
maxLines = 28,
|
|
5104
|
+
className
|
|
5105
|
+
}) {
|
|
5106
|
+
const formatted = react.useMemo(() => pretty(content), [content]);
|
|
5107
|
+
const [view, setView] = react.useState(formatted ? defaultView : "raw");
|
|
5108
|
+
const shown = view === "formatted" && formatted ? formatted : content;
|
|
5109
|
+
const json = formatted !== null;
|
|
5110
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5111
|
+
CodeBlock,
|
|
5112
|
+
{
|
|
5113
|
+
code: shown,
|
|
5114
|
+
lang: json ? "json" : void 0,
|
|
5115
|
+
caption: title,
|
|
5116
|
+
maxLines,
|
|
5117
|
+
className,
|
|
5118
|
+
actions: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5119
|
+
json ? /* @__PURE__ */ jsxRuntime.jsx("span", { role: "group", "aria-label": "View", className: "mr-1 flex items-center rounded-full bg-white/[0.06] p-0.5", children: ["formatted", "raw"].map((v) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5120
|
+
"button",
|
|
5121
|
+
{
|
|
5122
|
+
type: "button",
|
|
5123
|
+
"aria-pressed": view === v,
|
|
5124
|
+
onClick: () => setView(v),
|
|
5125
|
+
className: cn(
|
|
5126
|
+
"h-7 rounded-full px-2.5 text-[0.75rem] transition-colors",
|
|
5127
|
+
view === v ? "bg-white/[0.12] text-white" : "text-oca-ink-subtle hover:text-white"
|
|
5128
|
+
),
|
|
5129
|
+
children: v === "formatted" ? "Formatted" : "Raw"
|
|
5130
|
+
},
|
|
5131
|
+
v
|
|
5132
|
+
)) }) : null,
|
|
5133
|
+
filename ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5134
|
+
"button",
|
|
5135
|
+
{
|
|
5136
|
+
type: "button",
|
|
5137
|
+
onClick: () => download(content, filename, mime ?? (json ? "application/json" : "text/plain")),
|
|
5138
|
+
className: BAR_BUTTON,
|
|
5139
|
+
"aria-label": `Download ${filename}`,
|
|
5140
|
+
children: [
|
|
5141
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { "aria-hidden": true, className: "size-3.5" }),
|
|
5142
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-sm:hidden", children: "Download" })
|
|
5143
|
+
]
|
|
5144
|
+
}
|
|
5145
|
+
) : null
|
|
5146
|
+
] })
|
|
5147
|
+
}
|
|
5148
|
+
);
|
|
5149
|
+
}
|
|
5150
|
+
function DropZone({
|
|
5151
|
+
onFile,
|
|
5152
|
+
onText,
|
|
5153
|
+
accept,
|
|
5154
|
+
title = "Drop a file here, or choose one",
|
|
5155
|
+
hint,
|
|
5156
|
+
privacy = "It stays in your browser. Only its hash leaves this page.",
|
|
5157
|
+
file,
|
|
5158
|
+
progress,
|
|
5159
|
+
progressLabel = "Hashing",
|
|
5160
|
+
onClear,
|
|
5161
|
+
error,
|
|
5162
|
+
disabled = false,
|
|
5163
|
+
className
|
|
5164
|
+
}) {
|
|
5165
|
+
const input = react.useRef(null);
|
|
5166
|
+
const [over, setOver] = react.useState(false);
|
|
5167
|
+
const depth = react.useRef(0);
|
|
5168
|
+
const [mode, setMode] = react.useState("file");
|
|
5169
|
+
const [text, setText] = react.useState("");
|
|
5170
|
+
const errorId = react.useId();
|
|
5171
|
+
const titleId = react.useId();
|
|
5172
|
+
const busy = progress !== null && progress !== void 0;
|
|
5173
|
+
const pct = busy ? Math.round(Math.max(0, Math.min(1, progress)) * 100) : 0;
|
|
5174
|
+
const take = (f) => {
|
|
5175
|
+
if (f && !disabled) onFile(f);
|
|
5176
|
+
};
|
|
5177
|
+
const privacyLine = privacy === null ? null : /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "flex items-start gap-2 text-[0.8125rem] leading-snug text-muted-foreground", children: [
|
|
5178
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Lock, { "aria-hidden": true, className: "mt-0.5 size-3.5 shrink-0" }),
|
|
5179
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: privacy })
|
|
5180
|
+
] });
|
|
5181
|
+
if (mode === "text" && onText) {
|
|
5182
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-3", className), children: [
|
|
5183
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5184
|
+
Textarea,
|
|
5185
|
+
{
|
|
5186
|
+
value: text,
|
|
5187
|
+
onChange: (e) => setText(e.target.value),
|
|
5188
|
+
rows: 6,
|
|
5189
|
+
"aria-label": "Text",
|
|
5190
|
+
"aria-describedby": error ? errorId : void 0,
|
|
5191
|
+
"aria-invalid": error ? true : void 0,
|
|
5192
|
+
placeholder: "Paste the text here",
|
|
5193
|
+
className: "font-mono text-base md:text-[0.875rem]"
|
|
5194
|
+
}
|
|
5195
|
+
),
|
|
5196
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
5197
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", disabled: !text.trim() || disabled, onClick: () => onText(text), children: "Use this text" }),
|
|
5198
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", variant: "ghost", onClick: () => setMode("file"), children: "Choose a file instead" })
|
|
5199
|
+
] }),
|
|
5200
|
+
error ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, role: "alert", className: "text-[0.8125rem] text-destructive", children: error }) : null,
|
|
5201
|
+
privacyLine
|
|
5202
|
+
] });
|
|
5203
|
+
}
|
|
5204
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-3", className), children: [
|
|
5205
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5206
|
+
"div",
|
|
5207
|
+
{
|
|
5208
|
+
role: "group",
|
|
5209
|
+
"aria-labelledby": titleId,
|
|
5210
|
+
"aria-describedby": error ? errorId : void 0,
|
|
5211
|
+
"aria-busy": busy || void 0,
|
|
5212
|
+
onDragEnter: (e) => {
|
|
5213
|
+
e.preventDefault();
|
|
5214
|
+
depth.current++;
|
|
5215
|
+
if (!disabled) setOver(true);
|
|
5216
|
+
},
|
|
5217
|
+
onDragOver: (e) => e.preventDefault(),
|
|
5218
|
+
onDragLeave: () => {
|
|
5219
|
+
depth.current = Math.max(0, depth.current - 1);
|
|
5220
|
+
if (depth.current === 0) setOver(false);
|
|
5221
|
+
},
|
|
5222
|
+
onDrop: (e) => {
|
|
5223
|
+
e.preventDefault();
|
|
5224
|
+
depth.current = 0;
|
|
5225
|
+
setOver(false);
|
|
5226
|
+
take(e.dataTransfer.files?.[0]);
|
|
5227
|
+
},
|
|
5228
|
+
className: cn(
|
|
5229
|
+
"relative flex flex-col gap-3 rounded-[1.25rem] border border-dashed transition-colors",
|
|
5230
|
+
file ? "px-4 py-4 sm:px-5" : "items-center px-5 py-8 text-center md:py-10",
|
|
5231
|
+
over ? "border-foreground bg-accent" : "border-oca-hairline-strong bg-card",
|
|
5232
|
+
error && "border-destructive",
|
|
5233
|
+
disabled && "opacity-55"
|
|
5234
|
+
),
|
|
5235
|
+
children: [
|
|
5236
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5237
|
+
"input",
|
|
5238
|
+
{
|
|
5239
|
+
ref: input,
|
|
5240
|
+
type: "file",
|
|
5241
|
+
accept,
|
|
5242
|
+
disabled,
|
|
5243
|
+
tabIndex: -1,
|
|
5244
|
+
"aria-hidden": true,
|
|
5245
|
+
className: "sr-only",
|
|
5246
|
+
onChange: (e) => {
|
|
5247
|
+
take(e.target.files?.[0]);
|
|
5248
|
+
e.target.value = "";
|
|
5249
|
+
}
|
|
5250
|
+
}
|
|
5251
|
+
),
|
|
5252
|
+
file ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full flex-col gap-3", children: [
|
|
5253
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
5254
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-10 shrink-0 items-center justify-center rounded-xl bg-muted text-foreground", children: busy ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { "aria-hidden": true, className: "size-5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { "aria-hidden": true, className: "size-5" }) }),
|
|
5255
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
5256
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { id: titleId, className: "truncate text-[0.9375rem] font-medium", title: file.name, children: file.name }),
|
|
5257
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.8125rem] text-muted-foreground", children: [formatBytes(file.size), file.type].filter(Boolean).join(" \xB7 ") })
|
|
5258
|
+
] }),
|
|
5259
|
+
!busy && onClear ? /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", variant: "secondary", onClick: onClear, disabled, className: "shrink-0", children: "Choose another" }) : null
|
|
5260
|
+
] }),
|
|
5261
|
+
busy ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
5262
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5263
|
+
"div",
|
|
5264
|
+
{
|
|
5265
|
+
role: "progressbar",
|
|
5266
|
+
"aria-valuemin": 0,
|
|
5267
|
+
"aria-valuemax": 100,
|
|
5268
|
+
"aria-valuenow": pct,
|
|
5269
|
+
"aria-label": typeof progressLabel === "string" ? progressLabel : "Progress",
|
|
5270
|
+
className: "h-1.5 overflow-hidden rounded-full bg-muted",
|
|
5271
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full rounded-full bg-foreground transition-[width] duration-200", style: { width: `${pct}%` } })
|
|
5272
|
+
}
|
|
5273
|
+
),
|
|
5274
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[0.8125rem] text-muted-foreground oca-tabular", children: [
|
|
5275
|
+
progressLabel,
|
|
5276
|
+
" ",
|
|
5277
|
+
pct,
|
|
5278
|
+
"%"
|
|
5279
|
+
] })
|
|
5280
|
+
] }) : null
|
|
5281
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5282
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-11 items-center justify-center rounded-full bg-muted text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Upload, { "aria-hidden": true, className: "size-5" }) }),
|
|
5283
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
5284
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { id: titleId, className: "text-[1rem] font-medium", children: over ? "Drop it to add it" : title }),
|
|
5285
|
+
hint ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] text-muted-foreground", children: hint }) : null
|
|
5286
|
+
] }),
|
|
5287
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 flex flex-wrap items-center justify-center gap-2", children: [
|
|
5288
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", variant: "secondary", disabled, onClick: () => input.current?.click(), children: "Choose a file" }),
|
|
5289
|
+
onText ? /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", variant: "ghost", disabled, onClick: () => setMode("text"), children: "Paste text instead" }) : null
|
|
5290
|
+
] })
|
|
5291
|
+
] })
|
|
5292
|
+
]
|
|
5293
|
+
}
|
|
5294
|
+
),
|
|
5295
|
+
error ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, role: "alert", className: "text-[0.8125rem] text-destructive", children: error }) : null,
|
|
5296
|
+
privacyLine
|
|
5297
|
+
] });
|
|
5298
|
+
}
|
|
5299
|
+
function FormSection({
|
|
5300
|
+
n,
|
|
5301
|
+
title,
|
|
5302
|
+
hint,
|
|
5303
|
+
status,
|
|
5304
|
+
action,
|
|
5305
|
+
as: Heading = "h2",
|
|
5306
|
+
id,
|
|
5307
|
+
children,
|
|
5308
|
+
className
|
|
5309
|
+
}) {
|
|
5310
|
+
const titleId = react.useId();
|
|
5311
|
+
const tight = useDensity() === "compact";
|
|
5312
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5313
|
+
"section",
|
|
5314
|
+
{
|
|
5315
|
+
id,
|
|
5316
|
+
"aria-labelledby": titleId,
|
|
5317
|
+
"aria-current": status === "current" ? "step" : void 0,
|
|
5318
|
+
className: cn("scroll-mt-24 rounded-[1.25rem] border border-border bg-card", className),
|
|
5319
|
+
children: [
|
|
5320
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: cn("flex items-start gap-3.5", tight ? "px-5 pt-5" : "px-6 pt-6"), children: [
|
|
5321
|
+
n !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5322
|
+
"span",
|
|
5323
|
+
{
|
|
5324
|
+
"aria-hidden": true,
|
|
5325
|
+
className: cn(
|
|
5326
|
+
"mt-px flex size-7 shrink-0 items-center justify-center rounded-full border text-[0.8125rem] oca-tabular",
|
|
5327
|
+
status === "done" && "border-primary bg-primary text-primary-foreground",
|
|
5328
|
+
status === "current" && "border-brand text-oca-accent-ink",
|
|
5329
|
+
status === "blocked" && "border-destructive text-destructive",
|
|
5330
|
+
(status === "upcoming" || status === void 0) && "border-oca-hairline-strong text-muted-foreground"
|
|
5331
|
+
),
|
|
5332
|
+
children: status === "done" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "size-3.5", strokeWidth: 3 }) : n
|
|
5333
|
+
}
|
|
5334
|
+
) : null,
|
|
5335
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
|
|
5336
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Heading, { id: titleId, className: "text-[1.0625rem] font-medium leading-snug tracking-[-0.008em]", children: [
|
|
5337
|
+
n !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sr-only", children: [
|
|
5338
|
+
"Step ",
|
|
5339
|
+
n,
|
|
5340
|
+
": "
|
|
5341
|
+
] }) : null,
|
|
5342
|
+
title,
|
|
5343
|
+
status === "done" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: " (done)" }) : null
|
|
5344
|
+
] }),
|
|
5345
|
+
hint ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] leading-snug text-muted-foreground", children: hint }) : null
|
|
5346
|
+
] }),
|
|
5347
|
+
action ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: action }) : null
|
|
5348
|
+
] }),
|
|
5349
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col", tight ? "gap-4 p-5" : "gap-5 p-6", n !== void 0 && (tight ? "sm:pl-[3.875rem]" : "sm:pl-[4.125rem]")), children })
|
|
5350
|
+
]
|
|
5351
|
+
}
|
|
5352
|
+
);
|
|
5353
|
+
}
|
|
5354
|
+
var STATE_TONE = { good: "success", attention: "brand", bad: "danger", neutral: "neutral", quiet: "muted" };
|
|
5355
|
+
function StateBadge({
|
|
5356
|
+
tone = "neutral",
|
|
5357
|
+
children,
|
|
5358
|
+
title,
|
|
5359
|
+
className
|
|
5360
|
+
}) {
|
|
5361
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Badge, { tone: STATE_TONE[tone], title, className, children });
|
|
5362
|
+
}
|
|
5363
|
+
function createStateBadge(states) {
|
|
5364
|
+
function ProtocolStateBadge({ state, className }) {
|
|
5365
|
+
const def = states[state];
|
|
5366
|
+
if (!def) {
|
|
5367
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
|
|
5368
|
+
console.warn(`StateBadge: no state "${state}"; known: ${Object.keys(states).join(", ")}`);
|
|
5369
|
+
}
|
|
5370
|
+
return /* @__PURE__ */ jsxRuntime.jsx(StateBadge, { className, children: String(state) });
|
|
5371
|
+
}
|
|
5372
|
+
return /* @__PURE__ */ jsxRuntime.jsx(StateBadge, { tone: def.tone, title: def.hint, className, children: def.label });
|
|
5373
|
+
}
|
|
5374
|
+
return ProtocolStateBadge;
|
|
5375
|
+
}
|
|
5376
|
+
function BlockHeight({
|
|
5377
|
+
height,
|
|
5378
|
+
label = false,
|
|
5379
|
+
link = true,
|
|
5380
|
+
network = "mainnet",
|
|
5381
|
+
className
|
|
5382
|
+
}) {
|
|
5383
|
+
const text = `${label ? "block " : ""}${formatBlockHeight(height)}`;
|
|
5384
|
+
if (!link) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("oca-tabular", className), children: text });
|
|
5385
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5386
|
+
"a",
|
|
5387
|
+
{
|
|
5388
|
+
href: explorerUrl("block", Math.trunc(height), network),
|
|
5389
|
+
target: "_blank",
|
|
5390
|
+
rel: "noreferrer",
|
|
5391
|
+
title: `Block ${formatBlockHeight(height)} on mempool.space`,
|
|
5392
|
+
className: cn("oca-tabular underline decoration-foreground/35 underline-offset-4 hover:decoration-foreground", className),
|
|
5393
|
+
children: [
|
|
5394
|
+
text,
|
|
5395
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: " (opens mempool.space in a new tab)" })
|
|
5396
|
+
]
|
|
5397
|
+
}
|
|
5398
|
+
);
|
|
5399
|
+
}
|
|
5400
|
+
var ANCHOR = {
|
|
5401
|
+
anchored: { label: "Anchored", tone: "good" },
|
|
5402
|
+
pending: { label: "Anchor pending", tone: "attention" },
|
|
5403
|
+
unverified: { label: "Not checked", tone: "quiet" },
|
|
5404
|
+
none: { label: "Not anchored", tone: "quiet" },
|
|
5405
|
+
fail: { label: "Does not check out", tone: "bad" }
|
|
5406
|
+
};
|
|
5407
|
+
function hostOf(url) {
|
|
5408
|
+
try {
|
|
5409
|
+
return new URL(url).host;
|
|
5410
|
+
} catch {
|
|
5411
|
+
return url;
|
|
5412
|
+
}
|
|
5413
|
+
}
|
|
5414
|
+
function AnchorStatus({
|
|
5415
|
+
state,
|
|
5416
|
+
blockHeight,
|
|
5417
|
+
blockTime,
|
|
5418
|
+
submittedAt,
|
|
5419
|
+
calendar,
|
|
5420
|
+
message,
|
|
5421
|
+
network = "mainnet",
|
|
5422
|
+
variant = "detail",
|
|
5423
|
+
className
|
|
5424
|
+
}) {
|
|
5425
|
+
const def = ANCHOR[state];
|
|
5426
|
+
const block = blockHeight !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(BlockHeight, { height: blockHeight, label: true, network }) : null;
|
|
5427
|
+
const line = message ?? (state === "anchored" ? block ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5428
|
+
"In ",
|
|
5429
|
+
block,
|
|
5430
|
+
blockTime !== void 0 ? ` \xB7 ${formatUtc(blockTime)}` : null
|
|
5431
|
+
] }) : "Its hash is in a Bitcoin block." : state === "pending" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5432
|
+
"Submitted",
|
|
5433
|
+
submittedAt !== void 0 ? ` ${formatUtc(submittedAt)}` : "",
|
|
5434
|
+
" to",
|
|
5435
|
+
" ",
|
|
5436
|
+
calendar ? hostOf(calendar) : "an OpenTimestamps calendar",
|
|
5437
|
+
". Waiting for a Bitcoin block."
|
|
5438
|
+
] }) : state === "unverified" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5439
|
+
"The proof names ",
|
|
5440
|
+
block ?? "a block",
|
|
5441
|
+
", but its header could not be fetched to check it."
|
|
5442
|
+
] }) : state === "fail" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5443
|
+
"The proof does not lead to ",
|
|
5444
|
+
block ?? "the block it names",
|
|
5445
|
+
"."
|
|
5446
|
+
] }) : "No timestamp yet. The signature still checks offline.");
|
|
5447
|
+
if (variant === "badge") {
|
|
5448
|
+
const plain = typeof line === "string" ? line : void 0;
|
|
5449
|
+
return /* @__PURE__ */ jsxRuntime.jsx(StateBadge, { tone: def.tone, title: plain, className, children: def.label });
|
|
5450
|
+
}
|
|
5451
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col items-start gap-1.5", className), children: [
|
|
5452
|
+
/* @__PURE__ */ jsxRuntime.jsx(StateBadge, { tone: def.tone, children: def.label }),
|
|
5453
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] leading-snug text-muted-foreground", children: line })
|
|
5454
|
+
] });
|
|
5455
|
+
}
|
|
5456
|
+
function BlockCountdown({
|
|
5457
|
+
target,
|
|
5458
|
+
tip,
|
|
5459
|
+
from,
|
|
5460
|
+
reached = "Reached",
|
|
5461
|
+
minutesPerBlock = 10,
|
|
5462
|
+
network = "mainnet",
|
|
5463
|
+
className
|
|
5464
|
+
}) {
|
|
5465
|
+
const known = typeof tip === "number";
|
|
5466
|
+
const left = known ? target - tip : null;
|
|
5467
|
+
const done2 = left !== null && left <= 0;
|
|
5468
|
+
const share = known && from !== void 0 && target > from ? Math.min(1, Math.max(0, (tip - from) / (target - from))) : null;
|
|
5469
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
|
|
5470
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.9375rem] leading-snug", children: !known ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5471
|
+
"At ",
|
|
5472
|
+
/* @__PURE__ */ jsxRuntime.jsx(BlockHeight, { height: target, label: true, network })
|
|
5473
|
+
] }) : done2 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5474
|
+
reached,
|
|
5475
|
+
" at ",
|
|
5476
|
+
/* @__PURE__ */ jsxRuntime.jsx(BlockHeight, { height: target, label: true, network })
|
|
5477
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5478
|
+
"In ",
|
|
5479
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "oca-tabular font-medium", children: formatBlockHeight(left) }),
|
|
5480
|
+
" block",
|
|
5481
|
+
left === 1 ? "" : "s",
|
|
5482
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
|
|
5483
|
+
", ",
|
|
5484
|
+
blocksToDuration(left, minutesPerBlock)
|
|
5485
|
+
] })
|
|
5486
|
+
] }) }),
|
|
5487
|
+
share !== null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5488
|
+
"div",
|
|
5489
|
+
{
|
|
5490
|
+
role: "progressbar",
|
|
5491
|
+
"aria-valuemin": 0,
|
|
5492
|
+
"aria-valuemax": 100,
|
|
5493
|
+
"aria-valuenow": Math.round(share * 100),
|
|
5494
|
+
"aria-label": "Blocks passed",
|
|
5495
|
+
className: "h-1.5 overflow-hidden rounded-full bg-muted",
|
|
5496
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full rounded-full bg-foreground", style: { width: `${share * 100}%` } })
|
|
5497
|
+
}
|
|
5498
|
+
) : null,
|
|
5499
|
+
known && !done2 ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-[0.8125rem] text-muted-foreground", children: [
|
|
5500
|
+
"Target ",
|
|
5501
|
+
/* @__PURE__ */ jsxRuntime.jsx(BlockHeight, { height: target, network }),
|
|
5502
|
+
" \xB7 tip ",
|
|
5503
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "oca-tabular", children: formatBlockHeight(tip) })
|
|
5504
|
+
] }) : null
|
|
5505
|
+
] });
|
|
5506
|
+
}
|
|
5507
|
+
function Meter({
|
|
5508
|
+
value,
|
|
5509
|
+
max,
|
|
5510
|
+
ghost,
|
|
5511
|
+
label,
|
|
5512
|
+
figure,
|
|
5513
|
+
tone = "ink",
|
|
5514
|
+
size = "md",
|
|
5515
|
+
className
|
|
5516
|
+
}) {
|
|
5517
|
+
const id = react.useId();
|
|
5518
|
+
const total = max > 0 ? max : 1;
|
|
5519
|
+
const v = Math.max(0, Math.min(1, value / total));
|
|
5520
|
+
const g = ghost ? Math.max(0, Math.min(1 - v, ghost / total)) : 0;
|
|
5521
|
+
const pct = `${Math.round(v * 100)}%`;
|
|
5522
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
|
|
5523
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline justify-between gap-4 text-[0.875rem]", children: [
|
|
5524
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { id, className: "min-w-0 truncate", children: label }),
|
|
5525
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 oca-tabular text-muted-foreground", children: figure ?? pct })
|
|
5526
|
+
] }),
|
|
5527
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5528
|
+
"div",
|
|
5529
|
+
{
|
|
5530
|
+
role: "meter",
|
|
5531
|
+
"aria-labelledby": id,
|
|
5532
|
+
"aria-valuemin": 0,
|
|
5533
|
+
"aria-valuemax": max,
|
|
5534
|
+
"aria-valuenow": value,
|
|
5535
|
+
"aria-valuetext": typeof figure === "string" ? figure : pct,
|
|
5536
|
+
className: cn("flex overflow-hidden rounded-full bg-muted", size === "sm" ? "h-1.5" : "h-2.5"),
|
|
5537
|
+
children: [
|
|
5538
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5539
|
+
"div",
|
|
5540
|
+
{
|
|
5541
|
+
className: cn("h-full shrink-0 rounded-full", tone === "brand" ? "bg-oca-orange-deep" : "bg-foreground"),
|
|
5542
|
+
style: { width: `${v * 100}%` }
|
|
5543
|
+
}
|
|
5544
|
+
),
|
|
5545
|
+
g > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5546
|
+
"div",
|
|
5547
|
+
{
|
|
5548
|
+
"aria-hidden": true,
|
|
5549
|
+
className: "-ml-1.5 h-full shrink-0 rounded-r-full pl-1.5 text-foreground/45",
|
|
5550
|
+
style: {
|
|
5551
|
+
width: `calc(${g * 100}% + 0.375rem)`,
|
|
5552
|
+
backgroundImage: "repeating-linear-gradient(-45deg, currentColor 0 2px, transparent 2px 6px)"
|
|
5553
|
+
}
|
|
5554
|
+
}
|
|
5555
|
+
) : null
|
|
5556
|
+
]
|
|
5557
|
+
}
|
|
5558
|
+
)
|
|
5559
|
+
] });
|
|
5560
|
+
}
|
|
5561
|
+
function FilterChips({
|
|
5562
|
+
options,
|
|
5563
|
+
value,
|
|
5564
|
+
onChange,
|
|
5565
|
+
label,
|
|
5566
|
+
className
|
|
5567
|
+
}) {
|
|
5568
|
+
const tight = useDensity() === "compact";
|
|
5569
|
+
const multi = Array.isArray(value);
|
|
5570
|
+
const isOn = (v) => multi ? value.includes(v) : value === v;
|
|
5571
|
+
const press = (v) => {
|
|
5572
|
+
if (multi) {
|
|
5573
|
+
const cur = value;
|
|
5574
|
+
onChange(cur.includes(v) ? cur.filter((x) => x !== v) : [...cur, v]);
|
|
5575
|
+
} else onChange(v);
|
|
5576
|
+
};
|
|
5577
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--background)", className: cn("w-full", className), children: /* @__PURE__ */ jsxRuntime.jsx("div", { role: "group", "aria-label": label, className: "flex w-max items-center gap-2 py-0.5", children: options.map((o) => {
|
|
5578
|
+
const on = isOn(o.value);
|
|
5579
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5580
|
+
"button",
|
|
5581
|
+
{
|
|
5582
|
+
type: "button",
|
|
5583
|
+
"aria-pressed": on,
|
|
5584
|
+
onClick: () => press(o.value),
|
|
5585
|
+
className: cn(
|
|
5586
|
+
"inline-flex shrink-0 items-center gap-1.5 rounded-full border px-3.5 text-[0.875rem] transition-colors",
|
|
5587
|
+
tight ? "h-8" : "h-9",
|
|
5588
|
+
on ? "border-foreground bg-foreground text-background" : "border-border bg-card text-muted-foreground hover:border-oca-hairline-strong hover:text-foreground"
|
|
5589
|
+
),
|
|
5590
|
+
children: [
|
|
5591
|
+
o.label,
|
|
5592
|
+
o.count !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oca-tabular", children: o.count.toLocaleString("en-US") }) : null
|
|
5593
|
+
]
|
|
5594
|
+
},
|
|
5595
|
+
o.value
|
|
5596
|
+
);
|
|
5597
|
+
}) }) });
|
|
5598
|
+
}
|
|
5599
|
+
function ToolGrid({
|
|
5600
|
+
tools,
|
|
5601
|
+
as: Heading = "h2",
|
|
5602
|
+
className
|
|
5603
|
+
}) {
|
|
5604
|
+
const tight = useDensity() === "compact";
|
|
5605
|
+
const n = tools.length;
|
|
5606
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5607
|
+
"ul",
|
|
5608
|
+
{
|
|
5609
|
+
className: cn(
|
|
5610
|
+
"grid grid-cols-1 gap-3 sm:grid-cols-2 md:gap-4",
|
|
5611
|
+
// Three or four sit in one row on a wide screen.
|
|
5612
|
+
n === 3 || n === 6 ? "lg:grid-cols-3" : n === 4 ? "xl:grid-cols-4" : null,
|
|
5613
|
+
className
|
|
5614
|
+
),
|
|
5615
|
+
children: tools.map((t) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5616
|
+
"div",
|
|
5617
|
+
{
|
|
5618
|
+
className: cn(
|
|
5619
|
+
"group relative flex h-full flex-col rounded-[1.25rem] border border-border bg-card transition-colors",
|
|
5620
|
+
tight ? "gap-3 p-5" : "gap-4 p-6",
|
|
5621
|
+
"hover:border-oca-hairline-strong 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"
|
|
5622
|
+
),
|
|
5623
|
+
children: [
|
|
5624
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
5625
|
+
t.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-10 items-center justify-center rounded-xl bg-muted text-foreground [&_svg]:size-5", children: t.icon }) : /* @__PURE__ */ jsxRuntime.jsx("span", {}),
|
|
5626
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5627
|
+
lucideReact.ArrowRight,
|
|
5628
|
+
{
|
|
5629
|
+
"aria-hidden": true,
|
|
5630
|
+
className: "size-4 text-muted-foreground transition-transform duration-200 group-hover:translate-x-0.5 group-hover:text-foreground"
|
|
5631
|
+
}
|
|
5632
|
+
)
|
|
5633
|
+
] }),
|
|
5634
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
5635
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { className: "oca-title-sm", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5636
|
+
Link8__default.default,
|
|
5637
|
+
{
|
|
5638
|
+
href: t.href,
|
|
5639
|
+
className: "outline-none after:absolute after:inset-0 after:rounded-[1.25rem] after:content-['']",
|
|
5640
|
+
children: t.label
|
|
5641
|
+
}
|
|
5642
|
+
) }),
|
|
5643
|
+
t.description ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.9375rem] leading-relaxed text-muted-foreground", children: t.description }) : null
|
|
5644
|
+
] })
|
|
5645
|
+
]
|
|
5646
|
+
}
|
|
5647
|
+
) }, t.href))
|
|
5648
|
+
}
|
|
5649
|
+
);
|
|
5650
|
+
}
|
|
5651
|
+
function SiteRow({ site, here, onNavigate }) {
|
|
5652
|
+
return /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3584
5653
|
"a",
|
|
3585
5654
|
{
|
|
3586
5655
|
href: site.href,
|
|
@@ -3657,16 +5726,23 @@ function FamilyMenu({ current: current2, className }) {
|
|
|
3657
5726
|
)
|
|
3658
5727
|
] });
|
|
3659
5728
|
}
|
|
3660
|
-
function NavLink({
|
|
5729
|
+
function NavLink({
|
|
5730
|
+
item,
|
|
5731
|
+
className,
|
|
5732
|
+
onNavigate,
|
|
5733
|
+
line = false
|
|
5734
|
+
}) {
|
|
3661
5735
|
const cls = cn(
|
|
3662
5736
|
"rounded-full px-3 py-2 text-[0.9375rem] transition-colors",
|
|
3663
5737
|
item.active ? "text-foreground" : "text-muted-foreground hover:text-foreground",
|
|
5738
|
+
line && "relative after:absolute after:inset-x-3 after:-bottom-[0.625rem] after:h-0.5 after:rounded-full",
|
|
5739
|
+
line && item.active && "after:bg-foreground",
|
|
3664
5740
|
className
|
|
3665
5741
|
);
|
|
3666
5742
|
if (item.external) {
|
|
3667
5743
|
return /* @__PURE__ */ jsxRuntime.jsx("a", { href: item.href, className: cls, rel: "noreferrer", onClick: onNavigate, children: item.label });
|
|
3668
5744
|
}
|
|
3669
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5745
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Link8__default.default, { href: item.href, className: cls, "aria-current": item.active ? "page" : void 0, onClick: onNavigate, children: item.label });
|
|
3670
5746
|
}
|
|
3671
5747
|
function NavRow({ item, onNavigate }) {
|
|
3672
5748
|
const body = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -3677,7 +5753,7 @@ function NavRow({ item, onNavigate }) {
|
|
|
3677
5753
|
"flex flex-col gap-0.5 rounded-xl px-3 py-2 transition-colors hover:bg-accent",
|
|
3678
5754
|
item.active && "bg-muted hover:bg-muted dark:bg-white/[0.06]"
|
|
3679
5755
|
);
|
|
3680
|
-
return item.external ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: item.href, className: cls, rel: "noreferrer", onClick: onNavigate, children: body }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
5756
|
+
return item.external ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: item.href, className: cls, rel: "noreferrer", onClick: onNavigate, children: body }) : /* @__PURE__ */ jsxRuntime.jsx(Link8__default.default, { href: item.href, className: cls, "aria-current": item.active ? "page" : void 0, onClick: onNavigate, children: body });
|
|
3681
5757
|
}
|
|
3682
5758
|
var seeAll = (item) => typeof item.label === "string" ? `All ${item.label.toLowerCase()}` : "See all";
|
|
3683
5759
|
function NavDropdown({ item }) {
|
|
@@ -3719,13 +5795,16 @@ function SiteHeader({
|
|
|
3719
5795
|
search,
|
|
3720
5796
|
actions,
|
|
3721
5797
|
variant = "site",
|
|
5798
|
+
navOnPhone = true,
|
|
5799
|
+
menu: menuExtra,
|
|
3722
5800
|
className
|
|
3723
5801
|
}) {
|
|
3724
5802
|
const [open, setOpen] = react.useState(false);
|
|
3725
5803
|
const tool = variant === "tool";
|
|
3726
5804
|
const size = tool ? 24 : 28;
|
|
3727
5805
|
const current2 = typeof family === "string" ? family : void 0;
|
|
3728
|
-
const
|
|
5806
|
+
const phoneNav = navOnPhone ? nav : [];
|
|
5807
|
+
const menu = phoneNav.length > 0 || Boolean(family) || Boolean(menuExtra);
|
|
3729
5808
|
const brandNode = brand ?? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center", children: [
|
|
3730
5809
|
/* @__PURE__ */ jsxRuntime.jsx(Lockup, { size }),
|
|
3731
5810
|
product ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -3733,7 +5812,9 @@ function SiteHeader({
|
|
|
3733
5812
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium tracking-[-0.01em]", style: { fontSize: size * 0.56 }, children: product })
|
|
3734
5813
|
] }) : null
|
|
3735
5814
|
] });
|
|
3736
|
-
const navigation = nav.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Main", className: "hidden items-center gap-1 md:flex", children: nav.map(
|
|
5815
|
+
const navigation = nav.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Main", className: "hidden items-center gap-1 md:flex", children: nav.map(
|
|
5816
|
+
(n) => n.children?.length ? /* @__PURE__ */ jsxRuntime.jsx(NavDropdown, { item: n }, n.href) : /* @__PURE__ */ jsxRuntime.jsx(NavLink, { item: n, line: tool }, n.href)
|
|
5817
|
+
) }) : null;
|
|
3737
5818
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3738
5819
|
"header",
|
|
3739
5820
|
{
|
|
@@ -3755,7 +5836,7 @@ function SiteHeader({
|
|
|
3755
5836
|
),
|
|
3756
5837
|
children: [
|
|
3757
5838
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex min-w-0 items-center gap-1", tool ? "md:gap-1" : "justify-self-start"), children: [
|
|
3758
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5839
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Link8__default.default, { href: home, className: "-ml-1 min-w-0 rounded-lg p-1", children: [
|
|
3759
5840
|
brandNode,
|
|
3760
5841
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: " home" })
|
|
3761
5842
|
] }),
|
|
@@ -3777,7 +5858,8 @@ function SiteHeader({
|
|
|
3777
5858
|
),
|
|
3778
5859
|
/* @__PURE__ */ jsxRuntime.jsxs(SheetContent, { side: "right", className: "pt-16", children: [
|
|
3779
5860
|
/* @__PURE__ */ jsxRuntime.jsx(SheetTitle, { className: "sr-only", children: "Menu" }),
|
|
3780
|
-
|
|
5861
|
+
menuExtra ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col", (phoneNav.length > 0 || family) && "border-b border-border pb-3"), children: menuExtra }) : null,
|
|
5862
|
+
phoneNav.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Main", className: "flex flex-col", children: phoneNav.map(
|
|
3781
5863
|
(n) => n.children?.length ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col py-2", children: [
|
|
3782
5864
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-3 pb-1 text-[0.8125rem] text-muted-foreground", children: n.label }),
|
|
3783
5865
|
n.children.map((c) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3799,7 +5881,7 @@ function SiteHeader({
|
|
|
3799
5881
|
n.href
|
|
3800
5882
|
)
|
|
3801
5883
|
) }) : null,
|
|
3802
|
-
family ? /* @__PURE__ */ jsxRuntime.jsxs("details", { className: cn("group",
|
|
5884
|
+
family ? /* @__PURE__ */ jsxRuntime.jsxs("details", { className: cn("group", phoneNav.length > 0 && "mt-2 border-t border-border pt-4"), children: [
|
|
3803
5885
|
/* @__PURE__ */ jsxRuntime.jsxs("summary", { className: "flex cursor-pointer list-none items-center justify-between rounded-xl px-3 py-2.5 text-[1.0625rem] [&::-webkit-details-marker]:hidden", children: [
|
|
3804
5886
|
"All orangecheck sites",
|
|
3805
5887
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { "aria-hidden": true, className: "size-4 text-muted-foreground transition-transform group-open:rotate-180" })
|
|
@@ -3966,12 +6048,12 @@ function SignInFrame({
|
|
|
3966
6048
|
children: [
|
|
3967
6049
|
/* @__PURE__ */ jsxRuntime.jsxs("section", { className: "flex flex-col px-4 pb-8 pt-5 sm:px-8 lg:px-14 lg:pt-8", children: [
|
|
3968
6050
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex items-center justify-between gap-4", children: [
|
|
3969
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6051
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Link8__default.default, { href: home, className: "w-fit rounded-lg", children: [
|
|
3970
6052
|
brand ?? /* @__PURE__ */ jsxRuntime.jsx(Lockup, { size: 28 }),
|
|
3971
6053
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: " home" })
|
|
3972
6054
|
] }),
|
|
3973
6055
|
back === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3974
|
-
|
|
6056
|
+
Link8__default.default,
|
|
3975
6057
|
{
|
|
3976
6058
|
href: home,
|
|
3977
6059
|
className: "text-[0.9375rem] text-muted-foreground underline-offset-4 hover:text-foreground hover:underline",
|
|
@@ -4004,11 +6086,156 @@ function SignInFrame({
|
|
|
4004
6086
|
}
|
|
4005
6087
|
);
|
|
4006
6088
|
}
|
|
6089
|
+
var STATUS_WORDS = /* @__PURE__ */ new Set(["live", "testing", "not-yet", "paused", "good", "caution", "refused"]);
|
|
6090
|
+
var pathOf = (href) => href.split(/[?#]/)[0].replace(/(.)\/$/, "$1");
|
|
6091
|
+
function DocsNav({
|
|
6092
|
+
sections,
|
|
6093
|
+
current: current2,
|
|
6094
|
+
onNavigate,
|
|
6095
|
+
className
|
|
6096
|
+
}) {
|
|
6097
|
+
const here = pathOf(current2);
|
|
6098
|
+
const activeSection = react.useMemo(
|
|
6099
|
+
() => sections.findIndex((s) => s.items.some((i) => pathOf(i.href) === here)),
|
|
6100
|
+
[sections, here]
|
|
6101
|
+
);
|
|
6102
|
+
const [peeked, setPeeked] = react.useState(() => /* @__PURE__ */ new Set());
|
|
6103
|
+
react.useEffect(() => setPeeked(/* @__PURE__ */ new Set()), [activeSection]);
|
|
6104
|
+
const activeRef = react.useRef(null);
|
|
6105
|
+
react.useEffect(() => {
|
|
6106
|
+
const id = requestAnimationFrame(() => activeRef.current?.scrollIntoView({ block: "nearest" }));
|
|
6107
|
+
return () => cancelAnimationFrame(id);
|
|
6108
|
+
}, [here]);
|
|
6109
|
+
const base = react.useId();
|
|
6110
|
+
return /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Docs", className: cn("flex flex-col gap-0.5", className), children: sections.map((section, si) => {
|
|
6111
|
+
const isActive = si === activeSection;
|
|
6112
|
+
const open = isActive || peeked.has(si);
|
|
6113
|
+
const panel = `${base}-s${si}`;
|
|
6114
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
6115
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6116
|
+
"button",
|
|
6117
|
+
{
|
|
6118
|
+
type: "button",
|
|
6119
|
+
"aria-expanded": open,
|
|
6120
|
+
"aria-controls": panel,
|
|
6121
|
+
onClick: () => {
|
|
6122
|
+
if (isActive) return;
|
|
6123
|
+
setPeeked((p) => {
|
|
6124
|
+
const n = new Set(p);
|
|
6125
|
+
if (n.has(si)) n.delete(si);
|
|
6126
|
+
else n.add(si);
|
|
6127
|
+
return n;
|
|
6128
|
+
});
|
|
6129
|
+
},
|
|
6130
|
+
className: cn(
|
|
6131
|
+
"flex min-h-9 w-full items-center justify-between gap-2 rounded-lg px-2.5 py-1.5 text-left text-[0.875rem] transition-colors",
|
|
6132
|
+
isActive ? "font-medium text-foreground" : "text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
6133
|
+
isActive && "cursor-default"
|
|
6134
|
+
),
|
|
6135
|
+
children: [
|
|
6136
|
+
section.label,
|
|
6137
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6138
|
+
lucideReact.ChevronRight,
|
|
6139
|
+
{
|
|
6140
|
+
"aria-hidden": true,
|
|
6141
|
+
className: cn("size-3.5 shrink-0 text-oca-subtle transition-transform duration-200", open && "rotate-90")
|
|
6142
|
+
}
|
|
6143
|
+
)
|
|
6144
|
+
]
|
|
6145
|
+
}
|
|
6146
|
+
),
|
|
6147
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { id: panel, hidden: !open, className: "mb-2 ml-2.5 mt-0.5 border-l border-border", children: section.items.map((item) => {
|
|
6148
|
+
const on = pathOf(item.href) === here;
|
|
6149
|
+
const badge = typeof item.badge === "string" && STATUS_WORDS.has(item.badge) ? /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: item.badge }) : item.badge ? /* @__PURE__ */ jsxRuntime.jsx(Badge, { tone: "muted", children: item.badge }) : null;
|
|
6150
|
+
return /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6151
|
+
Link8__default.default,
|
|
6152
|
+
{
|
|
6153
|
+
href: item.href,
|
|
6154
|
+
ref: on ? activeRef : void 0,
|
|
6155
|
+
onClick: onNavigate,
|
|
6156
|
+
"aria-current": on ? "page" : void 0,
|
|
6157
|
+
className: cn(
|
|
6158
|
+
"-ml-px flex min-h-9 items-center gap-2 border-l-2 py-1.5 pl-3.5 pr-2 text-[0.875rem] leading-snug transition-colors",
|
|
6159
|
+
on ? "border-foreground font-medium text-foreground" : "border-transparent text-muted-foreground hover:border-oca-hairline-strong hover:text-foreground"
|
|
6160
|
+
),
|
|
6161
|
+
children: [
|
|
6162
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1", children: item.label }),
|
|
6163
|
+
badge
|
|
6164
|
+
]
|
|
6165
|
+
}
|
|
6166
|
+
) }, item.href);
|
|
6167
|
+
}) })
|
|
6168
|
+
] }, section.label);
|
|
6169
|
+
}) });
|
|
6170
|
+
}
|
|
6171
|
+
var DOCS_HEADER_NAV = OCHK_IO_NAV.map((n) => n.href === DOCS_HREF ? { ...n, active: true } : n);
|
|
6172
|
+
function DocsShell({
|
|
6173
|
+
nav,
|
|
6174
|
+
current: current2,
|
|
6175
|
+
header,
|
|
6176
|
+
search,
|
|
6177
|
+
actions,
|
|
6178
|
+
breadcrumbs,
|
|
6179
|
+
toc,
|
|
6180
|
+
pager,
|
|
6181
|
+
footer,
|
|
6182
|
+
children
|
|
6183
|
+
}) {
|
|
6184
|
+
const [menu, setMenu] = react.useState(false);
|
|
6185
|
+
react.useEffect(() => setMenu(false), [current2]);
|
|
6186
|
+
const read = useHeadings("#docs-content", current2);
|
|
6187
|
+
const items = toc ?? read.items;
|
|
6188
|
+
const activeId = toc ? void 0 : read.activeId;
|
|
6189
|
+
const here = pathOf(current2);
|
|
6190
|
+
const place = react.useMemo(() => {
|
|
6191
|
+
for (const s of nav) {
|
|
6192
|
+
const it = s.items.find((i) => pathOf(i.href) === here);
|
|
6193
|
+
if (it) return { section: s.label, page: it.label };
|
|
6194
|
+
}
|
|
6195
|
+
return null;
|
|
6196
|
+
}, [nav, here]);
|
|
6197
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-dvh flex-col bg-background", children: [
|
|
6198
|
+
/* @__PURE__ */ jsxRuntime.jsx(SkipLink, {}),
|
|
6199
|
+
header ?? /* @__PURE__ */ jsxRuntime.jsx(SiteHeader, { home: OCHK_IO, family: "docs", nav: DOCS_HEADER_NAV, search, actions }),
|
|
6200
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-16 z-30 border-b border-border bg-background/95 backdrop-blur-md supports-[backdrop-filter]:bg-background/90 md:top-[4.5rem] lg:hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oca-container flex h-12 items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsxs(Sheet, { open: menu, onOpenChange: setMenu, children: [
|
|
6201
|
+
/* @__PURE__ */ jsxRuntime.jsxs(SheetTrigger, { className: "-ml-2 inline-flex h-10 min-w-0 items-center gap-2 rounded-full px-2.5 text-[0.875rem] hover:bg-accent", children: [
|
|
6202
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelLeft, { "aria-hidden": true, className: "size-[1.125rem] shrink-0" }),
|
|
6203
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Docs menu. " }),
|
|
6204
|
+
place ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-1.5", children: [
|
|
6205
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-muted-foreground", children: place.section }),
|
|
6206
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": true, className: "size-3.5 shrink-0 text-oca-subtle" }),
|
|
6207
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-medium", children: place.page })
|
|
6208
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Docs" })
|
|
6209
|
+
] }),
|
|
6210
|
+
/* @__PURE__ */ jsxRuntime.jsxs(SheetContent, { side: "left", className: "w-[min(88vw,22rem)] gap-0 p-0", children: [
|
|
6211
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-border px-5 py-4 pr-14", children: /* @__PURE__ */ jsxRuntime.jsx(SheetTitle, { className: "text-[1.0625rem] font-medium", children: "Docs" }) }),
|
|
6212
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-y-auto p-3", children: /* @__PURE__ */ jsxRuntime.jsx(DocsNav, { sections: nav, current: current2, onNavigate: () => setMenu(false) }) })
|
|
6213
|
+
] })
|
|
6214
|
+
] }) }) }),
|
|
6215
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "oca-container flex-1", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lg:grid lg:grid-cols-[13.5rem_minmax(0,1fr)] lg:gap-x-10 xl:grid-cols-[13.5rem_minmax(0,1fr)_11rem]", children: [
|
|
6216
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-[4.5rem] hidden max-h-[calc(100dvh-4.5rem)] self-start overflow-y-auto overscroll-contain py-8 pr-1 lg:block", children: /* @__PURE__ */ jsxRuntime.jsx(DocsNav, { sections: nav, current: current2 }) }),
|
|
6217
|
+
/* @__PURE__ */ jsxRuntime.jsxs("main", { id: "main-content", className: "min-w-0 pb-16 pt-6 md:pt-8", children: [
|
|
6218
|
+
breadcrumbs ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-6 max-lg:hidden", children: breadcrumbs }) : null,
|
|
6219
|
+
items.length > 1 ? /* @__PURE__ */ jsxRuntime.jsxs("details", { className: "group mb-8 rounded-2xl border border-border bg-card xl:hidden", children: [
|
|
6220
|
+
/* @__PURE__ */ jsxRuntime.jsxs("summary", { className: "flex min-h-12 cursor-pointer list-none items-center justify-between px-4 text-[0.9375rem] font-medium [&::-webkit-details-marker]:hidden", children: [
|
|
6221
|
+
"On this page",
|
|
6222
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { "aria-hidden": true, className: "size-4 text-muted-foreground transition-transform group-open:rotate-180" })
|
|
6223
|
+
] }),
|
|
6224
|
+
/* @__PURE__ */ jsxRuntime.jsx(OnThisPage, { items, activeId, title: null, className: "px-4 pb-4" })
|
|
6225
|
+
] }) : null,
|
|
6226
|
+
/* @__PURE__ */ jsxRuntime.jsx("article", { id: "docs-content", className: "max-w-[46rem]", children }),
|
|
6227
|
+
pager ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-16 max-w-[46rem]", children: pager }) : null
|
|
6228
|
+
] }),
|
|
6229
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-[4.5rem] hidden max-h-[calc(100dvh-4.5rem)] self-start overflow-y-auto py-10 xl:block", children: items.length > 1 ? /* @__PURE__ */ jsxRuntime.jsx(OnThisPage, { items, activeId }) : null })
|
|
6230
|
+
] }) }),
|
|
6231
|
+
footer ?? /* @__PURE__ */ jsxRuntime.jsx(SiteFooter, { columns: OCHK_IO_FOOTER, family: true, legal: true, signature: false })
|
|
6232
|
+
] });
|
|
6233
|
+
}
|
|
4007
6234
|
function SideNav({ groups, onNavigate }) {
|
|
4008
6235
|
return /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Pages", className: "flex flex-col gap-5", children: groups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
4009
6236
|
g.label ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-3 pb-1 text-[0.8125rem] text-muted-foreground", children: g.label }) : null,
|
|
4010
6237
|
g.items.map((it) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4011
|
-
|
|
6238
|
+
Link8__default.default,
|
|
4012
6239
|
{
|
|
4013
6240
|
href: it.href,
|
|
4014
6241
|
onClick: onNavigate,
|
|
@@ -4043,7 +6270,7 @@ function SectionSwitch({
|
|
|
4043
6270
|
children: sections.map((sec) => {
|
|
4044
6271
|
const on = sec.id === current2.id;
|
|
4045
6272
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4046
|
-
|
|
6273
|
+
Link8__default.default,
|
|
4047
6274
|
{
|
|
4048
6275
|
href: sec.href,
|
|
4049
6276
|
onClick: onNavigate,
|
|
@@ -4073,7 +6300,7 @@ function TabBar({ items }) {
|
|
|
4073
6300
|
className: "mx-auto grid h-14 max-w-[32rem] px-1.5",
|
|
4074
6301
|
style: { gridTemplateColumns: `repeat(${items.length}, minmax(0, 1fr))` },
|
|
4075
6302
|
children: items.map((it) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4076
|
-
|
|
6303
|
+
Link8__default.default,
|
|
4077
6304
|
{
|
|
4078
6305
|
href: it.href,
|
|
4079
6306
|
"aria-current": it.active ? "page" : void 0,
|
|
@@ -4182,7 +6409,7 @@ function AppShell({
|
|
|
4182
6409
|
footer ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto flex flex-col gap-3", children: footer }) : null
|
|
4183
6410
|
] })
|
|
4184
6411
|
] }),
|
|
4185
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6412
|
+
/* @__PURE__ */ jsxRuntime.jsx(Link8__default.default, { href: home, "aria-label": "Home", className: "rounded-lg p-1", children: /* @__PURE__ */ jsxRuntime.jsx(Lockup, { size: 22 }) }),
|
|
4186
6413
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto flex items-center", children: account })
|
|
4187
6414
|
] }),
|
|
4188
6415
|
place.page ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -4205,7 +6432,7 @@ function AppShell({
|
|
|
4205
6432
|
] }),
|
|
4206
6433
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto flex w-full max-w-[90rem]", children: [
|
|
4207
6434
|
/* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "sticky top-0 hidden h-dvh w-[17rem] shrink-0 flex-col gap-6 overflow-y-auto px-4 py-6 lg:flex", children: [
|
|
4208
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6435
|
+
/* @__PURE__ */ jsxRuntime.jsx(Link8__default.default, { href: home, className: "px-2", "aria-label": "Home", children: /* @__PURE__ */ jsxRuntime.jsx(Lockup, { size: 26 }) }),
|
|
4209
6436
|
switcher,
|
|
4210
6437
|
/* @__PURE__ */ jsxRuntime.jsx(SideNav, { groups }),
|
|
4211
6438
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto flex flex-col gap-3", children: footer })
|
|
@@ -4236,9 +6463,16 @@ function AccountMenu({
|
|
|
4236
6463
|
"inline-flex h-10 items-center gap-2.5 rounded-full border border-border bg-card pl-1 pr-1 text-[0.9375rem] outline-none transition-colors hover:border-oca-hairline-strong focus-visible:ring-2 focus-visible:ring-ring",
|
|
4237
6464
|
nameFrom === "lg" ? "lg:pr-3.5" : "sm:pr-3.5"
|
|
4238
6465
|
),
|
|
4239
|
-
"aria-label":
|
|
6466
|
+
"aria-label": `${name}, account menu`,
|
|
4240
6467
|
children: [
|
|
4241
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6468
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6469
|
+
"span",
|
|
6470
|
+
{
|
|
6471
|
+
"aria-hidden": true,
|
|
6472
|
+
"data-initial": initial,
|
|
6473
|
+
className: "flex size-8 items-center justify-center rounded-full bg-foreground text-[0.8125rem] font-medium text-background before:content-[attr(data-initial)]"
|
|
6474
|
+
}
|
|
6475
|
+
),
|
|
4242
6476
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("max-w-[10rem] truncate", nameFrom === "lg" ? "max-lg:hidden" : "max-sm:hidden"), children: name })
|
|
4243
6477
|
]
|
|
4244
6478
|
}
|
|
@@ -4250,7 +6484,7 @@ function AccountMenu({
|
|
|
4250
6484
|
] }),
|
|
4251
6485
|
/* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
|
|
4252
6486
|
items.map(
|
|
4253
|
-
(it, i) => it === "separator" ? /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}, `sep-${i}`) : it.href ? /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuItem, { asChild: true, destructive: it.destructive, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6487
|
+
(it, i) => it === "separator" ? /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}, `sep-${i}`) : it.href ? /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuItem, { asChild: true, destructive: it.destructive, children: /* @__PURE__ */ jsxRuntime.jsxs(Link8__default.default, { href: it.href, children: [
|
|
4254
6488
|
it.icon,
|
|
4255
6489
|
it.label
|
|
4256
6490
|
] }) }, it.label) : /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { onSelect: it.onSelect, destructive: it.destructive, children: [
|
|
@@ -4283,6 +6517,259 @@ function ThemeToggle({ className }) {
|
|
|
4283
6517
|
}
|
|
4284
6518
|
);
|
|
4285
6519
|
}
|
|
6520
|
+
var OCHK_APP_ACCOUNT = "https://ochk.app/me/account";
|
|
6521
|
+
function SessionAccountView({
|
|
6522
|
+
state,
|
|
6523
|
+
name,
|
|
6524
|
+
detail,
|
|
6525
|
+
items = [],
|
|
6526
|
+
signInHref,
|
|
6527
|
+
signInLabel = "Sign in",
|
|
6528
|
+
accountHref = OCHK_APP_ACCOUNT,
|
|
6529
|
+
onSignOut,
|
|
6530
|
+
nameFrom = "lg"
|
|
6531
|
+
}) {
|
|
6532
|
+
if (state === "in") {
|
|
6533
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6534
|
+
AccountMenu,
|
|
6535
|
+
{
|
|
6536
|
+
name: name || "Your account",
|
|
6537
|
+
detail,
|
|
6538
|
+
nameFrom,
|
|
6539
|
+
items: [
|
|
6540
|
+
...items,
|
|
6541
|
+
...items.length > 0 ? ["separator"] : [],
|
|
6542
|
+
{ label: "Your account", href: accountHref, icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleUser, {}) },
|
|
6543
|
+
"separator",
|
|
6544
|
+
{ label: "Sign out", onSelect: onSignOut, icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LogOut, {}) }
|
|
6545
|
+
]
|
|
6546
|
+
}
|
|
6547
|
+
);
|
|
6548
|
+
}
|
|
6549
|
+
if (state === "unknown") {
|
|
6550
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Button, { asChild: true, size: "sm", variant: "secondary", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: accountHref, children: "Your account" }) });
|
|
6551
|
+
}
|
|
6552
|
+
return (
|
|
6553
|
+
// No box of its own: it sits exactly where the signed-in chip will. While checking it is only unseen.
|
|
6554
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: state === "checking" ? "contents invisible" : "contents", "aria-hidden": state === "checking" || void 0, children: /* @__PURE__ */ jsxRuntime.jsx(Button, { asChild: true, size: "sm", variant: "secondary", tabIndex: state === "checking" ? -1 : void 0, children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: signInHref, children: signInLabel }) }) })
|
|
6555
|
+
);
|
|
6556
|
+
}
|
|
6557
|
+
function ToolShell({
|
|
6558
|
+
protocol: protocol2,
|
|
6559
|
+
tools,
|
|
6560
|
+
home = "/",
|
|
6561
|
+
account,
|
|
6562
|
+
rail = false,
|
|
6563
|
+
railFooter,
|
|
6564
|
+
variant = "tool",
|
|
6565
|
+
banner,
|
|
6566
|
+
footer,
|
|
6567
|
+
children
|
|
6568
|
+
}) {
|
|
6569
|
+
const p = protocolSite(protocol2);
|
|
6570
|
+
const app = variant === "app";
|
|
6571
|
+
const tabs = app ? null : tabsFor([{ items: [...tools] }]);
|
|
6572
|
+
const about = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6573
|
+
"a",
|
|
6574
|
+
{
|
|
6575
|
+
href: p.pageHref,
|
|
6576
|
+
className: "inline-flex items-center gap-1 rounded-full px-3 py-2 text-[0.9375rem] text-muted-foreground transition-colors hover:text-foreground",
|
|
6577
|
+
children: [
|
|
6578
|
+
"About ",
|
|
6579
|
+
p.label,
|
|
6580
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUpRight, { "aria-hidden": true, className: "size-3.5" })
|
|
6581
|
+
]
|
|
6582
|
+
}
|
|
6583
|
+
);
|
|
6584
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DensityProvider, { density: "compact", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6585
|
+
"div",
|
|
6586
|
+
{
|
|
6587
|
+
className: cn(
|
|
6588
|
+
"flex flex-col bg-background",
|
|
6589
|
+
app ? "h-dvh overflow-hidden" : "min-h-dvh",
|
|
6590
|
+
tabs && "max-md:pb-[calc(3.5rem_+_env(safe-area-inset-bottom))]"
|
|
6591
|
+
),
|
|
6592
|
+
children: [
|
|
6593
|
+
/* @__PURE__ */ jsxRuntime.jsx(SkipLink, {}),
|
|
6594
|
+
banner,
|
|
6595
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6596
|
+
SiteHeader,
|
|
6597
|
+
{
|
|
6598
|
+
variant: "tool",
|
|
6599
|
+
home,
|
|
6600
|
+
product: p.label,
|
|
6601
|
+
family: protocol2,
|
|
6602
|
+
nav: tools.map((t) => ({ href: t.href, label: t.label, active: t.active })),
|
|
6603
|
+
navOnPhone: !tabs,
|
|
6604
|
+
menu: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "[&>a]:px-3 [&>a]:py-3 [&>a]:text-[1.0625rem]", children: about }),
|
|
6605
|
+
className: cn(rail && "lg:[&_nav[aria-label=Main]]:hidden"),
|
|
6606
|
+
actions: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
6607
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden lg:contents", children: about }),
|
|
6608
|
+
p.status !== "live" ? /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: p.status, className: "max-sm:hidden" }) : null,
|
|
6609
|
+
/* @__PURE__ */ jsxRuntime.jsx(ThemeToggle, { className: "max-sm:hidden" }),
|
|
6610
|
+
account
|
|
6611
|
+
] })
|
|
6612
|
+
}
|
|
6613
|
+
),
|
|
6614
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("mx-auto flex w-full", app ? "min-h-0 flex-1" : "max-w-[90rem] flex-1"), children: [
|
|
6615
|
+
rail ? /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "sticky top-14 hidden h-[calc(100dvh-3.5rem)] w-60 shrink-0 flex-col gap-6 overflow-y-auto px-4 py-6 lg:flex", children: [
|
|
6616
|
+
/* @__PURE__ */ jsxRuntime.jsx(SideNav, { groups: [{ label: "Tools", items: tools.map(({ href, label, icon, active }) => ({ href, label, icon, active })) }] }),
|
|
6617
|
+
railFooter ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto flex flex-col gap-0.5 px-3 text-[0.875rem] text-muted-foreground [&_a:hover]:text-foreground [&_a]:py-1.5 [&_a]:transition-colors", children: railFooter }) : null
|
|
6618
|
+
] }) : null,
|
|
6619
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6620
|
+
"main",
|
|
6621
|
+
{
|
|
6622
|
+
id: "main-content",
|
|
6623
|
+
className: cn("min-w-0 flex-1", app ? "flex min-h-0 flex-col" : "px-4 pb-16 pt-8 md:px-8 md:pt-10"),
|
|
6624
|
+
children: app ? children : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto w-full max-w-[72rem]", children })
|
|
6625
|
+
}
|
|
6626
|
+
)
|
|
6627
|
+
] }),
|
|
6628
|
+
app || footer === false ? null : footer ?? /* @__PURE__ */ jsxRuntime.jsx(SiteFooter, { compact: true, family: true, legal: true }),
|
|
6629
|
+
tabs ? /* @__PURE__ */ jsxRuntime.jsx(TabBar, { items: tabs }) : null
|
|
6630
|
+
]
|
|
6631
|
+
}
|
|
6632
|
+
) });
|
|
6633
|
+
}
|
|
6634
|
+
|
|
6635
|
+
// src/code/rehype.ts
|
|
6636
|
+
function textOf(node) {
|
|
6637
|
+
if (node.type === "text") return node.value ?? "";
|
|
6638
|
+
return (node.children ?? []).map(textOf).join("");
|
|
6639
|
+
}
|
|
6640
|
+
function langOf(code) {
|
|
6641
|
+
const cls = code.properties?.className;
|
|
6642
|
+
const list = Array.isArray(cls) ? cls : typeof cls === "string" ? cls.split(" ") : [];
|
|
6643
|
+
for (const c of list) {
|
|
6644
|
+
const m = String(c).match(/^language-(.+)$/);
|
|
6645
|
+
if (m) return m[1];
|
|
6646
|
+
}
|
|
6647
|
+
return void 0;
|
|
6648
|
+
}
|
|
6649
|
+
function rehypeCode(options = {}) {
|
|
6650
|
+
const skip = new Set(options.skip ?? ["mermaid"]);
|
|
6651
|
+
const visit = (node) => {
|
|
6652
|
+
for (const child of node.children ?? []) {
|
|
6653
|
+
const code = child.type === "element" && child.tagName === "pre" ? child.children?.[0] : void 0;
|
|
6654
|
+
if (code && code.type === "element" && code.tagName === "code" && child.children?.length === 1) {
|
|
6655
|
+
const lang = langOf(code);
|
|
6656
|
+
if (lang && skip.has(lang)) continue;
|
|
6657
|
+
const meta = parseCodeMeta(code.data?.meta);
|
|
6658
|
+
let source = textOf(code);
|
|
6659
|
+
const diff = meta.diff || lang === "diff" ? readDiff(source) : null;
|
|
6660
|
+
if (diff) source = diff.code;
|
|
6661
|
+
const lines = options.tokenize?.(source, lang) ?? highlight(source, lang === "diff" ? void 0 : lang);
|
|
6662
|
+
child.properties = {
|
|
6663
|
+
...child.properties,
|
|
6664
|
+
dataOcaCode: "",
|
|
6665
|
+
dataHtml: linesToHtml(lines, { highlight: parseLineRanges(meta.highlight), diff: diff?.diff }),
|
|
6666
|
+
...lang ? { dataLang: lang } : {},
|
|
6667
|
+
...meta.title ? { dataTitle: meta.title } : {},
|
|
6668
|
+
...diff ? { dataDiff: "" } : {},
|
|
6669
|
+
...meta.lineNumbers ? { dataLineNumbers: "" } : {}
|
|
6670
|
+
};
|
|
6671
|
+
child.children = [];
|
|
6672
|
+
continue;
|
|
6673
|
+
}
|
|
6674
|
+
visit(child);
|
|
6675
|
+
}
|
|
6676
|
+
};
|
|
6677
|
+
return (tree) => visit(tree);
|
|
6678
|
+
}
|
|
6679
|
+
function createMdxComponents({ mermaid } = {}) {
|
|
6680
|
+
function Pre(props) {
|
|
6681
|
+
if (props["data-oca-code"] !== void 0) {
|
|
6682
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6683
|
+
CodeBlock,
|
|
6684
|
+
{
|
|
6685
|
+
html: props["data-html"] ?? "",
|
|
6686
|
+
lang: props["data-lang"],
|
|
6687
|
+
caption: props["data-title"],
|
|
6688
|
+
diff: props["data-diff"] !== void 0,
|
|
6689
|
+
lineNumbers: props["data-line-numbers"] !== void 0,
|
|
6690
|
+
className: "my-6"
|
|
6691
|
+
}
|
|
6692
|
+
);
|
|
6693
|
+
}
|
|
6694
|
+
const lang = codeLang(props.children);
|
|
6695
|
+
const code = codeText(props.children);
|
|
6696
|
+
if (lang === "mermaid" && mermaid) return /* @__PURE__ */ jsxRuntime.jsx(Diagram, { chart: code, load: mermaid });
|
|
6697
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6698
|
+
CodeBlock,
|
|
6699
|
+
{
|
|
6700
|
+
code,
|
|
6701
|
+
lang: lang === "mermaid" ? void 0 : lang,
|
|
6702
|
+
caption: lang === "mermaid" ? "Diagram source" : void 0,
|
|
6703
|
+
className: "my-6"
|
|
6704
|
+
}
|
|
6705
|
+
);
|
|
6706
|
+
}
|
|
6707
|
+
function A({ href, children, ...rest }) {
|
|
6708
|
+
if (!href || href.startsWith("#")) {
|
|
6709
|
+
return /* @__PURE__ */ jsxRuntime.jsx("a", { href, ...rest, className: "text-foreground underline decoration-foreground/35 underline-offset-4 hover:decoration-foreground", children });
|
|
6710
|
+
}
|
|
6711
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TextLink, { href, children });
|
|
6712
|
+
}
|
|
6713
|
+
const heading = (as) => function Heading(props) {
|
|
6714
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DocsHeading, { as, ...props });
|
|
6715
|
+
};
|
|
6716
|
+
return {
|
|
6717
|
+
h1: heading("h1"),
|
|
6718
|
+
h2: heading("h2"),
|
|
6719
|
+
h3: heading("h3"),
|
|
6720
|
+
h4: heading("h4"),
|
|
6721
|
+
p: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("my-4 text-[1rem] leading-[1.75] text-muted-foreground md:text-[1.0625rem]", className), ...props }),
|
|
6722
|
+
a: A,
|
|
6723
|
+
strong: (props) => /* @__PURE__ */ jsxRuntime.jsx("strong", { className: "font-medium text-foreground", ...props }),
|
|
6724
|
+
ul: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6725
|
+
"ul",
|
|
6726
|
+
{
|
|
6727
|
+
className: cn(
|
|
6728
|
+
"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]",
|
|
6729
|
+
className
|
|
6730
|
+
),
|
|
6731
|
+
...props
|
|
6732
|
+
}
|
|
6733
|
+
),
|
|
6734
|
+
ol: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6735
|
+
"ol",
|
|
6736
|
+
{
|
|
6737
|
+
className: cn(
|
|
6738
|
+
"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]",
|
|
6739
|
+
className
|
|
6740
|
+
),
|
|
6741
|
+
...props
|
|
6742
|
+
}
|
|
6743
|
+
),
|
|
6744
|
+
li: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: cn("pl-1 [&>p]:my-1 [&>ul]:my-1.5 [&>ol]:my-1.5", className), ...props }),
|
|
6745
|
+
blockquote: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx(Callout, { children }),
|
|
6746
|
+
hr: () => /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "my-10 border-border" }),
|
|
6747
|
+
table: MdxTable,
|
|
6748
|
+
code: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6749
|
+
"code",
|
|
6750
|
+
{
|
|
6751
|
+
className: cn("break-words rounded-md bg-muted px-1.5 py-0.5 font-mono text-[0.875em] text-foreground", className),
|
|
6752
|
+
...props
|
|
6753
|
+
}
|
|
6754
|
+
),
|
|
6755
|
+
pre: Pre,
|
|
6756
|
+
img: ({ className, alt = "", ...props }) => /* @__PURE__ */ jsxRuntime.jsx("img", { alt, loading: "lazy", className: cn("my-6 h-auto max-w-full rounded-2xl border border-border", className), ...props }),
|
|
6757
|
+
Callout,
|
|
6758
|
+
Steps,
|
|
6759
|
+
Step,
|
|
6760
|
+
LinkCard,
|
|
6761
|
+
CardGrid,
|
|
6762
|
+
ApiTable,
|
|
6763
|
+
CodeBlock,
|
|
6764
|
+
CodeTabs,
|
|
6765
|
+
InstallTabs,
|
|
6766
|
+
SpecCard,
|
|
6767
|
+
ProtocolGrid,
|
|
6768
|
+
StatusBadge,
|
|
6769
|
+
...mermaid ? { Diagram: (p) => /* @__PURE__ */ jsxRuntime.jsx(Diagram, { ...p, load: mermaid }) } : {}
|
|
6770
|
+
};
|
|
6771
|
+
}
|
|
6772
|
+
var mdxComponents = createMdxComponents();
|
|
4286
6773
|
|
|
4287
6774
|
Object.defineProperty(exports, "toast", {
|
|
4288
6775
|
enumerable: true,
|
|
@@ -4295,29 +6782,42 @@ exports.Accordion = Accordion;
|
|
|
4295
6782
|
exports.AccordionItem = AccordionItem;
|
|
4296
6783
|
exports.AccountMenu = AccountMenu;
|
|
4297
6784
|
exports.ActivityList = ActivityList;
|
|
6785
|
+
exports.AnchorStatus = AnchorStatus;
|
|
6786
|
+
exports.ApiTable = ApiTable;
|
|
4298
6787
|
exports.AppCard = AppCard;
|
|
4299
6788
|
exports.AppGrid = AppGrid;
|
|
4300
6789
|
exports.AppIcon = AppIcon;
|
|
4301
6790
|
exports.AppShell = AppShell;
|
|
6791
|
+
exports.ArtifactView = ArtifactView;
|
|
4302
6792
|
exports.Badge = Badge;
|
|
6793
|
+
exports.BlockCountdown = BlockCountdown;
|
|
6794
|
+
exports.BlockHeight = BlockHeight;
|
|
6795
|
+
exports.Breadcrumbs = Breadcrumbs;
|
|
4303
6796
|
exports.BrowserFrame = BrowserFrame;
|
|
4304
6797
|
exports.Button = Button;
|
|
6798
|
+
exports.CODE_LANGS = CODE_LANGS;
|
|
6799
|
+
exports.Callout = Callout;
|
|
4305
6800
|
exports.Card = Card;
|
|
4306
6801
|
exports.CardContent = CardContent;
|
|
4307
6802
|
exports.CardDescription = CardDescription;
|
|
4308
6803
|
exports.CardFooter = CardFooter;
|
|
6804
|
+
exports.CardGrid = CardGrid;
|
|
4309
6805
|
exports.CardHeader = CardHeader;
|
|
4310
6806
|
exports.CardNumeral = CardNumeral;
|
|
4311
6807
|
exports.CardTitle = CardTitle;
|
|
4312
6808
|
exports.Checkbox = Checkbox;
|
|
4313
6809
|
exports.Closing = Closing;
|
|
4314
6810
|
exports.CodeBlock = CodeBlock;
|
|
6811
|
+
exports.CodeTabs = CodeTabs;
|
|
4315
6812
|
exports.ComparisonTable = ComparisonTable;
|
|
4316
6813
|
exports.Container = Container;
|
|
4317
6814
|
exports.CopyButton = CopyButton;
|
|
4318
6815
|
exports.Crowd = Crowd;
|
|
6816
|
+
exports.DOCS_HEADER_NAV = DOCS_HEADER_NAV;
|
|
4319
6817
|
exports.DOCS_HREF = DOCS_HREF;
|
|
4320
6818
|
exports.DataTable = DataTable;
|
|
6819
|
+
exports.DensityProvider = DensityProvider;
|
|
6820
|
+
exports.Diagram = Diagram;
|
|
4321
6821
|
exports.Dialog = Dialog;
|
|
4322
6822
|
exports.DialogClose = DialogClose;
|
|
4323
6823
|
exports.DialogContent = DialogContent;
|
|
@@ -4330,6 +6830,11 @@ exports.DialogTrigger = DialogTrigger;
|
|
|
4330
6830
|
exports.Display = Display;
|
|
4331
6831
|
exports.DocHeader = DocHeader;
|
|
4332
6832
|
exports.DocLayout = DocLayout;
|
|
6833
|
+
exports.DocsHeading = DocsHeading;
|
|
6834
|
+
exports.DocsNav = DocsNav;
|
|
6835
|
+
exports.DocsPager = DocsPager;
|
|
6836
|
+
exports.DocsShell = DocsShell;
|
|
6837
|
+
exports.DropZone = DropZone;
|
|
4333
6838
|
exports.DropdownMenu = DropdownMenu;
|
|
4334
6839
|
exports.DropdownMenuContent = DropdownMenuContent;
|
|
4335
6840
|
exports.DropdownMenuGroup = DropdownMenuGroup;
|
|
@@ -4350,12 +6855,15 @@ exports.FactRows = FactRows;
|
|
|
4350
6855
|
exports.FamilyMenu = FamilyMenu;
|
|
4351
6856
|
exports.Faq = Faq;
|
|
4352
6857
|
exports.Field = Field;
|
|
6858
|
+
exports.FilterChips = FilterChips;
|
|
4353
6859
|
exports.FloatChip = FloatChip;
|
|
4354
6860
|
exports.Footnote = Footnote;
|
|
6861
|
+
exports.FormSection = FormSection;
|
|
4355
6862
|
exports.HalftoneCanvas = HalftoneCanvas;
|
|
4356
6863
|
exports.HalftoneSphere = HalftoneSphere;
|
|
4357
6864
|
exports.HashChip = HashChip;
|
|
4358
6865
|
exports.Input = Input;
|
|
6866
|
+
exports.InstallTabs = InstallTabs;
|
|
4359
6867
|
exports.IsoCheck = IsoCheck;
|
|
4360
6868
|
exports.Kbd = Kbd;
|
|
4361
6869
|
exports.KeyValueList = KeyValueList;
|
|
@@ -4363,15 +6871,20 @@ exports.LEGAL_LINKS = LEGAL_LINKS;
|
|
|
4363
6871
|
exports.Label = Label;
|
|
4364
6872
|
exports.Lead = Lead;
|
|
4365
6873
|
exports.LegalDocument = LegalDocument;
|
|
6874
|
+
exports.LinkCard = LinkCard;
|
|
4366
6875
|
exports.LoadingBlock = LoadingBlock;
|
|
4367
6876
|
exports.Lockup = Lockup;
|
|
4368
6877
|
exports.MARK_FACES = MARK_FACES;
|
|
4369
6878
|
exports.Mark = Mark;
|
|
6879
|
+
exports.MdxTable = MdxTable;
|
|
6880
|
+
exports.Meter = Meter;
|
|
4370
6881
|
exports.Monogram = Monogram;
|
|
4371
6882
|
exports.Notice = Notice;
|
|
6883
|
+
exports.OCHK_APP_ACCOUNT = OCHK_APP_ACCOUNT;
|
|
4372
6884
|
exports.OCHK_IO = OCHK_IO;
|
|
4373
6885
|
exports.OCHK_IO_FOOTER = OCHK_IO_FOOTER;
|
|
4374
6886
|
exports.OCHK_IO_NAV = OCHK_IO_NAV;
|
|
6887
|
+
exports.OnThisPage = OnThisPage;
|
|
4375
6888
|
exports.PROTOCOLS = PROTOCOLS;
|
|
4376
6889
|
exports.PROTOCOL_ORDER = PROTOCOL_ORDER;
|
|
4377
6890
|
exports.PackageCard = PackageCard;
|
|
@@ -4398,6 +6911,8 @@ exports.Sats = Sats;
|
|
|
4398
6911
|
exports.SatsFigure = SatsFigure;
|
|
4399
6912
|
exports.ScrollFade = ScrollFade;
|
|
4400
6913
|
exports.ScrollStory = ScrollStory;
|
|
6914
|
+
exports.SearchButton = SearchButton;
|
|
6915
|
+
exports.SearchDialog = SearchDialog;
|
|
4401
6916
|
exports.Section = Section;
|
|
4402
6917
|
exports.SectionHeading = SectionHeading;
|
|
4403
6918
|
exports.SectionIntro = SectionIntro;
|
|
@@ -4408,6 +6923,7 @@ exports.SelectItem = SelectItem;
|
|
|
4408
6923
|
exports.SelectTrigger = SelectTrigger;
|
|
4409
6924
|
exports.SelectValue = SelectValue;
|
|
4410
6925
|
exports.Separator = Separator;
|
|
6926
|
+
exports.SessionAccountView = SessionAccountView;
|
|
4411
6927
|
exports.Sheet = Sheet;
|
|
4412
6928
|
exports.SheetClose = SheetClose;
|
|
4413
6929
|
exports.SheetContent = SheetContent;
|
|
@@ -4427,11 +6943,15 @@ exports.Spinner = Spinner;
|
|
|
4427
6943
|
exports.SplitBar = SplitBar;
|
|
4428
6944
|
exports.StatCard = StatCard;
|
|
4429
6945
|
exports.StatGrid = StatGrid;
|
|
6946
|
+
exports.StateBadge = StateBadge;
|
|
4430
6947
|
exports.StatusBadge = StatusBadge;
|
|
4431
6948
|
exports.StatusDot = StatusDot;
|
|
4432
6949
|
exports.StatusPill = StatusPill;
|
|
6950
|
+
exports.Step = Step;
|
|
4433
6951
|
exports.StepGrid = StepGrid;
|
|
6952
|
+
exports.Steps = Steps;
|
|
4434
6953
|
exports.Switch = Switch;
|
|
6954
|
+
exports.TOKEN_CLASS = TOKEN_CLASS;
|
|
4435
6955
|
exports.Tabs = Tabs;
|
|
4436
6956
|
exports.TabsContent = TabsContent;
|
|
4437
6957
|
exports.TabsList = TabsList;
|
|
@@ -4441,6 +6961,8 @@ exports.Textarea = Textarea;
|
|
|
4441
6961
|
exports.ThemeToggle = ThemeToggle;
|
|
4442
6962
|
exports.Ticker = Ticker;
|
|
4443
6963
|
exports.Toaster = Toaster;
|
|
6964
|
+
exports.ToolGrid = ToolGrid;
|
|
6965
|
+
exports.ToolShell = ToolShell;
|
|
4444
6966
|
exports.Tooltip = Tooltip;
|
|
4445
6967
|
exports.TooltipContent = TooltipContent;
|
|
4446
6968
|
exports.TooltipProvider = TooltipProvider;
|
|
@@ -4452,21 +6974,43 @@ exports.VerifyReport = VerifyReport;
|
|
|
4452
6974
|
exports.appColors = appColors;
|
|
4453
6975
|
exports.appFonts = appFonts;
|
|
4454
6976
|
exports.badgeVariants = badgeVariants;
|
|
6977
|
+
exports.blocksToDuration = blocksToDuration;
|
|
4455
6978
|
exports.buttonVariants = buttonVariants;
|
|
4456
6979
|
exports.cardVariants = cardVariants;
|
|
4457
6980
|
exports.cn = cn;
|
|
4458
6981
|
exports.confirm = confirm;
|
|
6982
|
+
exports.createMdxComponents = createMdxComponents;
|
|
6983
|
+
exports.createStateBadge = createStateBadge;
|
|
6984
|
+
exports.escapeHtml = escapeHtml;
|
|
6985
|
+
exports.explorerUrl = explorerUrl;
|
|
4459
6986
|
exports.familyByGroup = familyByGroup;
|
|
4460
6987
|
exports.familySite = familySite;
|
|
6988
|
+
exports.formatBlockHeight = formatBlockHeight;
|
|
6989
|
+
exports.formatBytes = formatBytes;
|
|
6990
|
+
exports.formatUtc = formatUtc;
|
|
6991
|
+
exports.grammarOf = grammarOf;
|
|
6992
|
+
exports.highlight = highlight;
|
|
6993
|
+
exports.highlightToHtml = highlightToHtml;
|
|
6994
|
+
exports.languageName = languageName;
|
|
6995
|
+
exports.linesToHtml = linesToHtml;
|
|
6996
|
+
exports.mdxComponents = mdxComponents;
|
|
4461
6997
|
exports.monogramGround = monogramGround;
|
|
4462
6998
|
exports.monogramLetter = monogramLetter;
|
|
6999
|
+
exports.parseCodeMeta = parseCodeMeta;
|
|
7000
|
+
exports.parseLineRanges = parseLineRanges;
|
|
4463
7001
|
exports.portraitTone = portraitTone;
|
|
4464
7002
|
exports.prompt = prompt;
|
|
4465
7003
|
exports.protocolSite = protocolSite;
|
|
7004
|
+
exports.readDiff = readDiff;
|
|
7005
|
+
exports.rehypeCode = rehypeCode;
|
|
4466
7006
|
exports.satsText = satsText;
|
|
4467
7007
|
exports.sectionVariants = sectionVariants;
|
|
7008
|
+
exports.shortenMiddle = shortenMiddle;
|
|
4468
7009
|
exports.statusWord = statusWord;
|
|
7010
|
+
exports.useActiveHeading = useActiveHeading;
|
|
4469
7011
|
exports.useCopy = useCopy;
|
|
7012
|
+
exports.useDensity = useDensity;
|
|
7013
|
+
exports.useHeadings = useHeadings;
|
|
4470
7014
|
exports.useInView = useInView;
|
|
4471
7015
|
exports.useShellPlace = useShellPlace;
|
|
4472
7016
|
exports.useTimedOut = useTimedOut;
|