@hanzo/ui 8.0.8 → 8.0.11

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/oss/catalog.ts","../src/oss/blueprint.ts"],"names":[],"mappings":"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","file":"oss.cjs","sourcesContent":["/**\n * The OSS App Store catalog — the shared client for the 1000+-app one-click\n * open-source catalog served as a flat JSON array at `<base>/meta.json`, with per-app\n * blueprint assets under `<base>/blueprints/<id>/`.\n *\n * One catalog, several surfaces: the console App Store, platform.hanzo.ai, and the\n * public gallery at oss.hanzo.ai. They previously each carried their own copy of the\n * shape, the normalizer and the URL builders, which is how three surfaces come to\n * disagree about the same catalog row. This is the one implementation.\n *\n * The catalog is a PUBLIC CDN with open CORS, so a browser fetches it DIRECTLY — no\n * BFF, no `/v1` proxy — which is why this works in the go:embed console where the\n * Next reverse-proxies are pruned. The base URL is INJECTED by the caller, so this\n * module holds no config import and its normalizers + URL builders stay pure.\n */\n\n/** One open-source app in the catalog (the meta.json entry, load-bearing fields only). */\nexport type OssApp = {\n /** Stable catalog id + blueprint path segment, e.g. `2fauth`, `n8n`, `postgres`. */\n id: string\n /** Display name, e.g. \"2FAuth\". */\n name: string\n /** One-line description. */\n description: string\n /** Version label — often the literal string `\"latest\"`, rendered raw. */\n version: string\n /** Bare logo filename (e.g. `logo.svg`), resolved against the blueprint path. */\n logo: string\n /** Category/provenance tags (e.g. `productivity`, `self-hosted`, `caprover`). */\n tags: string[]\n /** External links; only github/website/docs are surfaced. */\n links: { github?: string; website?: string; docs?: string }\n}\n\nconst str = (v: unknown): string => (typeof v === 'string' ? v : '')\nconst strTrim = (v: unknown): string | undefined => {\n const s = str(v).trim()\n return s ? s : undefined\n}\nconst strList = (v: unknown): string[] =>\n Array.isArray(v) ? v.map((x) => (typeof x === 'string' ? x.trim() : '')).filter((x) => x !== '') : []\nconst asRecord = (v: unknown): Record<string, unknown> =>\n v && typeof v === 'object' && !Array.isArray(v) ? (v as Record<string, unknown>) : {}\n\n/** Normalize one catalog record to an `OssApp` (drops a record with no id + name). */\nexport function normalizeOssApp(raw: unknown): OssApp | null {\n const r = asRecord(raw)\n const id = str(r.id).trim()\n const name = str(r.name).trim() || id\n if (!id || !name) return null\n const links = asRecord(r.links)\n return {\n id,\n name,\n description: str(r.description).trim(),\n version: str(r.version).trim() || 'latest',\n logo: str(r.logo).trim(),\n tags: strList(r.tags),\n links: {\n github: strTrim(links.github),\n website: strTrim(links.website),\n docs: strTrim(links.docs),\n },\n }\n}\n\n/** Normalize the catalog payload to the app list (bare array OR a `{data|apps|…}` wrap). */\nexport function normalizeOssApps(payload: unknown): OssApp[] {\n let arr: unknown[] = []\n if (Array.isArray(payload)) arr = payload\n else if (payload && typeof payload === 'object') {\n for (const k of ['data', 'apps', 'templates', 'items', 'rows']) {\n const v = (payload as Record<string, unknown>)[k]\n if (Array.isArray(v)) {\n arr = v\n break\n }\n }\n }\n const out: OssApp[] = []\n const seen = new Set<string>()\n for (const raw of arr) {\n const app = normalizeOssApp(raw)\n if (app && !seen.has(app.id)) {\n seen.add(app.id)\n out.push(app)\n }\n }\n return out\n}\n\n/** The per-app blueprint asset base: `<base>/blueprints/<id>`. */\nexport function blueprintBase(base: string, id: string): string {\n return `${base.replace(/\\/+$/, '')}/blueprints/${encodeURIComponent(id)}`\n}\n\n/**\n * The app's logo URL, or null when the entry carries no logo filename — a surface then\n * renders its monogram fallback rather than a broken image.\n */\nexport function logoUrl(base: string, app: OssApp): string | null {\n if (!app.logo) return null\n return `${blueprintBase(base, app.id)}/${app.logo}`\n}\n\n/**\n * Derive `owner/repo` from a GitHub URL — the maker identity, since the catalog\n * carries no author field. Returns null for a non-GitHub / malformed URL.\n */\nexport function ownerRepo(githubUrl?: string): string | null {\n if (!githubUrl) return null\n const m = githubUrl.match(/github\\.com\\/([^/\\s]+)\\/([^/\\s#?]+)/i)\n if (!m) return null\n const owner = m[1]\n const repo = m[2].replace(/\\.git$/i, '')\n if (!owner || !repo) return null\n return `${owner}/${repo}`\n}\n\n/** An app is one-click deployable when it carries a buildable source (its repo). */\nexport function hasDeploySource(app: OssApp): boolean {\n return Boolean(app.links.github)\n}\n\n// ── Live fetch (the one impure surface) ──────────────────────────────────────\n//\n// Cached per base URL so several mounts share ONE ~500 KB fetch. An in-flight fetch is\n// de-duped (concurrent callers await the same promise); a failure is not cached.\nconst cache = new Map<string, OssApp[]>()\nconst inflight = new Map<string, Promise<OssApp[]>>()\n\n/**\n * Fetch + normalize the catalog from `<base>/meta.json`. Cross-origin and\n * unauthenticated (public CDN); throws on a non-2xx or parse failure so the caller can\n * show an honest error state. Cached on success; `force` bypasses for a manual refresh.\n */\nexport async function fetchOssApps(base: string, force = false): Promise<OssApp[]> {\n const key = base.replace(/\\/+$/, '')\n if (!force) {\n const hit = cache.get(key)\n if (hit) return hit\n const pending = inflight.get(key)\n if (pending) return pending\n }\n const run = (async () => {\n const res = await fetch(`${key}/meta.json`, {\n headers: { Accept: 'application/json' },\n // Public catalog — no credentials, so a session cookie never leaks cross-origin.\n credentials: 'omit',\n })\n if (!res.ok) throw new Error(`Catalog unavailable (HTTP ${res.status})`)\n const apps = normalizeOssApps(await res.json())\n cache.set(key, apps)\n return apps\n })()\n inflight.set(key, run)\n try {\n return await run\n } finally {\n inflight.delete(key)\n }\n}\n\n/**\n * Fetch one app's `docker-compose.yml` as raw text, or null when the entry publishes\n * none. A 404 is a NORMAL answer for a large community catalog — not every blueprint\n * ships compose — so this never throws: a detail view treats an absent blueprint as\n * \"nothing to show\", and an optional asset must not fail a whole page.\n */\nexport async function fetchCompose(base: string, id: string): Promise<string | null> {\n try {\n const res = await fetch(`${blueprintBase(base, id)}/docker-compose.yml`, {\n headers: { Accept: 'text/plain' },\n credentials: 'omit',\n })\n if (!res.ok) return null\n const text = await res.text()\n return text.trim() ? text : null\n } catch {\n return null\n }\n}\n","/**\n * What an OSS blueprint actually provisions, read from its own `docker-compose.yml`.\n *\n * This is the one implementation. It was written twice before it lived here — once in\n * TypeScript for the console's App Store and once in vanilla JS for oss.hanzo.ai — and\n * two readers of the same file format drift, which means two surfaces can disagree\n * about what a deploy will start.\n *\n * Deliberately a SMALL structural reader, not a YAML implementation: it walks the\n * `services:` block by indentation and pulls only the keys a detail view shows.\n * Anything it cannot read is absent, never guessed, so a surface degrades to \"no\n * blueprint detail\" instead of asserting something false about what will run.\n *\n * Pure and total — it never throws on malformed or hostile input — so it is safe to\n * run on untrusted CDN content and testable without a DOM or a network.\n */\n\n/**\n * One service a blueprint provisions. `image` is absent for a service built from\n * source (`build:` rather than `image:`).\n */\nexport type Service = { name: string; image?: string; ports: string[] }\n\n/** What a blueprint provisions: the containers it starts and the config it expects. */\nexport type Blueprint = { services: Service[]; env: string[] }\n\n/** Indent width of a line, tabs counted as one column (compose files are space-indented). */\nconst indent = (line: string): number => line.length - line.trimStart().length\n\n/**\n * Parse the load-bearing facts out of a `docker-compose.yml`: the services it starts\n * (with image + published ports) and the environment keys it expects.\n *\n * Environment KEYS only — never the values, which are routinely secrets.\n */\nexport function parseBlueprint(yaml: string): Blueprint {\n const lines = String(yaml ?? '').split(/\\r?\\n/)\n const services: Service[] = []\n const env = new Set<string>()\n\n let servicesAt = -1 // indent of the `services:` key, -1 until seen\n let current: Service | null = null\n let currentAt = -1 // indent of the current service's name (bookkeeping, not a field)\n let listKey: 'ports' | 'environment' | null = null\n let listAt = -1\n\n for (const raw of lines) {\n const line = raw.replace(/\\t/g, ' ')\n const trimmed = line.trim()\n if (!trimmed || trimmed.startsWith('#')) continue\n const col = indent(line)\n\n if (servicesAt < 0) {\n if (/^services\\s*:/.test(trimmed)) servicesAt = col\n continue\n }\n // Dedent back to or past `services:` ends the block (e.g. a following `volumes:`).\n if (col <= servicesAt) {\n if (!/^services\\s*:/.test(trimmed)) break\n continue\n }\n\n // A service name sits exactly one level inside `services:`.\n if (current === null || col <= currentAt) {\n const m = trimmed.match(/^([A-Za-z0-9._-]+)\\s*:\\s*$/)\n if (m) {\n current = { name: m[1], ports: [] }\n currentAt = col\n services.push(current)\n listKey = null\n continue\n }\n }\n if (!current) continue\n\n if (listKey && col > listAt && trimmed.startsWith('-')) {\n const item = trimmed.replace(/^-\\s*/, '').replace(/^[\"']|[\"']$/g, '')\n if (listKey === 'ports') current.ports.push(item)\n else {\n const key = item.split(/[=:]/)[0]?.trim()\n if (key) env.add(key)\n }\n continue\n }\n listKey = null\n\n const img = trimmed.match(/^image\\s*:\\s*(.+)$/)\n if (img) {\n current.image = img[1].trim().replace(/^[\"']|[\"']$/g, '')\n continue\n }\n if (/^ports\\s*:/.test(trimmed)) {\n listKey = 'ports'\n listAt = col\n continue\n }\n if (/^environment\\s*:/.test(trimmed)) {\n listKey = 'environment'\n listAt = col\n continue\n }\n }\n\n return { services, env: [...env].sort((a, b) => a.localeCompare(b)) }\n}\n"]}
package/dist/oss.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './oss/catalog';
2
+ export * from './oss/blueprint';
package/dist/oss.js ADDED
@@ -0,0 +1,180 @@
1
+ 'use client';
2
+ // src/oss/catalog.ts
3
+ var str = (v) => typeof v === "string" ? v : "";
4
+ var strTrim = (v) => {
5
+ const s = str(v).trim();
6
+ return s ? s : void 0;
7
+ };
8
+ var strList = (v) => Array.isArray(v) ? v.map((x) => typeof x === "string" ? x.trim() : "").filter((x) => x !== "") : [];
9
+ var asRecord = (v) => v && typeof v === "object" && !Array.isArray(v) ? v : {};
10
+ function normalizeOssApp(raw) {
11
+ const r = asRecord(raw);
12
+ const id = str(r.id).trim();
13
+ const name = str(r.name).trim() || id;
14
+ if (!id || !name) return null;
15
+ const links = asRecord(r.links);
16
+ return {
17
+ id,
18
+ name,
19
+ description: str(r.description).trim(),
20
+ version: str(r.version).trim() || "latest",
21
+ logo: str(r.logo).trim(),
22
+ tags: strList(r.tags),
23
+ links: {
24
+ github: strTrim(links.github),
25
+ website: strTrim(links.website),
26
+ docs: strTrim(links.docs)
27
+ }
28
+ };
29
+ }
30
+ function normalizeOssApps(payload) {
31
+ let arr = [];
32
+ if (Array.isArray(payload)) arr = payload;
33
+ else if (payload && typeof payload === "object") {
34
+ for (const k of ["data", "apps", "templates", "items", "rows"]) {
35
+ const v = payload[k];
36
+ if (Array.isArray(v)) {
37
+ arr = v;
38
+ break;
39
+ }
40
+ }
41
+ }
42
+ const out = [];
43
+ const seen = /* @__PURE__ */ new Set();
44
+ for (const raw of arr) {
45
+ const app = normalizeOssApp(raw);
46
+ if (app && !seen.has(app.id)) {
47
+ seen.add(app.id);
48
+ out.push(app);
49
+ }
50
+ }
51
+ return out;
52
+ }
53
+ function blueprintBase(base, id) {
54
+ return `${base.replace(/\/+$/, "")}/blueprints/${encodeURIComponent(id)}`;
55
+ }
56
+ function logoUrl(base, app) {
57
+ if (!app.logo) return null;
58
+ return `${blueprintBase(base, app.id)}/${app.logo}`;
59
+ }
60
+ function ownerRepo(githubUrl) {
61
+ if (!githubUrl) return null;
62
+ const m = githubUrl.match(/github\.com\/([^/\s]+)\/([^/\s#?]+)/i);
63
+ if (!m) return null;
64
+ const owner = m[1];
65
+ const repo = m[2].replace(/\.git$/i, "");
66
+ if (!owner || !repo) return null;
67
+ return `${owner}/${repo}`;
68
+ }
69
+ function hasDeploySource(app) {
70
+ return Boolean(app.links.github);
71
+ }
72
+ var cache = /* @__PURE__ */ new Map();
73
+ var inflight = /* @__PURE__ */ new Map();
74
+ async function fetchOssApps(base, force = false) {
75
+ const key = base.replace(/\/+$/, "");
76
+ if (!force) {
77
+ const hit = cache.get(key);
78
+ if (hit) return hit;
79
+ const pending = inflight.get(key);
80
+ if (pending) return pending;
81
+ }
82
+ const run = (async () => {
83
+ const res = await fetch(`${key}/meta.json`, {
84
+ headers: { Accept: "application/json" },
85
+ // Public catalog — no credentials, so a session cookie never leaks cross-origin.
86
+ credentials: "omit"
87
+ });
88
+ if (!res.ok) throw new Error(`Catalog unavailable (HTTP ${res.status})`);
89
+ const apps = normalizeOssApps(await res.json());
90
+ cache.set(key, apps);
91
+ return apps;
92
+ })();
93
+ inflight.set(key, run);
94
+ try {
95
+ return await run;
96
+ } finally {
97
+ inflight.delete(key);
98
+ }
99
+ }
100
+ async function fetchCompose(base, id) {
101
+ try {
102
+ const res = await fetch(`${blueprintBase(base, id)}/docker-compose.yml`, {
103
+ headers: { Accept: "text/plain" },
104
+ credentials: "omit"
105
+ });
106
+ if (!res.ok) return null;
107
+ const text = await res.text();
108
+ return text.trim() ? text : null;
109
+ } catch {
110
+ return null;
111
+ }
112
+ }
113
+
114
+ // src/oss/blueprint.ts
115
+ var indent = (line) => line.length - line.trimStart().length;
116
+ function parseBlueprint(yaml) {
117
+ const lines = String(yaml ?? "").split(/\r?\n/);
118
+ const services = [];
119
+ const env = /* @__PURE__ */ new Set();
120
+ let servicesAt = -1;
121
+ let current = null;
122
+ let currentAt = -1;
123
+ let listKey = null;
124
+ let listAt = -1;
125
+ for (const raw of lines) {
126
+ const line = raw.replace(/\t/g, " ");
127
+ const trimmed = line.trim();
128
+ if (!trimmed || trimmed.startsWith("#")) continue;
129
+ const col = indent(line);
130
+ if (servicesAt < 0) {
131
+ if (/^services\s*:/.test(trimmed)) servicesAt = col;
132
+ continue;
133
+ }
134
+ if (col <= servicesAt) {
135
+ if (!/^services\s*:/.test(trimmed)) break;
136
+ continue;
137
+ }
138
+ if (current === null || col <= currentAt) {
139
+ const m = trimmed.match(/^([A-Za-z0-9._-]+)\s*:\s*$/);
140
+ if (m) {
141
+ current = { name: m[1], ports: [] };
142
+ currentAt = col;
143
+ services.push(current);
144
+ listKey = null;
145
+ continue;
146
+ }
147
+ }
148
+ if (!current) continue;
149
+ if (listKey && col > listAt && trimmed.startsWith("-")) {
150
+ const item = trimmed.replace(/^-\s*/, "").replace(/^["']|["']$/g, "");
151
+ if (listKey === "ports") current.ports.push(item);
152
+ else {
153
+ const key = item.split(/[=:]/)[0]?.trim();
154
+ if (key) env.add(key);
155
+ }
156
+ continue;
157
+ }
158
+ listKey = null;
159
+ const img = trimmed.match(/^image\s*:\s*(.+)$/);
160
+ if (img) {
161
+ current.image = img[1].trim().replace(/^["']|["']$/g, "");
162
+ continue;
163
+ }
164
+ if (/^ports\s*:/.test(trimmed)) {
165
+ listKey = "ports";
166
+ listAt = col;
167
+ continue;
168
+ }
169
+ if (/^environment\s*:/.test(trimmed)) {
170
+ listKey = "environment";
171
+ listAt = col;
172
+ continue;
173
+ }
174
+ }
175
+ return { services, env: [...env].sort((a, b) => a.localeCompare(b)) };
176
+ }
177
+
178
+ export { blueprintBase, fetchCompose, fetchOssApps, hasDeploySource, logoUrl, normalizeOssApp, normalizeOssApps, ownerRepo, parseBlueprint };
179
+ //# sourceMappingURL=oss.js.map
180
+ //# sourceMappingURL=oss.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/oss/catalog.ts","../src/oss/blueprint.ts"],"names":[],"mappings":";AAkCA,IAAM,MAAM,CAAC,CAAA,KAAwB,OAAO,CAAA,KAAM,WAAW,CAAA,GAAI,EAAA;AACjE,IAAM,OAAA,GAAU,CAAC,CAAA,KAAmC;AAClD,EAAA,MAAM,CAAA,GAAI,GAAA,CAAI,CAAC,CAAA,CAAE,IAAA,EAAK;AACtB,EAAA,OAAO,IAAI,CAAA,GAAI,MAAA;AACjB,CAAA;AACA,IAAM,OAAA,GAAU,CAAC,CAAA,KACf,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,GAAI,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAO,OAAO,MAAM,QAAA,GAAW,CAAA,CAAE,IAAA,EAAK,GAAI,EAAG,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,KAAM,EAAE,CAAA,GAAI,EAAC;AACtG,IAAM,QAAA,GAAW,CAAC,CAAA,KAChB,CAAA,IAAK,OAAO,CAAA,KAAM,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,GAAK,IAAgC,EAAC;AAG/E,SAAS,gBAAgB,GAAA,EAA6B;AAC3D,EAAA,MAAM,CAAA,GAAI,SAAS,GAAG,CAAA;AACtB,EAAA,MAAM,EAAA,GAAK,GAAA,CAAI,CAAA,CAAE,EAAE,EAAE,IAAA,EAAK;AAC1B,EAAA,MAAM,OAAO,GAAA,CAAI,CAAA,CAAE,IAAI,CAAA,CAAE,MAAK,IAAK,EAAA;AACnC,EAAA,IAAI,CAAC,EAAA,IAAM,CAAC,IAAA,EAAM,OAAO,IAAA;AACzB,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,CAAA,CAAE,KAAK,CAAA;AAC9B,EAAA,OAAO;AAAA,IACL,EAAA;AAAA,IACA,IAAA;AAAA,IACA,WAAA,EAAa,GAAA,CAAI,CAAA,CAAE,WAAW,EAAE,IAAA,EAAK;AAAA,IACrC,SAAS,GAAA,CAAI,CAAA,CAAE,OAAO,CAAA,CAAE,MAAK,IAAK,QAAA;AAAA,IAClC,IAAA,EAAM,GAAA,CAAI,CAAA,CAAE,IAAI,EAAE,IAAA,EAAK;AAAA,IACvB,IAAA,EAAM,OAAA,CAAQ,CAAA,CAAE,IAAI,CAAA;AAAA,IACpB,KAAA,EAAO;AAAA,MACL,MAAA,EAAQ,OAAA,CAAQ,KAAA,CAAM,MAAM,CAAA;AAAA,MAC5B,OAAA,EAAS,OAAA,CAAQ,KAAA,CAAM,OAAO,CAAA;AAAA,MAC9B,IAAA,EAAM,OAAA,CAAQ,KAAA,CAAM,IAAI;AAAA;AAC1B,GACF;AACF;AAGO,SAAS,iBAAiB,OAAA,EAA4B;AAC3D,EAAA,IAAI,MAAiB,EAAC;AACtB,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,EAAG,GAAA,GAAM,OAAA;AAAA,OAAA,IACzB,OAAA,IAAW,OAAO,OAAA,KAAY,QAAA,EAAU;AAC/C,IAAA,KAAA,MAAW,KAAK,CAAC,MAAA,EAAQ,QAAQ,WAAA,EAAa,OAAA,EAAS,MAAM,CAAA,EAAG;AAC9D,MAAA,MAAM,CAAA,GAAK,QAAoC,CAAC,CAAA;AAChD,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,EAAG;AACpB,QAAA,GAAA,GAAM,CAAA;AACN,QAAA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,EAAA,MAAM,MAAgB,EAAC;AACvB,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,KAAA,MAAW,OAAO,GAAA,EAAK;AACrB,IAAA,MAAM,GAAA,GAAM,gBAAgB,GAAG,CAAA;AAC/B,IAAA,IAAI,OAAO,CAAC,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA,EAAG;AAC5B,MAAA,IAAA,CAAK,GAAA,CAAI,IAAI,EAAE,CAAA;AACf,MAAA,GAAA,CAAI,KAAK,GAAG,CAAA;AAAA,IACd;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAGO,SAAS,aAAA,CAAc,MAAc,EAAA,EAAoB;AAC9D,EAAA,OAAO,CAAA,EAAG,KAAK,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAC,CAAA,YAAA,EAAe,kBAAA,CAAmB,EAAE,CAAC,CAAA,CAAA;AACzE;AAMO,SAAS,OAAA,CAAQ,MAAc,GAAA,EAA4B;AAChE,EAAA,IAAI,CAAC,GAAA,CAAI,IAAA,EAAM,OAAO,IAAA;AACtB,EAAA,OAAO,CAAA,EAAG,cAAc,IAAA,EAAM,GAAA,CAAI,EAAE,CAAC,CAAA,CAAA,EAAI,IAAI,IAAI,CAAA,CAAA;AACnD;AAMO,SAAS,UAAU,SAAA,EAAmC;AAC3D,EAAA,IAAI,CAAC,WAAW,OAAO,IAAA;AACvB,EAAA,MAAM,CAAA,GAAI,SAAA,CAAU,KAAA,CAAM,sCAAsC,CAAA;AAChE,EAAA,IAAI,CAAC,GAAG,OAAO,IAAA;AACf,EAAA,MAAM,KAAA,GAAQ,EAAE,CAAC,CAAA;AACjB,EAAA,MAAM,OAAO,CAAA,CAAE,CAAC,CAAA,CAAE,OAAA,CAAQ,WAAW,EAAE,CAAA;AACvC,EAAA,IAAI,CAAC,KAAA,IAAS,CAAC,IAAA,EAAM,OAAO,IAAA;AAC5B,EAAA,OAAO,CAAA,EAAG,KAAK,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AACzB;AAGO,SAAS,gBAAgB,GAAA,EAAsB;AACpD,EAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,MAAM,CAAA;AACjC;AAMA,IAAM,KAAA,uBAAY,GAAA,EAAsB;AACxC,IAAM,QAAA,uBAAe,GAAA,EAA+B;AAOpD,eAAsB,YAAA,CAAa,IAAA,EAAc,KAAA,GAAQ,KAAA,EAA0B;AACjF,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AACnC,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,MAAM,GAAA,GAAM,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA;AACzB,IAAA,IAAI,KAAK,OAAO,GAAA;AAChB,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AAChC,IAAA,IAAI,SAAS,OAAO,OAAA;AAAA,EACtB;AACA,EAAA,MAAM,OAAO,YAAY;AACvB,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA,UAAA,CAAA,EAAc;AAAA,MAC1C,OAAA,EAAS,EAAE,MAAA,EAAQ,kBAAA,EAAmB;AAAA;AAAA,MAEtC,WAAA,EAAa;AAAA,KACd,CAAA;AACD,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,GAAA,CAAI,MAAM,CAAA,CAAA,CAAG,CAAA;AACvE,IAAA,MAAM,IAAA,GAAO,gBAAA,CAAiB,MAAM,GAAA,CAAI,MAAM,CAAA;AAC9C,IAAA,KAAA,CAAM,GAAA,CAAI,KAAK,IAAI,CAAA;AACnB,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,GAAG;AACH,EAAA,QAAA,CAAS,GAAA,CAAI,KAAK,GAAG,CAAA;AACrB,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,GAAA;AAAA,EACf,CAAA,SAAE;AACA,IAAA,QAAA,CAAS,OAAO,GAAG,CAAA;AAAA,EACrB;AACF;AAQA,eAAsB,YAAA,CAAa,MAAc,EAAA,EAAoC;AACnF,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,CAAA,EAAG,cAAc,IAAA,EAAM,EAAE,CAAC,CAAA,mBAAA,CAAA,EAAuB;AAAA,MACvE,OAAA,EAAS,EAAE,MAAA,EAAQ,YAAA,EAAa;AAAA,MAChC,WAAA,EAAa;AAAA,KACd,CAAA;AACD,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,IAAA;AACpB,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,OAAO,IAAA,CAAK,IAAA,EAAK,GAAI,IAAA,GAAO,IAAA;AAAA,EAC9B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;;;AC1JA,IAAM,SAAS,CAAC,IAAA,KAAyB,KAAK,MAAA,GAAS,IAAA,CAAK,WAAU,CAAE,MAAA;AAQjE,SAAS,eAAe,IAAA,EAAyB;AACtD,EAAA,MAAM,QAAQ,MAAA,CAAO,IAAA,IAAQ,EAAE,CAAA,CAAE,MAAM,OAAO,CAAA;AAC9C,EAAA,MAAM,WAAsB,EAAC;AAC7B,EAAA,MAAM,GAAA,uBAAU,GAAA,EAAY;AAE5B,EAAA,IAAI,UAAA,GAAa,EAAA;AACjB,EAAA,IAAI,OAAA,GAA0B,IAAA;AAC9B,EAAA,IAAI,SAAA,GAAY,EAAA;AAChB,EAAA,IAAI,OAAA,GAA0C,IAAA;AAC9C,EAAA,IAAI,MAAA,GAAS,EAAA;AAEb,EAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AACnC,IAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAC1B,IAAA,IAAI,CAAC,OAAA,IAAW,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,EAAG;AACzC,IAAA,MAAM,GAAA,GAAM,OAAO,IAAI,CAAA;AAEvB,IAAA,IAAI,aAAa,CAAA,EAAG;AAClB,MAAA,IAAI,eAAA,CAAgB,IAAA,CAAK,OAAO,CAAA,EAAG,UAAA,GAAa,GAAA;AAChD,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,OAAO,UAAA,EAAY;AACrB,MAAA,IAAI,CAAC,eAAA,CAAgB,IAAA,CAAK,OAAO,CAAA,EAAG;AACpC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,OAAA,KAAY,IAAA,IAAQ,GAAA,IAAO,SAAA,EAAW;AACxC,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,KAAA,CAAM,4BAA4B,CAAA;AACpD,MAAA,IAAI,CAAA,EAAG;AACL,QAAA,OAAA,GAAU,EAAE,IAAA,EAAM,CAAA,CAAE,CAAC,CAAA,EAAG,KAAA,EAAO,EAAC,EAAE;AAClC,QAAA,SAAA,GAAY,GAAA;AACZ,QAAA,QAAA,CAAS,KAAK,OAAO,CAAA;AACrB,QAAA,OAAA,GAAU,IAAA;AACV,QAAA;AAAA,MACF;AAAA,IACF;AACA,IAAA,IAAI,CAAC,OAAA,EAAS;AAEd,IAAA,IAAI,WAAW,GAAA,GAAM,MAAA,IAAU,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,EAAG;AACtD,MAAA,MAAM,IAAA,GAAO,QAAQ,OAAA,CAAQ,OAAA,EAAS,EAAE,CAAA,CAAE,OAAA,CAAQ,gBAAgB,EAAE,CAAA;AACpE,MAAA,IAAI,OAAA,KAAY,OAAA,EAAS,OAAA,CAAQ,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,WAC3C;AACH,QAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA,CAAE,CAAC,GAAG,IAAA,EAAK;AACxC,QAAA,IAAI,GAAA,EAAK,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA;AAAA,MACtB;AACA,MAAA;AAAA,IACF;AACA,IAAA,OAAA,GAAU,IAAA;AAEV,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,KAAA,CAAM,oBAAoB,CAAA;AAC9C,IAAA,IAAI,GAAA,EAAK;AACP,MAAA,OAAA,CAAQ,KAAA,GAAQ,IAAI,CAAC,CAAA,CAAE,MAAK,CAAE,OAAA,CAAQ,gBAAgB,EAAE,CAAA;AACxD,MAAA;AAAA,IACF;AACA,IAAA,IAAI,YAAA,CAAa,IAAA,CAAK,OAAO,CAAA,EAAG;AAC9B,MAAA,OAAA,GAAU,OAAA;AACV,MAAA,MAAA,GAAS,GAAA;AACT,MAAA;AAAA,IACF;AACA,IAAA,IAAI,kBAAA,CAAmB,IAAA,CAAK,OAAO,CAAA,EAAG;AACpC,MAAA,OAAA,GAAU,aAAA;AACV,MAAA,MAAA,GAAS,GAAA;AACT,MAAA;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,QAAA,EAAU,GAAA,EAAK,CAAC,GAAG,GAAG,CAAA,CAAE,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM,CAAA,CAAE,aAAA,CAAc,CAAC,CAAC,CAAA,EAAE;AACtE","file":"oss.js","sourcesContent":["/**\n * The OSS App Store catalog — the shared client for the 1000+-app one-click\n * open-source catalog served as a flat JSON array at `<base>/meta.json`, with per-app\n * blueprint assets under `<base>/blueprints/<id>/`.\n *\n * One catalog, several surfaces: the console App Store, platform.hanzo.ai, and the\n * public gallery at oss.hanzo.ai. They previously each carried their own copy of the\n * shape, the normalizer and the URL builders, which is how three surfaces come to\n * disagree about the same catalog row. This is the one implementation.\n *\n * The catalog is a PUBLIC CDN with open CORS, so a browser fetches it DIRECTLY — no\n * BFF, no `/v1` proxy — which is why this works in the go:embed console where the\n * Next reverse-proxies are pruned. The base URL is INJECTED by the caller, so this\n * module holds no config import and its normalizers + URL builders stay pure.\n */\n\n/** One open-source app in the catalog (the meta.json entry, load-bearing fields only). */\nexport type OssApp = {\n /** Stable catalog id + blueprint path segment, e.g. `2fauth`, `n8n`, `postgres`. */\n id: string\n /** Display name, e.g. \"2FAuth\". */\n name: string\n /** One-line description. */\n description: string\n /** Version label — often the literal string `\"latest\"`, rendered raw. */\n version: string\n /** Bare logo filename (e.g. `logo.svg`), resolved against the blueprint path. */\n logo: string\n /** Category/provenance tags (e.g. `productivity`, `self-hosted`, `caprover`). */\n tags: string[]\n /** External links; only github/website/docs are surfaced. */\n links: { github?: string; website?: string; docs?: string }\n}\n\nconst str = (v: unknown): string => (typeof v === 'string' ? v : '')\nconst strTrim = (v: unknown): string | undefined => {\n const s = str(v).trim()\n return s ? s : undefined\n}\nconst strList = (v: unknown): string[] =>\n Array.isArray(v) ? v.map((x) => (typeof x === 'string' ? x.trim() : '')).filter((x) => x !== '') : []\nconst asRecord = (v: unknown): Record<string, unknown> =>\n v && typeof v === 'object' && !Array.isArray(v) ? (v as Record<string, unknown>) : {}\n\n/** Normalize one catalog record to an `OssApp` (drops a record with no id + name). */\nexport function normalizeOssApp(raw: unknown): OssApp | null {\n const r = asRecord(raw)\n const id = str(r.id).trim()\n const name = str(r.name).trim() || id\n if (!id || !name) return null\n const links = asRecord(r.links)\n return {\n id,\n name,\n description: str(r.description).trim(),\n version: str(r.version).trim() || 'latest',\n logo: str(r.logo).trim(),\n tags: strList(r.tags),\n links: {\n github: strTrim(links.github),\n website: strTrim(links.website),\n docs: strTrim(links.docs),\n },\n }\n}\n\n/** Normalize the catalog payload to the app list (bare array OR a `{data|apps|…}` wrap). */\nexport function normalizeOssApps(payload: unknown): OssApp[] {\n let arr: unknown[] = []\n if (Array.isArray(payload)) arr = payload\n else if (payload && typeof payload === 'object') {\n for (const k of ['data', 'apps', 'templates', 'items', 'rows']) {\n const v = (payload as Record<string, unknown>)[k]\n if (Array.isArray(v)) {\n arr = v\n break\n }\n }\n }\n const out: OssApp[] = []\n const seen = new Set<string>()\n for (const raw of arr) {\n const app = normalizeOssApp(raw)\n if (app && !seen.has(app.id)) {\n seen.add(app.id)\n out.push(app)\n }\n }\n return out\n}\n\n/** The per-app blueprint asset base: `<base>/blueprints/<id>`. */\nexport function blueprintBase(base: string, id: string): string {\n return `${base.replace(/\\/+$/, '')}/blueprints/${encodeURIComponent(id)}`\n}\n\n/**\n * The app's logo URL, or null when the entry carries no logo filename — a surface then\n * renders its monogram fallback rather than a broken image.\n */\nexport function logoUrl(base: string, app: OssApp): string | null {\n if (!app.logo) return null\n return `${blueprintBase(base, app.id)}/${app.logo}`\n}\n\n/**\n * Derive `owner/repo` from a GitHub URL — the maker identity, since the catalog\n * carries no author field. Returns null for a non-GitHub / malformed URL.\n */\nexport function ownerRepo(githubUrl?: string): string | null {\n if (!githubUrl) return null\n const m = githubUrl.match(/github\\.com\\/([^/\\s]+)\\/([^/\\s#?]+)/i)\n if (!m) return null\n const owner = m[1]\n const repo = m[2].replace(/\\.git$/i, '')\n if (!owner || !repo) return null\n return `${owner}/${repo}`\n}\n\n/** An app is one-click deployable when it carries a buildable source (its repo). */\nexport function hasDeploySource(app: OssApp): boolean {\n return Boolean(app.links.github)\n}\n\n// ── Live fetch (the one impure surface) ──────────────────────────────────────\n//\n// Cached per base URL so several mounts share ONE ~500 KB fetch. An in-flight fetch is\n// de-duped (concurrent callers await the same promise); a failure is not cached.\nconst cache = new Map<string, OssApp[]>()\nconst inflight = new Map<string, Promise<OssApp[]>>()\n\n/**\n * Fetch + normalize the catalog from `<base>/meta.json`. Cross-origin and\n * unauthenticated (public CDN); throws on a non-2xx or parse failure so the caller can\n * show an honest error state. Cached on success; `force` bypasses for a manual refresh.\n */\nexport async function fetchOssApps(base: string, force = false): Promise<OssApp[]> {\n const key = base.replace(/\\/+$/, '')\n if (!force) {\n const hit = cache.get(key)\n if (hit) return hit\n const pending = inflight.get(key)\n if (pending) return pending\n }\n const run = (async () => {\n const res = await fetch(`${key}/meta.json`, {\n headers: { Accept: 'application/json' },\n // Public catalog — no credentials, so a session cookie never leaks cross-origin.\n credentials: 'omit',\n })\n if (!res.ok) throw new Error(`Catalog unavailable (HTTP ${res.status})`)\n const apps = normalizeOssApps(await res.json())\n cache.set(key, apps)\n return apps\n })()\n inflight.set(key, run)\n try {\n return await run\n } finally {\n inflight.delete(key)\n }\n}\n\n/**\n * Fetch one app's `docker-compose.yml` as raw text, or null when the entry publishes\n * none. A 404 is a NORMAL answer for a large community catalog — not every blueprint\n * ships compose — so this never throws: a detail view treats an absent blueprint as\n * \"nothing to show\", and an optional asset must not fail a whole page.\n */\nexport async function fetchCompose(base: string, id: string): Promise<string | null> {\n try {\n const res = await fetch(`${blueprintBase(base, id)}/docker-compose.yml`, {\n headers: { Accept: 'text/plain' },\n credentials: 'omit',\n })\n if (!res.ok) return null\n const text = await res.text()\n return text.trim() ? text : null\n } catch {\n return null\n }\n}\n","/**\n * What an OSS blueprint actually provisions, read from its own `docker-compose.yml`.\n *\n * This is the one implementation. It was written twice before it lived here — once in\n * TypeScript for the console's App Store and once in vanilla JS for oss.hanzo.ai — and\n * two readers of the same file format drift, which means two surfaces can disagree\n * about what a deploy will start.\n *\n * Deliberately a SMALL structural reader, not a YAML implementation: it walks the\n * `services:` block by indentation and pulls only the keys a detail view shows.\n * Anything it cannot read is absent, never guessed, so a surface degrades to \"no\n * blueprint detail\" instead of asserting something false about what will run.\n *\n * Pure and total — it never throws on malformed or hostile input — so it is safe to\n * run on untrusted CDN content and testable without a DOM or a network.\n */\n\n/**\n * One service a blueprint provisions. `image` is absent for a service built from\n * source (`build:` rather than `image:`).\n */\nexport type Service = { name: string; image?: string; ports: string[] }\n\n/** What a blueprint provisions: the containers it starts and the config it expects. */\nexport type Blueprint = { services: Service[]; env: string[] }\n\n/** Indent width of a line, tabs counted as one column (compose files are space-indented). */\nconst indent = (line: string): number => line.length - line.trimStart().length\n\n/**\n * Parse the load-bearing facts out of a `docker-compose.yml`: the services it starts\n * (with image + published ports) and the environment keys it expects.\n *\n * Environment KEYS only — never the values, which are routinely secrets.\n */\nexport function parseBlueprint(yaml: string): Blueprint {\n const lines = String(yaml ?? '').split(/\\r?\\n/)\n const services: Service[] = []\n const env = new Set<string>()\n\n let servicesAt = -1 // indent of the `services:` key, -1 until seen\n let current: Service | null = null\n let currentAt = -1 // indent of the current service's name (bookkeeping, not a field)\n let listKey: 'ports' | 'environment' | null = null\n let listAt = -1\n\n for (const raw of lines) {\n const line = raw.replace(/\\t/g, ' ')\n const trimmed = line.trim()\n if (!trimmed || trimmed.startsWith('#')) continue\n const col = indent(line)\n\n if (servicesAt < 0) {\n if (/^services\\s*:/.test(trimmed)) servicesAt = col\n continue\n }\n // Dedent back to or past `services:` ends the block (e.g. a following `volumes:`).\n if (col <= servicesAt) {\n if (!/^services\\s*:/.test(trimmed)) break\n continue\n }\n\n // A service name sits exactly one level inside `services:`.\n if (current === null || col <= currentAt) {\n const m = trimmed.match(/^([A-Za-z0-9._-]+)\\s*:\\s*$/)\n if (m) {\n current = { name: m[1], ports: [] }\n currentAt = col\n services.push(current)\n listKey = null\n continue\n }\n }\n if (!current) continue\n\n if (listKey && col > listAt && trimmed.startsWith('-')) {\n const item = trimmed.replace(/^-\\s*/, '').replace(/^[\"']|[\"']$/g, '')\n if (listKey === 'ports') current.ports.push(item)\n else {\n const key = item.split(/[=:]/)[0]?.trim()\n if (key) env.add(key)\n }\n continue\n }\n listKey = null\n\n const img = trimmed.match(/^image\\s*:\\s*(.+)$/)\n if (img) {\n current.image = img[1].trim().replace(/^[\"']|[\"']$/g, '')\n continue\n }\n if (/^ports\\s*:/.test(trimmed)) {\n listKey = 'ports'\n listAt = col\n continue\n }\n if (/^environment\\s*:/.test(trimmed)) {\n listKey = 'environment'\n listAt = col\n continue\n }\n }\n\n return { services, env: [...env].sort((a, b) => a.localeCompare(b)) }\n}\n"]}
@@ -0,0 +1,21 @@
1
+ import type { Org } from './scope';
2
+ /**
3
+ * The monogram for a name: the first letter of each of the first two words,
4
+ * uppercased — the SAME rule @hanzo/iam's account widget applies to a person, so
5
+ * a workspace and a user wear one treatment. Words break on whitespace and on the
6
+ * separators an org id carries (`.`, `_`, `-`, `/`), so `acme-labs` reads AL
7
+ * while a single word reads its one initial.
8
+ */
9
+ export declare function monogram(name: string): string;
10
+ export type OrgMarkProps = {
11
+ /** The org to mark — its `logo` wins, else the monogram of its display name. */
12
+ org: Org;
13
+ /** Edge of the square tile / height of the logo. Default 22. */
14
+ size?: number;
15
+ /**
16
+ * Widest a LOGO may run, for a wordmark that is not square. Omit to keep the
17
+ * logo square like the monogram (a switcher row, an avatar slot).
18
+ */
19
+ maxW?: number;
20
+ };
21
+ export declare function OrgMark({ org, size, maxW }: OrgMarkProps): import("react/jsx-runtime").JSX.Element;
@@ -10,9 +10,16 @@ export type OrgSwitcherProps = {
10
10
  orgs?: (page: number, query: string) => Promise<Org[]>;
11
11
  /** Rows per page the loader returns. Default 20. */
12
12
  pageSize?: number;
13
+ /**
14
+ * The org the surface is scoped to, already resolved (display name + logo).
15
+ * Omit and the trigger synthesizes it from the scope id alone — enough to name
16
+ * the org, but it cannot know a logo. Pass it wherever the host already
17
+ * resolves the org, so the switcher and the chrome's org mark agree.
18
+ */
19
+ current?: Org;
13
20
  /** Create-org hook → the created org's id; omit to hide the affordance. */
14
21
  create?: (name: string) => Promise<string>;
15
22
  /** Show the "All organizations" de-scope row (`scope.leaveOrg`). */
16
23
  picker?: boolean;
17
24
  };
18
- export declare function OrgSwitcher({ scope, orgs, pageSize, create, picker }: OrgSwitcherProps): import("react/jsx-runtime").JSX.Element;
25
+ export declare function OrgSwitcher({ scope, orgs, pageSize, current: given, create, picker }: OrgSwitcherProps): import("react/jsx-runtime").JSX.Element;
@@ -1,266 +1,274 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunkHSPMQQVJ_cjs = require('../chunk-HSPMQQVJ.cjs');
4
+ var chunkM2ILMK44_cjs = require('../chunk-M2ILMK44.cjs');
5
5
  var chunkYBXVUV7P_cjs = require('../chunk-YBXVUV7P.cjs');
6
6
 
7
7
 
8
8
 
9
9
  Object.defineProperty(exports, "AppHeader", {
10
10
  enumerable: true,
11
- get: function () { return chunkHSPMQQVJ_cjs.AppHeader; }
11
+ get: function () { return chunkM2ILMK44_cjs.AppHeader; }
12
12
  });
13
13
  Object.defineProperty(exports, "BarChart", {
14
14
  enumerable: true,
15
- get: function () { return chunkHSPMQQVJ_cjs.BarChart; }
15
+ get: function () { return chunkM2ILMK44_cjs.BarChart; }
16
16
  });
17
17
  Object.defineProperty(exports, "BarRows", {
18
18
  enumerable: true,
19
- get: function () { return chunkHSPMQQVJ_cjs.BarRows; }
19
+ get: function () { return chunkM2ILMK44_cjs.BarRows; }
20
20
  });
21
21
  Object.defineProperty(exports, "BrandMark", {
22
22
  enumerable: true,
23
- get: function () { return chunkHSPMQQVJ_cjs.BrandMark; }
23
+ get: function () { return chunkM2ILMK44_cjs.BrandMark; }
24
24
  });
25
25
  Object.defineProperty(exports, "CHART_OTHER", {
26
26
  enumerable: true,
27
- get: function () { return chunkHSPMQQVJ_cjs.CHART_OTHER; }
27
+ get: function () { return chunkM2ILMK44_cjs.CHART_OTHER; }
28
28
  });
29
29
  Object.defineProperty(exports, "CHART_PALETTE", {
30
30
  enumerable: true,
31
- get: function () { return chunkHSPMQQVJ_cjs.CHART_PALETTE; }
31
+ get: function () { return chunkM2ILMK44_cjs.CHART_PALETTE; }
32
32
  });
33
33
  Object.defineProperty(exports, "ComboBox", {
34
34
  enumerable: true,
35
- get: function () { return chunkHSPMQQVJ_cjs.ComboBox; }
35
+ get: function () { return chunkM2ILMK44_cjs.ComboBox; }
36
36
  });
37
37
  Object.defineProperty(exports, "ContextMenu", {
38
38
  enumerable: true,
39
- get: function () { return chunkHSPMQQVJ_cjs.ContextMenu; }
39
+ get: function () { return chunkM2ILMK44_cjs.ContextMenu; }
40
40
  });
41
41
  Object.defineProperty(exports, "CustomModelMark", {
42
42
  enumerable: true,
43
- get: function () { return chunkHSPMQQVJ_cjs.Boxes; }
43
+ get: function () { return chunkM2ILMK44_cjs.Boxes; }
44
44
  });
45
45
  Object.defineProperty(exports, "DataTable", {
46
46
  enumerable: true,
47
- get: function () { return chunkHSPMQQVJ_cjs.DataTable; }
47
+ get: function () { return chunkM2ILMK44_cjs.DataTable; }
48
48
  });
49
49
  Object.defineProperty(exports, "Donut", {
50
50
  enumerable: true,
51
- get: function () { return chunkHSPMQQVJ_cjs.Donut; }
51
+ get: function () { return chunkM2ILMK44_cjs.Donut; }
52
52
  });
53
53
  Object.defineProperty(exports, "DonutRing", {
54
54
  enumerable: true,
55
- get: function () { return chunkHSPMQQVJ_cjs.Donut2; }
55
+ get: function () { return chunkM2ILMK44_cjs.Donut2; }
56
56
  });
57
57
  Object.defineProperty(exports, "DropdownMenu", {
58
58
  enumerable: true,
59
- get: function () { return chunkHSPMQQVJ_cjs.DropdownMenu; }
59
+ get: function () { return chunkM2ILMK44_cjs.DropdownMenu; }
60
60
  });
61
61
  Object.defineProperty(exports, "EmptyState", {
62
62
  enumerable: true,
63
- get: function () { return chunkHSPMQQVJ_cjs.EmptyState; }
63
+ get: function () { return chunkM2ILMK44_cjs.EmptyState; }
64
64
  });
65
65
  Object.defineProperty(exports, "FadeIn", {
66
66
  enumerable: true,
67
- get: function () { return chunkHSPMQQVJ_cjs.FadeIn; }
67
+ get: function () { return chunkM2ILMK44_cjs.FadeIn; }
68
68
  });
69
69
  Object.defineProperty(exports, "FieldRow", {
70
70
  enumerable: true,
71
- get: function () { return chunkHSPMQQVJ_cjs.FieldRow; }
71
+ get: function () { return chunkM2ILMK44_cjs.FieldRow; }
72
72
  });
73
73
  Object.defineProperty(exports, "FieldSelect", {
74
74
  enumerable: true,
75
- get: function () { return chunkHSPMQQVJ_cjs.FieldSelect; }
75
+ get: function () { return chunkM2ILMK44_cjs.FieldSelect; }
76
76
  });
77
77
  Object.defineProperty(exports, "FieldSlider", {
78
78
  enumerable: true,
79
- get: function () { return chunkHSPMQQVJ_cjs.FieldSlider; }
79
+ get: function () { return chunkM2ILMK44_cjs.FieldSlider; }
80
80
  });
81
81
  Object.defineProperty(exports, "FieldSwitch", {
82
82
  enumerable: true,
83
- get: function () { return chunkHSPMQQVJ_cjs.FieldSwitch; }
83
+ get: function () { return chunkM2ILMK44_cjs.FieldSwitch; }
84
84
  });
85
85
  Object.defineProperty(exports, "FieldText", {
86
86
  enumerable: true,
87
- get: function () { return chunkHSPMQQVJ_cjs.FieldText; }
87
+ get: function () { return chunkM2ILMK44_cjs.FieldText; }
88
88
  });
89
89
  Object.defineProperty(exports, "FieldTextArea", {
90
90
  enumerable: true,
91
- get: function () { return chunkHSPMQQVJ_cjs.FieldTextArea; }
91
+ get: function () { return chunkM2ILMK44_cjs.FieldTextArea; }
92
92
  });
93
93
  Object.defineProperty(exports, "FloatingMenu", {
94
94
  enumerable: true,
95
- get: function () { return chunkHSPMQQVJ_cjs.FloatingMenu; }
95
+ get: function () { return chunkM2ILMK44_cjs.FloatingMenu; }
96
96
  });
97
97
  Object.defineProperty(exports, "GenericLogo", {
98
98
  enumerable: true,
99
- get: function () { return chunkHSPMQQVJ_cjs.GenericLogo; }
99
+ get: function () { return chunkM2ILMK44_cjs.GenericLogo; }
100
100
  });
101
101
  Object.defineProperty(exports, "HanzoMark", {
102
102
  enumerable: true,
103
- get: function () { return chunkHSPMQQVJ_cjs.HanzoMark; }
103
+ get: function () { return chunkM2ILMK44_cjs.HanzoMark; }
104
104
  });
105
105
  Object.defineProperty(exports, "HintButton", {
106
106
  enumerable: true,
107
- get: function () { return chunkHSPMQQVJ_cjs.HintButton; }
107
+ get: function () { return chunkM2ILMK44_cjs.HintButton; }
108
108
  });
109
109
  Object.defineProperty(exports, "LegendDot", {
110
110
  enumerable: true,
111
- get: function () { return chunkHSPMQQVJ_cjs.LegendDot; }
111
+ get: function () { return chunkM2ILMK44_cjs.LegendDot; }
112
112
  });
113
113
  Object.defineProperty(exports, "LineChart", {
114
114
  enumerable: true,
115
- get: function () { return chunkHSPMQQVJ_cjs.LineChart; }
115
+ get: function () { return chunkM2ILMK44_cjs.LineChart; }
116
116
  });
117
117
  Object.defineProperty(exports, "MenuItemView", {
118
118
  enumerable: true,
119
- get: function () { return chunkHSPMQQVJ_cjs.MenuItemView; }
119
+ get: function () { return chunkM2ILMK44_cjs.MenuItemView; }
120
120
  });
121
121
  Object.defineProperty(exports, "MenuLabelView", {
122
122
  enumerable: true,
123
- get: function () { return chunkHSPMQQVJ_cjs.MenuLabelView; }
123
+ get: function () { return chunkM2ILMK44_cjs.MenuLabelView; }
124
124
  });
125
125
  Object.defineProperty(exports, "MenuPanel", {
126
126
  enumerable: true,
127
- get: function () { return chunkHSPMQQVJ_cjs.MenuPanel; }
127
+ get: function () { return chunkM2ILMK44_cjs.MenuPanel; }
128
128
  });
129
129
  Object.defineProperty(exports, "MenuSeparatorView", {
130
130
  enumerable: true,
131
- get: function () { return chunkHSPMQQVJ_cjs.MenuSeparatorView; }
131
+ get: function () { return chunkM2ILMK44_cjs.MenuSeparatorView; }
132
132
  });
133
133
  Object.defineProperty(exports, "MetricCard", {
134
134
  enumerable: true,
135
- get: function () { return chunkHSPMQQVJ_cjs.MetricCard; }
135
+ get: function () { return chunkM2ILMK44_cjs.MetricCard; }
136
136
  });
137
137
  Object.defineProperty(exports, "MetricSparkline", {
138
138
  enumerable: true,
139
- get: function () { return chunkHSPMQQVJ_cjs.Sparkline2; }
139
+ get: function () { return chunkM2ILMK44_cjs.Sparkline2; }
140
140
  });
141
141
  Object.defineProperty(exports, "MiniBars", {
142
142
  enumerable: true,
143
- get: function () { return chunkHSPMQQVJ_cjs.MiniBars; }
143
+ get: function () { return chunkM2ILMK44_cjs.MiniBars; }
144
+ });
145
+ Object.defineProperty(exports, "OrgMark", {
146
+ enumerable: true,
147
+ get: function () { return chunkM2ILMK44_cjs.OrgMark; }
144
148
  });
145
149
  Object.defineProperty(exports, "OrgSwitcher", {
146
150
  enumerable: true,
147
- get: function () { return chunkHSPMQQVJ_cjs.OrgSwitcher; }
151
+ get: function () { return chunkM2ILMK44_cjs.OrgSwitcher; }
148
152
  });
149
153
  Object.defineProperty(exports, "PageHeader", {
150
154
  enumerable: true,
151
- get: function () { return chunkHSPMQQVJ_cjs.PageHeader; }
155
+ get: function () { return chunkM2ILMK44_cjs.PageHeader; }
152
156
  });
153
157
  Object.defineProperty(exports, "Panel", {
154
158
  enumerable: true,
155
- get: function () { return chunkHSPMQQVJ_cjs.Panel; }
159
+ get: function () { return chunkM2ILMK44_cjs.Panel; }
156
160
  });
157
161
  Object.defineProperty(exports, "PortalTheme", {
158
162
  enumerable: true,
159
- get: function () { return chunkHSPMQQVJ_cjs.PortalTheme; }
163
+ get: function () { return chunkM2ILMK44_cjs.PortalTheme; }
160
164
  });
161
165
  Object.defineProperty(exports, "PrimaryButton", {
162
166
  enumerable: true,
163
- get: function () { return chunkHSPMQQVJ_cjs.PrimaryButton; }
167
+ get: function () { return chunkM2ILMK44_cjs.PrimaryButton; }
164
168
  });
165
169
  Object.defineProperty(exports, "ProductIcon", {
166
170
  enumerable: true,
167
- get: function () { return chunkHSPMQQVJ_cjs.ProductIcon; }
171
+ get: function () { return chunkM2ILMK44_cjs.ProductIcon; }
168
172
  });
169
173
  Object.defineProperty(exports, "ProviderLogo", {
170
174
  enumerable: true,
171
- get: function () { return chunkHSPMQQVJ_cjs.ProviderLogo; }
175
+ get: function () { return chunkM2ILMK44_cjs.ProviderLogo; }
172
176
  });
173
177
  Object.defineProperty(exports, "Reorder", {
174
178
  enumerable: true,
175
- get: function () { return chunkHSPMQQVJ_cjs.Reorder; }
179
+ get: function () { return chunkM2ILMK44_cjs.Reorder; }
176
180
  });
177
181
  Object.defineProperty(exports, "SERIES", {
178
182
  enumerable: true,
179
- get: function () { return chunkHSPMQQVJ_cjs.SERIES; }
183
+ get: function () { return chunkM2ILMK44_cjs.SERIES; }
180
184
  });
181
185
  Object.defineProperty(exports, "SLIDEOVER_LG", {
182
186
  enumerable: true,
183
- get: function () { return chunkHSPMQQVJ_cjs.LG; }
187
+ get: function () { return chunkM2ILMK44_cjs.LG; }
184
188
  });
185
189
  Object.defineProperty(exports, "SURFACES", {
186
190
  enumerable: true,
187
- get: function () { return chunkHSPMQQVJ_cjs.SURFACES; }
191
+ get: function () { return chunkM2ILMK44_cjs.SURFACES; }
188
192
  });
189
193
  Object.defineProperty(exports, "SelectMenu", {
190
194
  enumerable: true,
191
- get: function () { return chunkHSPMQQVJ_cjs.SelectMenu; }
195
+ get: function () { return chunkM2ILMK44_cjs.SelectMenu; }
192
196
  });
193
197
  Object.defineProperty(exports, "SlideOver", {
194
198
  enumerable: true,
195
- get: function () { return chunkHSPMQQVJ_cjs.SlideOver; }
199
+ get: function () { return chunkM2ILMK44_cjs.SlideOver; }
196
200
  });
197
201
  Object.defineProperty(exports, "Sparkline", {
198
202
  enumerable: true,
199
- get: function () { return chunkHSPMQQVJ_cjs.Sparkline; }
203
+ get: function () { return chunkM2ILMK44_cjs.Sparkline; }
200
204
  });
201
205
  Object.defineProperty(exports, "StatusTag", {
202
206
  enumerable: true,
203
- get: function () { return chunkHSPMQQVJ_cjs.StatusTag; }
207
+ get: function () { return chunkM2ILMK44_cjs.StatusTag; }
204
208
  });
205
209
  Object.defineProperty(exports, "ToastProvider", {
206
210
  enumerable: true,
207
- get: function () { return chunkHSPMQQVJ_cjs.ToastProvider; }
211
+ get: function () { return chunkM2ILMK44_cjs.ToastProvider; }
208
212
  });
209
213
  Object.defineProperty(exports, "UtilBar", {
210
214
  enumerable: true,
211
- get: function () { return chunkHSPMQQVJ_cjs.UtilBar; }
215
+ get: function () { return chunkM2ILMK44_cjs.UtilBar; }
212
216
  });
213
217
  Object.defineProperty(exports, "asColor", {
214
218
  enumerable: true,
215
- get: function () { return chunkHSPMQQVJ_cjs.asColor; }
219
+ get: function () { return chunkM2ILMK44_cjs.asColor; }
216
220
  });
217
221
  Object.defineProperty(exports, "colorForIndex", {
218
222
  enumerable: true,
219
- get: function () { return chunkHSPMQQVJ_cjs.colorForIndex; }
223
+ get: function () { return chunkM2ILMK44_cjs.colorForIndex; }
220
224
  });
221
225
  Object.defineProperty(exports, "filterOptions", {
222
226
  enumerable: true,
223
- get: function () { return chunkHSPMQQVJ_cjs.filterOptions; }
227
+ get: function () { return chunkM2ILMK44_cjs.filterOptions; }
224
228
  });
225
229
  Object.defineProperty(exports, "filterOrgs", {
226
230
  enumerable: true,
227
- get: function () { return chunkHSPMQQVJ_cjs.filterOrgs; }
231
+ get: function () { return chunkM2ILMK44_cjs.filterOrgs; }
228
232
  });
229
233
  Object.defineProperty(exports, "isKnownOption", {
230
234
  enumerable: true,
231
- get: function () { return chunkHSPMQQVJ_cjs.isKnownOption; }
235
+ get: function () { return chunkM2ILMK44_cjs.isKnownOption; }
236
+ });
237
+ Object.defineProperty(exports, "monogram", {
238
+ enumerable: true,
239
+ get: function () { return chunkM2ILMK44_cjs.monogram; }
232
240
  });
233
241
  Object.defineProperty(exports, "orgScope", {
234
242
  enumerable: true,
235
- get: function () { return chunkHSPMQQVJ_cjs.orgScope; }
243
+ get: function () { return chunkM2ILMK44_cjs.orgScope; }
236
244
  });
237
245
  Object.defineProperty(exports, "otherSurfaces", {
238
246
  enumerable: true,
239
- get: function () { return chunkHSPMQQVJ_cjs.otherSurfaces; }
247
+ get: function () { return chunkM2ILMK44_cjs.otherSurfaces; }
240
248
  });
241
249
  Object.defineProperty(exports, "providerInitials", {
242
250
  enumerable: true,
243
- get: function () { return chunkHSPMQQVJ_cjs.providerInitials; }
251
+ get: function () { return chunkM2ILMK44_cjs.providerInitials; }
244
252
  });
245
253
  Object.defineProperty(exports, "renderMenuItems", {
246
254
  enumerable: true,
247
- get: function () { return chunkHSPMQQVJ_cjs.renderMenuItems; }
255
+ get: function () { return chunkM2ILMK44_cjs.renderMenuItems; }
248
256
  });
249
257
  Object.defineProperty(exports, "rowShift", {
250
258
  enumerable: true,
251
- get: function () { return chunkHSPMQQVJ_cjs.rowShift; }
259
+ get: function () { return chunkM2ILMK44_cjs.rowShift; }
252
260
  });
253
261
  Object.defineProperty(exports, "targetIndex", {
254
262
  enumerable: true,
255
- get: function () { return chunkHSPMQQVJ_cjs.targetIndex; }
263
+ get: function () { return chunkM2ILMK44_cjs.targetIndex; }
256
264
  });
257
265
  Object.defineProperty(exports, "useToast", {
258
266
  enumerable: true,
259
- get: function () { return chunkHSPMQQVJ_cjs.useToast; }
267
+ get: function () { return chunkM2ILMK44_cjs.useToast; }
260
268
  });
261
269
  Object.defineProperty(exports, "utilColor", {
262
270
  enumerable: true,
263
- get: function () { return chunkHSPMQQVJ_cjs.utilColor; }
271
+ get: function () { return chunkM2ILMK44_cjs.utilColor; }
264
272
  });
265
273
  Object.defineProperty(exports, "AgnosticThemeToggle", {
266
274
  enumerable: true,
@@ -6,6 +6,7 @@ export * from './combobox/filter';
6
6
  export * from './surfaces.data';
7
7
  export * from './AppHeader';
8
8
  export * from './BrandMark';
9
+ export * from './OrgMark';
9
10
  export * from './OrgSwitcher';
10
11
  export * from './scope';
11
12
  export * from './menu';