@cat-factory/integrations 0.25.2 → 0.26.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.
Files changed (41) hide show
  1. package/dist/index.d.ts +7 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +8 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/modules/documents/ClaudeDesignProvider.d.ts +32 -0
  6. package/dist/modules/documents/ClaudeDesignProvider.d.ts.map +1 -0
  7. package/dist/modules/documents/ClaudeDesignProvider.js +163 -0
  8. package/dist/modules/documents/ClaudeDesignProvider.js.map +1 -0
  9. package/dist/modules/documents/ConfluenceProvider.d.ts +2 -1
  10. package/dist/modules/documents/ConfluenceProvider.d.ts.map +1 -1
  11. package/dist/modules/documents/DocumentConnectionService.d.ts +28 -11
  12. package/dist/modules/documents/DocumentConnectionService.d.ts.map +1 -1
  13. package/dist/modules/documents/DocumentConnectionService.js +71 -12
  14. package/dist/modules/documents/DocumentConnectionService.js.map +1 -1
  15. package/dist/modules/documents/DocumentImportService.d.ts +9 -3
  16. package/dist/modules/documents/DocumentImportService.d.ts.map +1 -1
  17. package/dist/modules/documents/DocumentImportService.js +11 -5
  18. package/dist/modules/documents/DocumentImportService.js.map +1 -1
  19. package/dist/modules/documents/FigmaProvider.d.ts +42 -0
  20. package/dist/modules/documents/FigmaProvider.d.ts.map +1 -0
  21. package/dist/modules/documents/FigmaProvider.js +176 -0
  22. package/dist/modules/documents/FigmaProvider.js.map +1 -0
  23. package/dist/modules/documents/GitHubDocsProvider.d.ts +2 -1
  24. package/dist/modules/documents/GitHubDocsProvider.d.ts.map +1 -1
  25. package/dist/modules/documents/LinearDocumentProvider.d.ts +2 -1
  26. package/dist/modules/documents/LinearDocumentProvider.d.ts.map +1 -1
  27. package/dist/modules/documents/NotionProvider.d.ts +2 -1
  28. package/dist/modules/documents/NotionProvider.d.ts.map +1 -1
  29. package/dist/modules/documents/claudeDesign.logic.d.ts +88 -0
  30. package/dist/modules/documents/claudeDesign.logic.d.ts.map +1 -0
  31. package/dist/modules/documents/claudeDesign.logic.js +317 -0
  32. package/dist/modules/documents/claudeDesign.logic.js.map +1 -0
  33. package/dist/modules/documents/figma.logic.d.ts +98 -0
  34. package/dist/modules/documents/figma.logic.d.ts.map +1 -0
  35. package/dist/modules/documents/figma.logic.js +249 -0
  36. package/dist/modules/documents/figma.logic.js.map +1 -0
  37. package/dist/modules/documents/http.d.ts +35 -0
  38. package/dist/modules/documents/http.d.ts.map +1 -0
  39. package/dist/modules/documents/http.js +120 -0
  40. package/dist/modules/documents/http.js.map +1 -0
  41. package/package.json +3 -3
@@ -0,0 +1,317 @@
1
+ import { assertHostPinned } from './http.js';
2
+ // Claude-Design pure logic, kept out of the provider shell so it is unit-testable
3
+ // without a live API: the connect-form descriptor, parsing a project/file ref out of
4
+ // user input, the fixed-host SSRF guard, and — the part that earns the provider its
5
+ // place over a plain HTML upload — a deterministic **design-system normalizer** that
6
+ // turns a Claude Design project's manifest + component-preview HTML into the same
7
+ // lightweight Markdown shape the Figma provider emits (`### Components`, `### Design
8
+ // tokens`), so a frontend agent reads the design system the same way regardless of
9
+ // which tool authored it. The `fetch` itself lives in `ClaudeDesignProvider`.
10
+ //
11
+ // Why a normalizer and not pass-through: a Claude Design export bundle is raw component
12
+ // HTML + CSS. Handed to an agent verbatim it is noise (markup, scripts, inline styles).
13
+ // The value is the *structure* — which components exist, grouped how, and what design
14
+ // tokens (CSS custom properties) back them. That extraction is deterministic, so it is
15
+ // backend TS here, not an LLM step, and it is what distinguishes this provider from
16
+ // attaching the same HTML as a generic document.
17
+ /**
18
+ * Claude Design's programmatic-read host. PROVISIONAL: today the design-system read is
19
+ * bound to a claude.ai login; this provider targets the per-user-PAT API shape the
20
+ * product is moving toward. The host is pinned (see {@link assertSafeClaudeDesignUrl})
21
+ * and the exact endpoints in `ClaudeDesignProvider` should be re-verified against the
22
+ * current API when the credentialed read ships — treat them as the intended shape, not a
23
+ * frozen contract.
24
+ */
25
+ export const CLAUDE_DESIGN_API_HOST = 'api.claude.com';
26
+ /** Where a human opens the project (the canonical URL stored on imported documents). */
27
+ export const CLAUDE_DESIGN_APP_HOST = 'claude.ai';
28
+ /** What the connect UI renders, and which credentials the provider needs. */
29
+ export const CLAUDE_DESIGN_DESCRIPTOR = {
30
+ source: 'claude-design',
31
+ label: 'Claude Design',
32
+ icon: 'i-lucide-palette',
33
+ credentialFields: [
34
+ {
35
+ key: 'apiToken',
36
+ label: 'Personal access token',
37
+ secret: true,
38
+ placeholder: 'sk-ant-…',
39
+ help: 'A Claude Design personal access token authenticates as your own account, so it is stored per user and never shared with the rest of the workspace. Create one in claude.ai → Settings → Design.',
40
+ },
41
+ ],
42
+ refLabel: 'Claude Design project or component URL',
43
+ refPlaceholder: 'https://claude.ai/design/<projectId>',
44
+ // No catalogue search over a PAT — import a specific project/component by URL.
45
+ searchable: false,
46
+ // Personal token: each member connects their own; stored keyed by user id.
47
+ credentialScope: 'user',
48
+ };
49
+ /**
50
+ * The Claude Design read host is fixed, so any request/redirect must stay on it over
51
+ * https. A redirect off-host (e.g. to a link-local metadata address) is rejected as an
52
+ * SSRF attempt. Delegates to the shared host-pin guard; throws a plain `Error` the
53
+ * provider maps to a `DocumentHttpError`. Kept pure so it is unit-testable without a
54
+ * network.
55
+ */
56
+ export function assertSafeClaudeDesignUrl(url) {
57
+ assertHostPinned(url, CLAUDE_DESIGN_API_HOST, 'Claude Design');
58
+ }
59
+ // ---- Ref parsing + canonical URL ------------------------------------------
60
+ /** Composite external id delimiter: `<projectId>` or `<projectId>::<filePath>`. */
61
+ const REF_DELIM = '::';
62
+ const PROJECT_ID_RE = /^[A-Za-z0-9_-]+$/;
63
+ /**
64
+ * Resolve a Claude Design reference from raw user input into the stable composite
65
+ * external id this provider stores: `"<projectId>"` for a whole project, or
66
+ * `"<projectId>::<filePath>"` for a single component/file. Accepts a
67
+ * `claude.ai/design/<projectId>` URL (optionally `…/files/<path>` or `?file=<path>`), a
68
+ * bare project id, or the composite form. Returns null when no project id is found.
69
+ *
70
+ * Deterministic (same input → same external id), which the
71
+ * `(workspace, source, externalId)` document key relies on for de-duplication.
72
+ */
73
+ export function parseClaudeDesignRef(input) {
74
+ const trimmed = input.trim();
75
+ if (!trimmed)
76
+ return null;
77
+ // Bare ref (anything that isn't an absolute URL): a project id, optionally
78
+ // `::`-suffixed with a file path (the path may itself contain `/`). Keyed off the
79
+ // `://` scheme separator so a bare `projectId::path` is never mis-parsed as a URL.
80
+ if (!trimmed.includes('://')) {
81
+ const [projectId, ...rest] = trimmed.split(REF_DELIM);
82
+ if (!projectId || !PROJECT_ID_RE.test(projectId))
83
+ return null;
84
+ const path = rest.join(REF_DELIM).trim();
85
+ return path ? `${projectId}${REF_DELIM}${normalizeFilePath(path)}` : projectId;
86
+ }
87
+ let url;
88
+ try {
89
+ url = new URL(trimmed);
90
+ }
91
+ catch {
92
+ return null;
93
+ }
94
+ if (!/(^|\.)claude\.(ai|com)$/i.test(url.hostname))
95
+ return null;
96
+ const segments = url.pathname.split('/').filter(Boolean);
97
+ const designIdx = segments.indexOf('design');
98
+ if (designIdx === -1 || designIdx + 1 >= segments.length)
99
+ return null;
100
+ const projectId = segments[designIdx + 1];
101
+ if (!PROJECT_ID_RE.test(projectId))
102
+ return null;
103
+ // A file path may follow as `…/design/<id>/files/<path…>` or `?file=<path>`.
104
+ const after = segments.slice(designIdx + 2);
105
+ const fileSegments = after[0] === 'files' ? after.slice(1) : after;
106
+ const queryFile = url.searchParams.get('file') ?? url.searchParams.get('path');
107
+ const rawPath = queryFile ?? (fileSegments.length ? fileSegments.join('/') : '');
108
+ const path = rawPath ? normalizeFilePath(rawPath) : '';
109
+ return path ? `${projectId}${REF_DELIM}${path}` : projectId;
110
+ }
111
+ /** Strip leading slashes and collapse `.`/empty segments from a file path. */
112
+ function normalizeFilePath(path) {
113
+ return path
114
+ .split('/')
115
+ .map((s) => s.trim())
116
+ .filter((s) => s && s !== '.')
117
+ .join('/');
118
+ }
119
+ /** Split a composite external id back into its project id and optional file path. */
120
+ export function splitClaudeDesignExternalId(externalId) {
121
+ const idx = externalId.indexOf(REF_DELIM);
122
+ if (idx === -1)
123
+ return { projectId: externalId };
124
+ const filePath = externalId.slice(idx + REF_DELIM.length);
125
+ return { projectId: externalId.slice(0, idx), filePath: filePath || undefined };
126
+ }
127
+ /** Build the canonical web URL stored on the imported document (matched by `getByUrl`). */
128
+ export function claudeDesignUrlFor(externalId) {
129
+ const { projectId, filePath } = splitClaudeDesignExternalId(externalId);
130
+ const base = `https://${CLAUDE_DESIGN_APP_HOST}/design/${projectId}`;
131
+ return filePath ? `${base}/files/${filePath}` : base;
132
+ }
133
+ /** The manifest file name Claude Design compiles its card index into. */
134
+ export const DS_MANIFEST_PATH = '_ds_manifest.json';
135
+ const MAX_CARDS = 200;
136
+ const MAX_TOKENS = 200;
137
+ const MAX_TEXT_CHARS = 2000;
138
+ /**
139
+ * Parse a `_ds_manifest.json` payload (a bare array of cards, or `{ cards: [...] }`)
140
+ * into a lenient {@link DsCard} list. Unknown shapes yield `[]` so the caller falls
141
+ * back to per-file HTML extraction.
142
+ */
143
+ export function parseDsManifest(json) {
144
+ const raw = Array.isArray(json)
145
+ ? json
146
+ : json && typeof json === 'object' && Array.isArray(json.cards)
147
+ ? json.cards
148
+ : [];
149
+ const cards = [];
150
+ for (const item of raw) {
151
+ if (!item || typeof item !== 'object')
152
+ continue;
153
+ const o = item;
154
+ const card = {};
155
+ if (typeof o.name === 'string')
156
+ card.name = o.name.trim();
157
+ if (typeof o.group === 'string')
158
+ card.group = o.group.trim();
159
+ if (typeof o.subtitle === 'string')
160
+ card.subtitle = o.subtitle.trim();
161
+ if (typeof o.path === 'string')
162
+ card.path = o.path.trim();
163
+ if (card.name || card.path)
164
+ cards.push(card);
165
+ if (cards.length >= MAX_CARDS)
166
+ break;
167
+ }
168
+ return cards;
169
+ }
170
+ const DS_CARD_RE = /<!--\s*@dsCard\s+([^>]*?)-->/i;
171
+ const ATTR_RE = /(\w+)\s*=\s*"([^"]*)"/g;
172
+ /**
173
+ * Read the first-line `<!-- @dsCard group="…" name="…" subtitle="…" -->` marker Claude
174
+ * Design writes at the top of each component-preview HTML. Returns null when absent.
175
+ */
176
+ export function parseDsCardComment(html) {
177
+ const match = DS_CARD_RE.exec(html);
178
+ if (!match)
179
+ return null;
180
+ const attrs = {};
181
+ let m;
182
+ ATTR_RE.lastIndex = 0;
183
+ while ((m = ATTR_RE.exec(match[1])))
184
+ attrs[m[1].toLowerCase()] = m[2].trim();
185
+ const card = {};
186
+ if (attrs.name)
187
+ card.name = attrs.name;
188
+ if (attrs.group)
189
+ card.group = attrs.group;
190
+ if (attrs.subtitle)
191
+ card.subtitle = attrs.subtitle;
192
+ return card.name || card.group ? card : null;
193
+ }
194
+ const CSS_VAR_RE = /(--[A-Za-z0-9_-]+)\s*:\s*([^;{}]+)[;}]/g;
195
+ /**
196
+ * Extract CSS custom properties (`--token: value`) from a stylesheet/HTML blob as design
197
+ * tokens, deduped (last value wins) and sorted. These are Claude Design's design tokens —
198
+ * the analogue of Figma variables.
199
+ */
200
+ export function extractCssTokens(content) {
201
+ const tokens = new Map();
202
+ let m;
203
+ CSS_VAR_RE.lastIndex = 0;
204
+ while ((m = CSS_VAR_RE.exec(content))) {
205
+ const name = m[1];
206
+ const value = m[2].replace(/\s+/g, ' ').trim();
207
+ if (value && !value.startsWith('var('))
208
+ tokens.set(name, value);
209
+ if (tokens.size >= MAX_TOKENS)
210
+ break;
211
+ }
212
+ return [...tokens.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => `${k} = ${v}`);
213
+ }
214
+ /** Strip `<script>`/`<style>` blocks and all tags, returning collapsed visible text. */
215
+ export function htmlToText(html) {
216
+ const text = html
217
+ .replace(/<!--[\s\S]*?-->/g, ' ')
218
+ .replace(/<(script|style)\b[\s\S]*?<\/\1>/gi, ' ')
219
+ .replace(/<[^>]+>/g, ' ')
220
+ .replace(/&nbsp;/g, ' ')
221
+ .replace(/&amp;/g, '&')
222
+ .replace(/&lt;/g, '<')
223
+ .replace(/&gt;/g, '>')
224
+ .replace(/&quot;/g, '"')
225
+ .replace(/&#39;/g, "'")
226
+ .replace(/\s+/g, ' ')
227
+ .trim();
228
+ return text.length > MAX_TEXT_CHARS ? `${text.slice(0, MAX_TEXT_CHARS)}…` : text;
229
+ }
230
+ /** Render a grouped component inventory from a card list (`### <group>` → `- <name>`). */
231
+ export function dsCardsToMarkdown(cards) {
232
+ const byGroup = new Map();
233
+ for (const card of cards) {
234
+ if (!card.name && !card.path)
235
+ continue;
236
+ const group = card.group?.trim() || 'Components';
237
+ const list = byGroup.get(group) ?? [];
238
+ list.push(card);
239
+ byGroup.set(group, list);
240
+ }
241
+ if (byGroup.size === 0)
242
+ return '';
243
+ const lines = ['### Components'];
244
+ for (const group of [...byGroup.keys()].sort()) {
245
+ lines.push(`#### ${group}`);
246
+ const seen = new Set();
247
+ for (const card of byGroup.get(group)) {
248
+ const name = card.name?.trim() || card.path?.trim() || '(unnamed)';
249
+ if (seen.has(name))
250
+ continue;
251
+ seen.add(name);
252
+ lines.push(card.subtitle ? `- ${name} — ${card.subtitle}` : `- ${name}`);
253
+ }
254
+ }
255
+ return lines.join('\n');
256
+ }
257
+ /**
258
+ * Normalize a whole Claude Design project's fetched files into the lightweight Markdown a
259
+ * frontend agent consumes. Strategy:
260
+ * 1. If a `_ds_manifest.json` is present, it is the authoritative component index →
261
+ * `### Components` grouped inventory.
262
+ * 2. Otherwise, recover the inventory from each preview HTML's `@dsCard` marker.
263
+ * 3. Design tokens are unioned from the CSS custom properties across all files.
264
+ * 4. A bounded slice of visible text gives the agent a sense of the content.
265
+ *
266
+ * `projectName` titles the document. Pure: no network, fully unit-testable.
267
+ */
268
+ export function renderClaudeDesignProject(projectName, files) {
269
+ const manifest = files.find((f) => f.path.endsWith(DS_MANIFEST_PATH));
270
+ let cards = [];
271
+ if (manifest) {
272
+ try {
273
+ cards = parseDsManifest(JSON.parse(manifest.content));
274
+ }
275
+ catch {
276
+ cards = [];
277
+ }
278
+ }
279
+ const htmlFiles = files.filter((f) => /\.html?$/i.test(f.path));
280
+ if (cards.length === 0) {
281
+ for (const file of htmlFiles) {
282
+ const card = parseDsCardComment(file.content);
283
+ if (card)
284
+ cards.push({ ...card, path: file.path });
285
+ }
286
+ }
287
+ const tokenSet = new Map();
288
+ for (const file of files) {
289
+ if (file.path.endsWith(DS_MANIFEST_PATH))
290
+ continue;
291
+ for (const entry of extractCssTokens(file.content)) {
292
+ const eq = entry.indexOf(' = ');
293
+ tokenSet.set(entry.slice(0, eq), entry.slice(eq + 3));
294
+ if (tokenSet.size >= MAX_TOKENS)
295
+ break;
296
+ }
297
+ }
298
+ const sections = [`## ${projectName.trim() || 'Claude Design project'}`];
299
+ const inventory = dsCardsToMarkdown(cards);
300
+ if (inventory)
301
+ sections.push(inventory);
302
+ if (tokenSet.size) {
303
+ const tokenLines = [...tokenSet.entries()]
304
+ .sort(([a], [b]) => a.localeCompare(b))
305
+ .map(([k, v]) => `- ${k} = ${v}`);
306
+ sections.push(['### Design tokens', ...tokenLines].join('\n'));
307
+ }
308
+ // A single-component import (one HTML, no manifest) carries little structure, so fold in
309
+ // a slice of its visible text — the same text-content affordance the Figma renderer gives.
310
+ if (!manifest && htmlFiles.length === 1) {
311
+ const text = htmlToText(htmlFiles[0].content);
312
+ if (text)
313
+ sections.push(['### Content', text].join('\n'));
314
+ }
315
+ return sections.join('\n\n').trim();
316
+ }
317
+ //# sourceMappingURL=claudeDesign.logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claudeDesign.logic.js","sourceRoot":"","sources":["../../../src/modules/documents/claudeDesign.logic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ import type { DocumentSourceDescriptor } from '@cat-factory/kernel';
2
+ /** Figma's REST API host. The PAT is sent to this host only — see {@link assertSafeFigmaUrl}. */
3
+ export declare const FIGMA_API_HOST = "api.figma.com";
4
+ /** What the connect UI renders, and which credentials the provider needs. */
5
+ export declare const FIGMA_DESCRIPTOR: DocumentSourceDescriptor;
6
+ /**
7
+ * The Figma REST host is fixed, so any request/redirect must stay on
8
+ * `api.figma.com` over https. A redirect off-host (e.g. to an internal address)
9
+ * is treated as an SSRF attempt and rejected. Mirrors the per-hop guard the other
10
+ * document providers run. Throws a plain `Error` (the provider maps it to a
11
+ * `FigmaApiError`); kept pure so it is unit-testable without a network.
12
+ */
13
+ export declare function assertSafeFigmaUrl(url: string): void;
14
+ /**
15
+ * Normalise a Figma node id to the API/colon form. Figma share URLs encode a
16
+ * node id as `1234-5678` (dash) where the REST API expects `1234:5678` (colon);
17
+ * a `?node-id=1234%3A5678` decodes straight to the colon form. We accept either
18
+ * and return the colon form, or null for anything that isn't a simple
19
+ * `n` / `n:n` node id (complex instance ids like `I12:3;45:6` are dropped → the
20
+ * import falls back to the whole file rather than guessing).
21
+ */
22
+ export declare function normalizeFigmaNodeId(raw: string): string | null;
23
+ /**
24
+ * Resolve a Figma reference from raw user input into the stable composite
25
+ * external id this provider stores: `"<fileKey>"` for a whole-file link, or
26
+ * `"<fileKey>:<nodeId>"` for a specific frame/node (nodeId in colon form).
27
+ * Accepts a `figma.com` file/design/proto/board URL, a bare file key, or a
28
+ * `fileKey:node:id` string. Returns null when no file key is found.
29
+ *
30
+ * `parseRef` is deterministic (same input → same external id), which is what the
31
+ * `(workspace, source, externalId)` document key relies on for de-duplication —
32
+ * URL auto-match via `getByUrl` is a separate, best-effort path keyed on the
33
+ * canonical {@link figmaUrlFor} output.
34
+ */
35
+ export declare function parseFigmaRef(input: string): string | null;
36
+ /** Split a composite external id back into its file key and optional node id (colon form). */
37
+ export declare function splitFigmaExternalId(externalId: string): {
38
+ fileKey: string;
39
+ nodeId?: string;
40
+ };
41
+ /**
42
+ * Build the canonical web URL stored on the imported document (and matched by
43
+ * `getByUrl`). The node id is rendered back in the share-URL dash form so the
44
+ * stored URL matches the kind of link a teammate pastes into a task description.
45
+ */
46
+ export declare function figmaUrlFor(externalId: string): string;
47
+ /** The subset of a Figma node we read for the layout/text/component rendering. */
48
+ export interface FigmaNode {
49
+ id?: string;
50
+ name?: string;
51
+ type?: string;
52
+ characters?: string;
53
+ componentId?: string;
54
+ absoluteBoundingBox?: {
55
+ width?: number;
56
+ height?: number;
57
+ } | null;
58
+ children?: FigmaNode[];
59
+ }
60
+ /** A `componentId → { name }` map (Figma returns it alongside the node tree). */
61
+ export interface FigmaComponentMap {
62
+ [id: string]: {
63
+ name?: string;
64
+ } | undefined;
65
+ }
66
+ /**
67
+ * Convert a fetched Figma node (a frame or a whole file's document) into the
68
+ * lightweight Markdown the planner/agent consume: a `## <name>` heading, a
69
+ * `### Layout` bullet tree, the `### Text content`, and the distinct
70
+ * `### Components used` (matched against the repo's components by the agent).
71
+ */
72
+ export declare function figmaNodesToMarkdown(roots: FigmaNode[], components?: FigmaComponentMap): string;
73
+ interface FigmaVariable {
74
+ name?: string;
75
+ resolvedType?: string;
76
+ variableCollectionId?: string;
77
+ valuesByMode?: Record<string, unknown>;
78
+ }
79
+ interface FigmaVariableCollection {
80
+ name?: string;
81
+ modes?: {
82
+ modeId?: string;
83
+ name?: string;
84
+ }[];
85
+ }
86
+ /** The `/v1/files/:key/variables/local` `meta` payload we read. */
87
+ export interface FigmaVariablesMeta {
88
+ variables?: Record<string, FigmaVariable | undefined>;
89
+ variableCollections?: Record<string, FigmaVariableCollection | undefined>;
90
+ }
91
+ /**
92
+ * Convert the Figma local-variables payload into a `### Design tokens` section,
93
+ * one line per `collection › mode › name = value`. Returns '' when there are no
94
+ * variables (so the caller drops the section entirely).
95
+ */
96
+ export declare function figmaVariablesToMarkdown(meta: FigmaVariablesMeta | undefined): string;
97
+ export {};
98
+ //# sourceMappingURL=figma.logic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/documents/figma.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AASnE,iGAAiG;AACjG,eAAO,MAAM,cAAc,kBAAkB,CAAA;AAE7C,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,EAAE,wBAiB9B,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEpD;AAID;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM/D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA4B1D;AAED,8FAA8F;AAC9F,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAI7F;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAKtD;AAID,kFAAkF;AAClF,MAAM,WAAW,SAAS;IACxB,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mBAAmB,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IAChE,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAA;CACvB;AAED,iFAAiF;AACjF,MAAM,WAAW,iBAAiB;IAChC,CAAC,EAAE,EAAE,MAAM,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAA;CAC5C;AAqDD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,EAAE,EAClB,UAAU,GAAE,iBAAsB,GACjC,MAAM,CA8BR;AAID,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACvC;AAED,UAAU,uBAAuB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAC7C;AAED,mEAAmE;AACnE,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC,CAAA;IACrD,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,GAAG,SAAS,CAAC,CAAA;CAC1E;AAoBD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,kBAAkB,GAAG,SAAS,GAAG,MAAM,CAoBrF"}