@ory/argus 0.13.8 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/assets/commands/dashboard.md +34 -0
- package/assets/skills/ory-build-agent/SKILL.md +11 -13
- package/assets/skills/ory-e2b-sandbox/SKILL.md +0 -1
- package/assets/skills/ory-temporal-worker/SKILL.md +8 -10
- package/assets/skills/permissions-onboarding/SKILL.md +3 -3
- package/dist/adapters.d.ts +27 -4
- package/dist/adapters.js +132 -32
- package/dist/agent-auth.d.ts +34 -3
- package/dist/agent-auth.js +58 -8
- package/dist/auth.d.ts +7 -0
- package/dist/auth.js +90 -5
- package/dist/branding.d.ts +67 -0
- package/dist/branding.js +81 -0
- package/dist/build-info.json +4 -4
- package/dist/cli.d.ts +3 -3
- package/dist/cli.js +13 -52
- package/dist/client.d.ts +31 -0
- package/dist/client.js +58 -0
- package/dist/config.d.ts +48 -19
- package/dist/config.js +31 -26
- package/dist/contract-suite.d.ts +5 -3
- package/dist/contract-suite.js +13 -22
- package/dist/dashboard-cli.d.ts +8 -0
- package/dist/dashboard-cli.js +70 -0
- package/dist/dev.js +3 -4
- package/dist/index.d.ts +12 -5
- package/dist/index.js +41 -3
- package/dist/interactive-setup.d.ts +144 -23
- package/dist/interactive-setup.js +412 -224
- package/dist/local/health.d.ts +14 -0
- package/dist/local/health.js +46 -0
- package/dist/local/manager.js +1 -3
- package/dist/local/seed.d.ts +9 -20
- package/dist/local/seed.js +26 -18
- package/dist/permissions-cli.js +12 -4
- package/dist/project-api-key.d.ts +69 -0
- package/dist/project-api-key.js +147 -0
- package/dist/registry/manager.js +62 -18
- package/dist/setup-actions.d.ts +232 -0
- package/dist/setup-actions.js +507 -0
- package/dist/setup.d.ts +19 -0
- package/dist/setup.js +44 -14
- package/dist/skills.js +7 -0
- package/dist/status-cli.d.ts +2 -2
- package/dist/status-cli.js +4 -30
- package/dist/status-data.d.ts +96 -0
- package/dist/status-data.js +250 -0
- package/dist/status-system.d.ts +24 -0
- package/dist/status-system.js +56 -0
- package/dist/testing.d.ts +8 -0
- package/dist/testing.js +20 -1
- package/dist/uninstall.d.ts +33 -15
- package/dist/uninstall.js +65 -22
- package/dist/user-login.d.ts +16 -9
- package/dist/user-login.js +18 -28
- package/dist/web/api.d.ts +33 -0
- package/dist/web/api.js +294 -0
- package/dist/web/launch.d.ts +11 -0
- package/dist/web/launch.js +96 -0
- package/dist/web/server.d.ts +20 -0
- package/dist/web/server.js +233 -0
- package/dist/web/types.d.ts +65 -0
- package/dist/web/types.js +2 -0
- package/dist/webapp/assets/index-Wucl4SZs.css +1 -0
- package/dist/webapp/assets/index-m-GtEdq0.js +49 -0
- package/dist/webapp/favicon.ico +0 -0
- package/dist/webapp/index.html +15 -0
- package/package.json +17 -2
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.canLaunchBrowser = canLaunchBrowser;
|
|
4
|
+
exports.launchWebInstaller = launchWebInstaller;
|
|
5
|
+
exports.launchWebDashboard = launchWebDashboard;
|
|
6
|
+
/**
|
|
7
|
+
* Deciding whether to open the browser, and doing it. `canLaunchBrowser()`
|
|
8
|
+
* gates the web UI on an interactive, non-CI environment with a usable display;
|
|
9
|
+
* `launchWebInstaller` / `launchWebDashboard` start the local server, open the
|
|
10
|
+
* browser, and block until the SPA signals it is done (or the user hits
|
|
11
|
+
* Ctrl+C). Every entry point is fail-open: a launch that can't start returns
|
|
12
|
+
* `false` so the caller falls back to the TTY wizard / text readout.
|
|
13
|
+
*/
|
|
14
|
+
const server_js_1 = require("./server.js");
|
|
15
|
+
/** Whether the environment opts out of the web UI. */
|
|
16
|
+
function webDisabledByEnv() {
|
|
17
|
+
const off = (v) => v === "1" || v === "true" || v === "yes";
|
|
18
|
+
return off(process.env.ORY_NO_WEB?.trim()) || off(process.env.ORY_SETUP_NO_WEB?.trim());
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Heuristic for whether we can meaningfully open a browser for the user:
|
|
22
|
+
* an interactive TTY, not CI, not opted-out, and — on Linux — an actual
|
|
23
|
+
* display server. macOS/Windows are assumed to have a default browser.
|
|
24
|
+
*/
|
|
25
|
+
function canLaunchBrowser() {
|
|
26
|
+
if (webDisabledByEnv())
|
|
27
|
+
return false;
|
|
28
|
+
if (process.env.CI)
|
|
29
|
+
return false;
|
|
30
|
+
if (!process.stdout.isTTY)
|
|
31
|
+
return false;
|
|
32
|
+
if (process.platform === "linux") {
|
|
33
|
+
return !!(process.env.DISPLAY || process.env.WAYLAND_DISPLAY);
|
|
34
|
+
}
|
|
35
|
+
return process.platform === "darwin" || process.platform === "win32";
|
|
36
|
+
}
|
|
37
|
+
async function openBrowser(url) {
|
|
38
|
+
try {
|
|
39
|
+
const mod = (await import("open"));
|
|
40
|
+
await mod.default(url);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
/* the URL is also printed to stderr; the user can open it manually */
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Start the server, open the browser, and wait until the SPA POSTs
|
|
48
|
+
* `/api/shutdown` or the user interrupts. Returns true once handled; false if
|
|
49
|
+
* the server could not start (caller falls back).
|
|
50
|
+
*/
|
|
51
|
+
async function launch(opts) {
|
|
52
|
+
let server;
|
|
53
|
+
try {
|
|
54
|
+
server = await (0, server_js_1.startServer)({
|
|
55
|
+
mode: opts.mode,
|
|
56
|
+
harness: opts.harness,
|
|
57
|
+
binName: opts.binName,
|
|
58
|
+
deps: opts.deps,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
// All human-facing output goes to stderr — stdout stays clean for any harness
|
|
65
|
+
// that parses it.
|
|
66
|
+
console.error("");
|
|
67
|
+
console.error(` Ory Agent ${opts.label} is running in your browser:`);
|
|
68
|
+
console.error(` ${server.url}`);
|
|
69
|
+
console.error(` Leave this terminal open; press Ctrl+C when you're done.`);
|
|
70
|
+
console.error("");
|
|
71
|
+
await openBrowser(server.url);
|
|
72
|
+
const onSigint = () => server.close();
|
|
73
|
+
process.once("SIGINT", onSigint);
|
|
74
|
+
try {
|
|
75
|
+
await server.closed;
|
|
76
|
+
// The shutdown request resolves `closed` before its HTTP response has
|
|
77
|
+
// flushed; give the browser a beat to receive it before we tear down the
|
|
78
|
+
// sockets (otherwise the SPA's final fetch just errors — harmless, but
|
|
79
|
+
// this keeps the "done" confirmation clean).
|
|
80
|
+
await new Promise((r) => setTimeout(r, 150));
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
process.removeListener("SIGINT", onSigint);
|
|
84
|
+
await server.close();
|
|
85
|
+
}
|
|
86
|
+
console.error(" Done — you can close the browser tab.");
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
/** Open the guided install/setup wizard in the browser. */
|
|
90
|
+
function launchWebInstaller(binName, harness, deps) {
|
|
91
|
+
return launch({ mode: "install", binName, harness, deps, label: "setup" });
|
|
92
|
+
}
|
|
93
|
+
/** Open the status dashboard in the browser. */
|
|
94
|
+
function launchWebDashboard(binName, harness, deps) {
|
|
95
|
+
return launch({ mode: "status", binName, harness, deps, label: "status" });
|
|
96
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { SetupActionDeps } from "../setup-actions.js";
|
|
2
|
+
import type { WebAppMode } from "./types.js";
|
|
3
|
+
export interface StartServerOptions {
|
|
4
|
+
mode: WebAppMode;
|
|
5
|
+
harness: string;
|
|
6
|
+
binName: string;
|
|
7
|
+
deps?: SetupActionDeps;
|
|
8
|
+
/** Override the static web root (defaults to the built `dist/webapp`). */
|
|
9
|
+
webRoot?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface RunningServer {
|
|
12
|
+
url: string;
|
|
13
|
+
port: number;
|
|
14
|
+
token: string;
|
|
15
|
+
/** Resolves when the SPA requests shutdown or {@link close} is called. */
|
|
16
|
+
closed: Promise<void>;
|
|
17
|
+
close(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
/** Start the server. Resolves once it is listening. */
|
|
20
|
+
export declare function startServer(opts: StartServerOptions): Promise<RunningServer>;
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.startServer = startServer;
|
|
37
|
+
/**
|
|
38
|
+
* The local web server that backs the installer / status dashboard. A minimal
|
|
39
|
+
* Node `http` server bound to `127.0.0.1` on an ephemeral port that:
|
|
40
|
+
*
|
|
41
|
+
* - serves the pre-built React SPA from `dist/webapp/` (with the SPA fallback
|
|
42
|
+
* to `index.html`, into which it injects the per-launch bootstrap payload);
|
|
43
|
+
* - exposes the JSON API from {@link file://./api.ts} under `/api/*`.
|
|
44
|
+
*
|
|
45
|
+
* Because the API drives privileged `ory` CLI operations, it is guarded two
|
|
46
|
+
* ways: a per-launch secret token required on every `/api` request, and an
|
|
47
|
+
* `Origin`/`Host` allow-list (only this loopback origin) to block DNS-rebinding
|
|
48
|
+
* and cross-site requests from any other page the user has open. There is no
|
|
49
|
+
* network exposure beyond loopback.
|
|
50
|
+
*/
|
|
51
|
+
const http = __importStar(require("node:http"));
|
|
52
|
+
const fs = __importStar(require("node:fs"));
|
|
53
|
+
const path = __importStar(require("node:path"));
|
|
54
|
+
const node_crypto_1 = require("node:crypto");
|
|
55
|
+
const api_js_1 = require("./api.js");
|
|
56
|
+
const MIME = {
|
|
57
|
+
".html": "text/html; charset=utf-8",
|
|
58
|
+
".js": "text/javascript; charset=utf-8",
|
|
59
|
+
".css": "text/css; charset=utf-8",
|
|
60
|
+
".json": "application/json; charset=utf-8",
|
|
61
|
+
".svg": "image/svg+xml",
|
|
62
|
+
".woff2": "font/woff2",
|
|
63
|
+
".woff": "font/woff",
|
|
64
|
+
".png": "image/png",
|
|
65
|
+
".ico": "image/x-icon",
|
|
66
|
+
};
|
|
67
|
+
function defaultWebRoot() {
|
|
68
|
+
// Compiled to dist/web/server.js; the SPA is built to dist/webapp.
|
|
69
|
+
return path.join(__dirname, "..", "webapp");
|
|
70
|
+
}
|
|
71
|
+
/** Start the server. Resolves once it is listening. */
|
|
72
|
+
function startServer(opts) {
|
|
73
|
+
const token = (0, node_crypto_1.randomBytes)(24).toString("hex");
|
|
74
|
+
const webRoot = opts.webRoot ?? defaultWebRoot();
|
|
75
|
+
let resolveClosed;
|
|
76
|
+
const closed = new Promise((r) => (resolveClosed = r));
|
|
77
|
+
const api = (0, api_js_1.createApi)({
|
|
78
|
+
mode: opts.mode,
|
|
79
|
+
harness: opts.harness,
|
|
80
|
+
binName: opts.binName,
|
|
81
|
+
deps: opts.deps ?? {},
|
|
82
|
+
onShutdown: () => resolveClosed(),
|
|
83
|
+
});
|
|
84
|
+
const server = http.createServer((req, res) => {
|
|
85
|
+
handleRequest(req, res, { token, webRoot, api, opts }).catch(() => {
|
|
86
|
+
if (!res.headersSent)
|
|
87
|
+
res.writeHead(500, { "content-type": "application/json" });
|
|
88
|
+
res.end(JSON.stringify({ error: "internal error" }));
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
return new Promise((resolve, reject) => {
|
|
92
|
+
server.on("error", reject);
|
|
93
|
+
// Port 0 = OS-assigned ephemeral port; bind loopback only.
|
|
94
|
+
server.listen(0, "127.0.0.1", () => {
|
|
95
|
+
const addr = server.address();
|
|
96
|
+
const port = typeof addr === "object" && addr ? addr.port : 0;
|
|
97
|
+
const url = `http://127.0.0.1:${port}/`;
|
|
98
|
+
resolve({
|
|
99
|
+
url,
|
|
100
|
+
port,
|
|
101
|
+
token,
|
|
102
|
+
closed,
|
|
103
|
+
close: () => new Promise((r) => {
|
|
104
|
+
resolveClosed();
|
|
105
|
+
server.close(() => r());
|
|
106
|
+
// Browsers hold the connection open with keep-alive, so plain
|
|
107
|
+
// `close()` would wait forever and the CLI would never return to
|
|
108
|
+
// the terminal. Force those idle/live sockets closed so `close()`
|
|
109
|
+
// completes and the process can exit.
|
|
110
|
+
server.closeAllConnections?.();
|
|
111
|
+
}),
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
async function handleRequest(req, res, ctx) {
|
|
117
|
+
const host = req.headers.host ?? "";
|
|
118
|
+
// Only accept loopback Host headers (defends against DNS rebinding).
|
|
119
|
+
if (!/^(127\.0\.0\.1|localhost)(:\d+)?$/.test(host)) {
|
|
120
|
+
return send(res, 403, { error: "forbidden host" });
|
|
121
|
+
}
|
|
122
|
+
const url = new URL(req.url ?? "/", `http://${host}`);
|
|
123
|
+
const pathname = url.pathname;
|
|
124
|
+
if (pathname.startsWith("/api/")) {
|
|
125
|
+
return handleApi(req, res, ctx, url);
|
|
126
|
+
}
|
|
127
|
+
return serveStatic(res, ctx, pathname);
|
|
128
|
+
}
|
|
129
|
+
async function handleApi(req, res, ctx, url) {
|
|
130
|
+
// Origin allow-list: browsers send Origin on API fetches; reject anything
|
|
131
|
+
// that isn't our own loopback origin (blocks cross-site calls into the API).
|
|
132
|
+
const origin = req.headers.origin;
|
|
133
|
+
if (origin && !/^http:\/\/(127\.0\.0\.1|localhost):\d+$/.test(origin)) {
|
|
134
|
+
return send(res, 403, { error: "forbidden origin" });
|
|
135
|
+
}
|
|
136
|
+
// Per-launch secret token, required on every API call.
|
|
137
|
+
if (req.headers["x-ory-setup-token"] !== ctx.token) {
|
|
138
|
+
return send(res, 403, { error: "forbidden" });
|
|
139
|
+
}
|
|
140
|
+
const method = req.method ?? "GET";
|
|
141
|
+
let body = {};
|
|
142
|
+
if (method === "GET") {
|
|
143
|
+
body = Object.fromEntries(url.searchParams.entries());
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
body = await readJsonBody(req);
|
|
147
|
+
}
|
|
148
|
+
const result = await ctx.api.handle(method, url.pathname, body);
|
|
149
|
+
return send(res, result.status, result.json);
|
|
150
|
+
}
|
|
151
|
+
function readJsonBody(req) {
|
|
152
|
+
return new Promise((resolve) => {
|
|
153
|
+
const chunks = [];
|
|
154
|
+
let size = 0;
|
|
155
|
+
req.on("data", (c) => {
|
|
156
|
+
size += c.length;
|
|
157
|
+
// 1 MB cap — the API only ever receives small JSON payloads.
|
|
158
|
+
if (size > 1_000_000) {
|
|
159
|
+
req.destroy();
|
|
160
|
+
resolve({});
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
chunks.push(c);
|
|
164
|
+
});
|
|
165
|
+
req.on("end", () => {
|
|
166
|
+
const raw = Buffer.concat(chunks).toString("utf-8").trim();
|
|
167
|
+
if (!raw)
|
|
168
|
+
return resolve({});
|
|
169
|
+
try {
|
|
170
|
+
const parsed = JSON.parse(raw);
|
|
171
|
+
resolve(parsed && typeof parsed === "object" ? parsed : {});
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
resolve({});
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
req.on("error", () => resolve({}));
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
function serveStatic(res, ctx, pathname) {
|
|
181
|
+
const indexFile = path.join(ctx.webRoot, "index.html");
|
|
182
|
+
// Root or an unknown non-asset path → the SPA shell (with bootstrap injected).
|
|
183
|
+
const looksLikeAsset = /\.[a-z0-9]+$/i.test(pathname);
|
|
184
|
+
if (pathname === "/" || !looksLikeAsset) {
|
|
185
|
+
return sendIndex(res, ctx, indexFile);
|
|
186
|
+
}
|
|
187
|
+
// Resolve the requested asset, guarding against path traversal.
|
|
188
|
+
const resolved = path.join(ctx.webRoot, pathname);
|
|
189
|
+
if (!resolved.startsWith(path.resolve(ctx.webRoot))) {
|
|
190
|
+
return send(res, 403, { error: "forbidden" });
|
|
191
|
+
}
|
|
192
|
+
if (!fs.existsSync(resolved) || !fs.statSync(resolved).isFile()) {
|
|
193
|
+
// Unknown asset → fall back to the SPA shell (client-side routing).
|
|
194
|
+
return sendIndex(res, ctx, indexFile);
|
|
195
|
+
}
|
|
196
|
+
const ext = path.extname(resolved).toLowerCase();
|
|
197
|
+
res.writeHead(200, {
|
|
198
|
+
"content-type": MIME[ext] ?? "application/octet-stream",
|
|
199
|
+
"cache-control": "no-store",
|
|
200
|
+
});
|
|
201
|
+
fs.createReadStream(resolved).pipe(res);
|
|
202
|
+
}
|
|
203
|
+
function sendIndex(res, ctx, indexFile) {
|
|
204
|
+
let html;
|
|
205
|
+
try {
|
|
206
|
+
html = fs.readFileSync(indexFile, "utf-8");
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
html = FALLBACK_HTML;
|
|
210
|
+
}
|
|
211
|
+
const bootstrap = {
|
|
212
|
+
token: ctx.token,
|
|
213
|
+
mode: ctx.opts.mode,
|
|
214
|
+
harness: ctx.opts.harness,
|
|
215
|
+
binName: ctx.opts.binName,
|
|
216
|
+
};
|
|
217
|
+
const inject = `<script>window.__ORY_SETUP__=${JSON.stringify(bootstrap)};</script>`;
|
|
218
|
+
html = html.includes("</head>")
|
|
219
|
+
? html.replace("</head>", `${inject}</head>`)
|
|
220
|
+
: inject + html;
|
|
221
|
+
res.writeHead(200, { "content-type": MIME[".html"], "cache-control": "no-store" });
|
|
222
|
+
res.end(html);
|
|
223
|
+
}
|
|
224
|
+
/** Shown when the built SPA is missing (e.g. a source checkout without a build). */
|
|
225
|
+
const FALLBACK_HTML = `<!doctype html><meta charset="utf-8"><title>Ory Agent Setup</title>
|
|
226
|
+
<body style="font-family:system-ui;padding:2rem;max-width:40rem;margin:auto">
|
|
227
|
+
<h1>Ory Agent Setup</h1>
|
|
228
|
+
<p>The web UI bundle was not found. Run <code>pnpm --filter @ory/argus build</code>,
|
|
229
|
+
or use the terminal wizard instead.</p></body>`;
|
|
230
|
+
function send(res, status, json) {
|
|
231
|
+
res.writeHead(status, { "content-type": "application/json; charset=utf-8", "cache-control": "no-store" });
|
|
232
|
+
res.end(JSON.stringify(json));
|
|
233
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire types shared (in spirit) between the local web server and the SPA. The
|
|
3
|
+
* SPA re-declares matching shapes in `webapp/src/api.ts`; keeping them here
|
|
4
|
+
* documents the contract on the server side.
|
|
5
|
+
*/
|
|
6
|
+
import type { OryWorkspace, OryProject } from "../interactive-setup.js";
|
|
7
|
+
export type WebAppMode = "install" | "status";
|
|
8
|
+
/** Initial payload the SPA reads on load (also injected into index.html). */
|
|
9
|
+
export interface BootstrapPayload {
|
|
10
|
+
mode: WebAppMode;
|
|
11
|
+
harness: string;
|
|
12
|
+
binName: string;
|
|
13
|
+
/** The @ory/argus version, for a footer. */
|
|
14
|
+
version: string;
|
|
15
|
+
/** Whether Ory is already configured (drives the install "already connected" view). */
|
|
16
|
+
alreadyConfigured: boolean;
|
|
17
|
+
auditOnly: boolean;
|
|
18
|
+
projectUrl?: string;
|
|
19
|
+
}
|
|
20
|
+
export type TaskState = "idle" | "running" | "done" | "failed";
|
|
21
|
+
export interface OryCliResponse {
|
|
22
|
+
present: boolean;
|
|
23
|
+
installed: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface SignInStatusResponse {
|
|
26
|
+
state: TaskState;
|
|
27
|
+
signedIn: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface WorkspacesResponse {
|
|
30
|
+
workspaces: OryWorkspace[];
|
|
31
|
+
}
|
|
32
|
+
export interface ProjectsResponse {
|
|
33
|
+
projects: OryProject[];
|
|
34
|
+
cap: number;
|
|
35
|
+
canCreate: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface SelectProjectResponse {
|
|
38
|
+
projectUrl: string;
|
|
39
|
+
dcrEnabled: boolean | null;
|
|
40
|
+
}
|
|
41
|
+
export interface OAuth2ClientResponse {
|
|
42
|
+
clientId: string;
|
|
43
|
+
reused: boolean;
|
|
44
|
+
}
|
|
45
|
+
export interface LoginStatusResponse {
|
|
46
|
+
state: TaskState;
|
|
47
|
+
authenticated: boolean;
|
|
48
|
+
subjectLabel: string | null;
|
|
49
|
+
}
|
|
50
|
+
export interface PermissionModelResponse {
|
|
51
|
+
model: "present" | "empty" | "merge" | "blocked" | "unknown";
|
|
52
|
+
opl?: string;
|
|
53
|
+
}
|
|
54
|
+
export interface GrantResponse {
|
|
55
|
+
ok: boolean;
|
|
56
|
+
count: number;
|
|
57
|
+
error?: string;
|
|
58
|
+
}
|
|
59
|
+
export interface ApiKeyResponse {
|
|
60
|
+
status: "env" | "valid_existing" | "created" | "failed";
|
|
61
|
+
}
|
|
62
|
+
/** Uniform error envelope for a failed action. */
|
|
63
|
+
export interface ApiError {
|
|
64
|
+
error: string;
|
|
65
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}@layer theme{:root,:host{--font-sans:system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--font-mono:"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-200:oklch(88.5% .062 18.334);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-red-900:oklch(39.6% .141 25.723);--color-red-950:oklch(25.8% .092 26.042);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-800:oklch(47.3% .137 46.201);--color-amber-900:oklch(41.4% .112 45.904);--color-amber-950:oklch(27.9% .077 45.635);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-300:oklch(84.5% .143 164.978);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--color-emerald-700:oklch(50.8% .118 165.612);--color-emerald-800:oklch(43.2% .095 166.913);--color-emerald-900:oklch(37.8% .077 168.94);--color-emerald-950:oklch(26.2% .051 172.552);--color-sky-400:oklch(74.6% .16 232.661);--color-sky-500:oklch(68.5% .169 237.323);--color-sky-700:oklch(50% .134 242.749);--color-indigo-50:oklch(96.2% .018 272.314);--color-indigo-200:oklch(87% .065 274.039);--color-indigo-300:oklch(78.5% .115 274.713);--color-indigo-400:oklch(67.3% .182 276.935);--color-indigo-500:oklch(58.5% .233 277.117);--color-indigo-600:oklch(51.1% .262 276.966);--color-indigo-700:oklch(45.7% .24 277.023);--color-indigo-900:oklch(35.9% .144 278.697);--color-indigo-950:oklch(25.7% .09 281.288);--color-slate-50:oklch(98.4% .003 247.858);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-600:oklch(44.6% .043 257.281);--color-slate-700:oklch(37.2% .044 257.287);--color-slate-800:oklch(27.9% .041 260.031);--color-slate-900:oklch(20.8% .042 265.755);--color-slate-950:oklch(12.9% .042 264.695);--color-white:#fff;--spacing:.25rem;--container-3xl:48rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-snug:1.375;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.relative{position:relative}.static{position:static}.top-full{top:100%}.right-0{right:0}.left-8{left:calc(var(--spacing) * 8)}.z-10{z-index:10}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-10{margin-top:calc(var(--spacing) * 10)}.mb-1{margin-bottom:var(--spacing)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.-ml-1{margin-left:calc(var(--spacing) * -1)}.block{display:block}.flex{display:flex}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-11{height:calc(var(--spacing) * 11)}.h-12{height:calc(var(--spacing) * 12)}.max-h-72{max-height:calc(var(--spacing) * 72)}.min-h-full{min-height:100%}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-6{width:calc(var(--spacing) * 6)}.w-9{width:calc(var(--spacing) * 9)}.w-11{width:calc(var(--spacing) * 11)}.w-64{width:calc(var(--spacing) * 64)}.w-auto{width:auto}.w-full{width:100%}.max-w-3xl{max-width:var(--container-3xl)}.min-w-0{min-width:0}.flex-1{flex:1}.flex-none{flex:none}.shrink-0{flex-shrink:0}.translate-x-0\.5{--tw-translate-x:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-\[1\.125rem\]{--tw-translate-x:1.125rem;translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-auto{cursor:auto}.cursor-help{cursor:help}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-x-1\.5{column-gap:calc(var(--spacing) * 1.5)}.gap-x-2{column-gap:calc(var(--spacing) * 2)}.gap-y-1{row-gap:var(--spacing)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-slate-100>:not(:last-child)){border-color:var(--color-slate-100)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-amber-200{border-color:var(--color-amber-200)}.border-amber-300{border-color:var(--color-amber-300)}.border-emerald-200{border-color:var(--color-emerald-200)}.border-emerald-300{border-color:var(--color-emerald-300)}.border-indigo-200{border-color:var(--color-indigo-200)}.border-indigo-400{border-color:var(--color-indigo-400)}.border-red-200{border-color:var(--color-red-200)}.border-slate-100{border-color:var(--color-slate-100)}.border-slate-200{border-color:var(--color-slate-200)}.border-slate-300{border-color:var(--color-slate-300)}.bg-amber-50{background-color:var(--color-amber-50)}.bg-amber-100{background-color:var(--color-amber-100)}.bg-amber-500{background-color:var(--color-amber-500)}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-indigo-50{background-color:var(--color-indigo-50)}.bg-indigo-50\/60{background-color:#eef2ff99}@supports (color:color-mix(in lab,red,red)){.bg-indigo-50\/60{background-color:color-mix(in oklab,var(--color-indigo-50) 60%,transparent)}}.bg-indigo-500{background-color:var(--color-indigo-500)}.bg-indigo-600{background-color:var(--color-indigo-600)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-600{background-color:var(--color-red-600)}.bg-sky-500{background-color:var(--color-sky-500)}.bg-slate-50{background-color:var(--color-slate-50)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-slate-300{background-color:var(--color-slate-300)}.bg-slate-400{background-color:var(--color-slate-400)}.bg-white{background-color:var(--color-white)}.bg-white\/60{background-color:#fff9}@supports (color:color-mix(in lab,red,red)){.bg-white\/60{background-color:color-mix(in oklab,var(--color-white) 60%,transparent)}}.bg-white\/70{background-color:#ffffffb3}@supports (color:color-mix(in lab,red,red)){.bg-white\/70{background-color:color-mix(in oklab,var(--color-white) 70%,transparent)}}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-10{padding-block:calc(var(--spacing) * 10)}.pt-1{padding-top:var(--spacing)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.8em\]{font-size:.8em}.text-\[0\.65rem\]{font-size:.65rem}.text-\[11px\]{font-size:11px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-pre-wrap{white-space:pre-wrap}.text-amber-500{color:var(--color-amber-500)}.text-amber-600{color:var(--color-amber-600)}.text-amber-700{color:var(--color-amber-700)}.text-amber-800{color:var(--color-amber-800)}.text-amber-900{color:var(--color-amber-900)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-600{color:var(--color-emerald-600)}.text-emerald-700{color:var(--color-emerald-700)}.text-emerald-900{color:var(--color-emerald-900)}.text-indigo-500{color:var(--color-indigo-500)}.text-indigo-600{color:var(--color-indigo-600)}.text-indigo-700{color:var(--color-indigo-700)}.text-indigo-900{color:var(--color-indigo-900)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-red-900{color:var(--color-red-900)}.text-sky-700{color:var(--color-sky-700)}.text-slate-300{color:var(--color-slate-300)}.text-slate-400{color:var(--color-slate-400)}.text-slate-500{color:var(--color-slate-500)}.text-slate-600{color:var(--color-slate-600)}.text-slate-700{color:var(--color-slate-700)}.text-slate-800{color:var(--color-slate-800)}.text-slate-900{color:var(--color-slate-900)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.decoration-dotted{text-decoration-style:dotted}.underline-offset-2{text-underline-offset:2px}.opacity-25{opacity:.25}.opacity-90{opacity:.9}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.\[dev\:webapp\]{dev:webapp}@media(hover:hover){.group-hover\:block:is(:where(.group):hover *){display:block}.group-hover\:text-indigo-700:is(:where(.group):hover *){color:var(--color-indigo-700)}.group-hover\:text-slate-600:is(:where(.group):hover *){color:var(--color-slate-600)}}.placeholder\:text-slate-400::placeholder{color:var(--color-slate-400)}@media(hover:hover){.hover\:border-indigo-400:hover{border-color:var(--color-indigo-400)}.hover\:bg-indigo-50:hover{background-color:var(--color-indigo-50)}.hover\:bg-indigo-50\/50:hover{background-color:#eef2ff80}@supports (color:color-mix(in lab,red,red)){.hover\:bg-indigo-50\/50:hover{background-color:color-mix(in oklab,var(--color-indigo-50) 50%,transparent)}}.hover\:bg-indigo-700:hover{background-color:var(--color-indigo-700)}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}.hover\:bg-slate-50:hover{background-color:var(--color-slate-50)}.hover\:text-indigo-500:hover{color:var(--color-indigo-500)}.hover\:text-indigo-600:hover{color:var(--color-indigo-600)}}.focus\:border-indigo-400:focus{border-color:var(--color-indigo-400)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-indigo-200:focus{--tw-ring-color:var(--color-indigo-200)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-indigo-300:focus-visible{--tw-ring-color:var(--color-indigo-300)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media(hover:hover){.disabled\:hover\:bg-indigo-600:disabled:hover{background-color:var(--color-indigo-600)}}@media(prefers-reduced-motion:reduce){.motion-reduce\:transition-none{transition-property:none}}@media(prefers-color-scheme:dark){:where(.dark\:divide-slate-800>:not(:last-child)){border-color:var(--color-slate-800)}.dark\:border-amber-800{border-color:var(--color-amber-800)}.dark\:border-amber-900\/50{border-color:#7b330680}@supports (color:color-mix(in lab,red,red)){.dark\:border-amber-900\/50{border-color:color-mix(in oklab,var(--color-amber-900) 50%,transparent)}}.dark\:border-amber-900\/60{border-color:#7b330699}@supports (color:color-mix(in lab,red,red)){.dark\:border-amber-900\/60{border-color:color-mix(in oklab,var(--color-amber-900) 60%,transparent)}}.dark\:border-emerald-800{border-color:var(--color-emerald-800)}.dark\:border-emerald-900\/50{border-color:#004e3b80}@supports (color:color-mix(in lab,red,red)){.dark\:border-emerald-900\/50{border-color:color-mix(in oklab,var(--color-emerald-900) 50%,transparent)}}.dark\:border-emerald-900\/60{border-color:#004e3b99}@supports (color:color-mix(in lab,red,red)){.dark\:border-emerald-900\/60{border-color:color-mix(in oklab,var(--color-emerald-900) 60%,transparent)}}.dark\:border-indigo-500{border-color:var(--color-indigo-500)}.dark\:border-indigo-900\/50{border-color:#312c8580}@supports (color:color-mix(in lab,red,red)){.dark\:border-indigo-900\/50{border-color:color-mix(in oklab,var(--color-indigo-900) 50%,transparent)}}.dark\:border-indigo-900\/60{border-color:#312c8599}@supports (color:color-mix(in lab,red,red)){.dark\:border-indigo-900\/60{border-color:color-mix(in oklab,var(--color-indigo-900) 60%,transparent)}}.dark\:border-red-900\/50{border-color:#82181a80}@supports (color:color-mix(in lab,red,red)){.dark\:border-red-900\/50{border-color:color-mix(in oklab,var(--color-red-900) 50%,transparent)}}.dark\:border-slate-600{border-color:var(--color-slate-600)}.dark\:border-slate-700{border-color:var(--color-slate-700)}.dark\:border-slate-800{border-color:var(--color-slate-800)}.dark\:bg-amber-900\/50{background-color:#7b330680}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-900\/50{background-color:color-mix(in oklab,var(--color-amber-900) 50%,transparent)}}.dark\:bg-amber-950\/40{background-color:#46190166}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-950\/40{background-color:color-mix(in oklab,var(--color-amber-950) 40%,transparent)}}.dark\:bg-emerald-950\/40{background-color:#002c2266}@supports (color:color-mix(in lab,red,red)){.dark\:bg-emerald-950\/40{background-color:color-mix(in oklab,var(--color-emerald-950) 40%,transparent)}}.dark\:bg-indigo-950\/40{background-color:#1e1a4d66}@supports (color:color-mix(in lab,red,red)){.dark\:bg-indigo-950\/40{background-color:color-mix(in oklab,var(--color-indigo-950) 40%,transparent)}}.dark\:bg-red-950\/40{background-color:#46080966}@supports (color:color-mix(in lab,red,red)){.dark\:bg-red-950\/40{background-color:color-mix(in oklab,var(--color-red-950) 40%,transparent)}}.dark\:bg-slate-600{background-color:var(--color-slate-600)}.dark\:bg-slate-800{background-color:var(--color-slate-800)}.dark\:bg-slate-900{background-color:var(--color-slate-900)}.dark\:bg-slate-900\/60{background-color:#0f172b99}@supports (color:color-mix(in lab,red,red)){.dark\:bg-slate-900\/60{background-color:color-mix(in oklab,var(--color-slate-900) 60%,transparent)}}.dark\:bg-slate-950{background-color:var(--color-slate-950)}.dark\:bg-white\/5{background-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){.dark\:bg-white\/5{background-color:color-mix(in oklab,var(--color-white) 5%,transparent)}}.dark\:text-amber-200{color:var(--color-amber-200)}.dark\:text-amber-300{color:var(--color-amber-300)}.dark\:text-amber-400{color:var(--color-amber-400)}.dark\:text-emerald-200{color:var(--color-emerald-200)}.dark\:text-emerald-300{color:var(--color-emerald-300)}.dark\:text-emerald-400{color:var(--color-emerald-400)}.dark\:text-indigo-200{color:var(--color-indigo-200)}.dark\:text-indigo-300{color:var(--color-indigo-300)}.dark\:text-indigo-400{color:var(--color-indigo-400)}.dark\:text-red-200{color:var(--color-red-200)}.dark\:text-red-400{color:var(--color-red-400)}.dark\:text-sky-400{color:var(--color-sky-400)}.dark\:text-slate-100{color:var(--color-slate-100)}.dark\:text-slate-200{color:var(--color-slate-200)}.dark\:text-slate-300{color:var(--color-slate-300)}.dark\:text-slate-400{color:var(--color-slate-400)}.dark\:text-slate-500{color:var(--color-slate-500)}.dark\:text-slate-600{color:var(--color-slate-600)}.dark\:text-white{color:var(--color-white)}@media(hover:hover){.dark\:group-hover\:text-indigo-300:is(:where(.group):hover *){color:var(--color-indigo-300)}.dark\:group-hover\:text-slate-300:is(:where(.group):hover *){color:var(--color-slate-300)}.dark\:hover\:border-indigo-500:hover{border-color:var(--color-indigo-500)}.dark\:hover\:bg-slate-800:hover{background-color:var(--color-slate-800)}.dark\:hover\:text-indigo-400:hover{color:var(--color-indigo-400)}}}}:root{color-scheme:light dark}html,body,#root{height:100%}body{font-family:var(--font-sans);background-color:var(--color-slate-50);color:var(--color-slate-800);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;margin:0}@media(prefers-color-scheme:dark){body{background-color:var(--color-slate-950);color:var(--color-slate-100)}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@keyframes spin{to{transform:rotate(360deg)}}
|