@unovis/mcp 1.7.0-mcp.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 (153) hide show
  1. package/LICENSE +193 -0
  2. package/README.md +154 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +109 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/codegen/index.d.ts +14 -0
  7. package/dist/codegen/index.js +346 -0
  8. package/dist/codegen/index.js.map +1 -0
  9. package/dist/env/bbox.d.ts +13 -0
  10. package/dist/env/bbox.js +335 -0
  11. package/dist/env/bbox.js.map +1 -0
  12. package/dist/env/canvas.d.ts +9 -0
  13. package/dist/env/canvas.js +55 -0
  14. package/dist/env/canvas.js.map +1 -0
  15. package/dist/env/computed-style.d.ts +38 -0
  16. package/dist/env/computed-style.js +186 -0
  17. package/dist/env/computed-style.js.map +1 -0
  18. package/dist/env/fonts.d.ts +3 -0
  19. package/dist/env/fonts.js +103 -0
  20. package/dist/env/fonts.js.map +1 -0
  21. package/dist/env/index.d.ts +13 -0
  22. package/dist/env/index.js +121 -0
  23. package/dist/env/index.js.map +1 -0
  24. package/dist/env/raf-queue.d.ts +23 -0
  25. package/dist/env/raf-queue.js +51 -0
  26. package/dist/env/raf-queue.js.map +1 -0
  27. package/dist/env/size.d.ts +9 -0
  28. package/dist/env/size.js +30 -0
  29. package/dist/env/size.js.map +1 -0
  30. package/dist/html/document.d.ts +16 -0
  31. package/dist/html/document.js +95 -0
  32. package/dist/html/document.js.map +1 -0
  33. package/dist/index.d.ts +25 -0
  34. package/dist/index.js +18 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/recipes/area.d.ts +66 -0
  37. package/dist/recipes/area.js +76 -0
  38. package/dist/recipes/area.js.map +1 -0
  39. package/dist/recipes/bar.d.ts +67 -0
  40. package/dist/recipes/bar.js +69 -0
  41. package/dist/recipes/bar.js.map +1 -0
  42. package/dist/recipes/boxplot.d.ts +64 -0
  43. package/dist/recipes/boxplot.js +89 -0
  44. package/dist/recipes/boxplot.js.map +1 -0
  45. package/dist/recipes/chord.d.ts +41 -0
  46. package/dist/recipes/chord.js +72 -0
  47. package/dist/recipes/chord.js.map +1 -0
  48. package/dist/recipes/choropleth-regions.d.ts +49 -0
  49. package/dist/recipes/choropleth-regions.js +521 -0
  50. package/dist/recipes/choropleth-regions.js.map +1 -0
  51. package/dist/recipes/choropleth.d.ts +27 -0
  52. package/dist/recipes/choropleth.js +86 -0
  53. package/dist/recipes/choropleth.js.map +1 -0
  54. package/dist/recipes/donut.d.ts +25 -0
  55. package/dist/recipes/donut.js +51 -0
  56. package/dist/recipes/donut.js.map +1 -0
  57. package/dist/recipes/graph.d.ts +55 -0
  58. package/dist/recipes/graph.js +132 -0
  59. package/dist/recipes/graph.js.map +1 -0
  60. package/dist/recipes/heatmap.d.ts +21 -0
  61. package/dist/recipes/heatmap.js +79 -0
  62. package/dist/recipes/heatmap.js.map +1 -0
  63. package/dist/recipes/index.d.ts +5 -0
  64. package/dist/recipes/index.js +35 -0
  65. package/dist/recipes/index.js.map +1 -0
  66. package/dist/recipes/line.d.ts +69 -0
  67. package/dist/recipes/line.js +64 -0
  68. package/dist/recipes/line.js.map +1 -0
  69. package/dist/recipes/nested-donut.d.ts +22 -0
  70. package/dist/recipes/nested-donut.js +47 -0
  71. package/dist/recipes/nested-donut.js.map +1 -0
  72. package/dist/recipes/radial-bar.d.ts +25 -0
  73. package/dist/recipes/radial-bar.js +53 -0
  74. package/dist/recipes/radial-bar.js.map +1 -0
  75. package/dist/recipes/sankey.d.ts +41 -0
  76. package/dist/recipes/sankey.js +61 -0
  77. package/dist/recipes/sankey.js.map +1 -0
  78. package/dist/recipes/scatter.d.ts +68 -0
  79. package/dist/recipes/scatter.js +75 -0
  80. package/dist/recipes/scatter.js.map +1 -0
  81. package/dist/recipes/shared.d.ts +144 -0
  82. package/dist/recipes/shared.js +212 -0
  83. package/dist/recipes/shared.js.map +1 -0
  84. package/dist/recipes/timeline.d.ts +31 -0
  85. package/dist/recipes/timeline.js +123 -0
  86. package/dist/recipes/timeline.js.map +1 -0
  87. package/dist/recipes/treemap.d.ts +19 -0
  88. package/dist/recipes/treemap.js +43 -0
  89. package/dist/recipes/treemap.js.map +1 -0
  90. package/dist/recipes/types.d.ts +16 -0
  91. package/dist/recipes/types.js +2 -0
  92. package/dist/recipes/types.js.map +1 -0
  93. package/dist/render/headless.d.ts +62 -0
  94. package/dist/render/headless.js +158 -0
  95. package/dist/render/headless.js.map +1 -0
  96. package/dist/render/materialize.d.ts +35 -0
  97. package/dist/render/materialize.js +160 -0
  98. package/dist/render/materialize.js.map +1 -0
  99. package/dist/render/mutex.d.ts +9 -0
  100. package/dist/render/mutex.js +14 -0
  101. package/dist/render/mutex.js.map +1 -0
  102. package/dist/render/rasterize.d.ts +10 -0
  103. package/dist/render/rasterize.js +29 -0
  104. package/dist/render/rasterize.js.map +1 -0
  105. package/dist/render/renderer.d.ts +21 -0
  106. package/dist/render/renderer.js +66 -0
  107. package/dist/render/renderer.js.map +1 -0
  108. package/dist/render/spec.d.ts +95 -0
  109. package/dist/render/spec.js +15 -0
  110. package/dist/render/spec.js.map +1 -0
  111. package/dist/server.d.ts +4 -0
  112. package/dist/server.js +44 -0
  113. package/dist/server.js.map +1 -0
  114. package/dist/svg/collect-css.d.ts +14 -0
  115. package/dist/svg/collect-css.js +53 -0
  116. package/dist/svg/collect-css.js.map +1 -0
  117. package/dist/svg/css-vars.d.ts +17 -0
  118. package/dist/svg/css-vars.js +64 -0
  119. package/dist/svg/css-vars.js.map +1 -0
  120. package/dist/svg/header.d.ts +8 -0
  121. package/dist/svg/header.js +81 -0
  122. package/dist/svg/header.js.map +1 -0
  123. package/dist/svg/ids.d.ts +12 -0
  124. package/dist/svg/ids.js +94 -0
  125. package/dist/svg/ids.js.map +1 -0
  126. package/dist/svg/postprocess.d.ts +41 -0
  127. package/dist/svg/postprocess.js +135 -0
  128. package/dist/svg/postprocess.js.map +1 -0
  129. package/dist/tools/register.d.ts +12 -0
  130. package/dist/tools/register.js +127 -0
  131. package/dist/tools/register.js.map +1 -0
  132. package/dist/widget/bundle.js +1777 -0
  133. package/dist/widget/bundle.meta.json +3 -0
  134. package/dist/widget/entry.d.ts +34 -0
  135. package/dist/widget/entry.js +118 -0
  136. package/dist/widget/entry.js.map +1 -0
  137. package/dist/widget/interactions.d.ts +14 -0
  138. package/dist/widget/interactions.js +151 -0
  139. package/dist/widget/interactions.js.map +1 -0
  140. package/dist/widget/unovis-slim.d.ts +33 -0
  141. package/dist/widget/unovis-slim.js +34 -0
  142. package/dist/widget/unovis-slim.js.map +1 -0
  143. package/docs/README.md +56 -0
  144. package/docs/architecture.md +158 -0
  145. package/docs/chart-spec.md +148 -0
  146. package/docs/getting-started.md +175 -0
  147. package/docs/interactive.md +125 -0
  148. package/docs/output-types.md +170 -0
  149. package/docs/programmatic.md +234 -0
  150. package/docs/tools.md +273 -0
  151. package/docs/troubleshooting.md +140 -0
  152. package/fonts/README.md +19 -0
  153. package/package.json +73 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computed-style.js","sourceRoot":"","sources":["../../src/env/computed-style.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Resolve a directory containing font files for text measurement, or
2
+ * undefined when none is available (system-font fallback). */
3
+ export declare function ensureFontsDir(): Promise<string | undefined>;
@@ -0,0 +1,103 @@
1
+ /** Inter font provisioning.
2
+ *
3
+ * Unovis defaults to the Inter font stack, and text measurement drives label
4
+ * trimming, wrapping and axis margins — measuring with the same font the
5
+ * viewer renders keeps geometry faithful. Fonts are resolved in order:
6
+ *
7
+ * 1. `UNOVIS_MCP_FONTS_DIR` (explicit directory of font files)
8
+ * 2. the package's own `fonts/` directory (manually added / bundled)
9
+ * 3. a user-level cache, populated once by downloading the official Inter
10
+ * release (pinned version + SHA-256 verified) and extracting four static
11
+ * TTF faces + the OFL license
12
+ *
13
+ * The download is best-effort: offline environments (or
14
+ * `UNOVIS_MCP_NO_DOWNLOAD=1`) fall back to system fonts with a one-line
15
+ * stderr note — rendering never fails because of fonts.
16
+ */
17
+ import { createHash } from 'node:crypto';
18
+ import { mkdirSync, readdirSync, writeFileSync, renameSync, rmSync } from 'node:fs';
19
+ import { tmpdir, homedir } from 'node:os';
20
+ import { join } from 'node:path';
21
+ import { fileURLToPath } from 'node:url';
22
+ import { unzipSync } from 'fflate';
23
+ const INTER_VERSION = '4.1';
24
+ const INTER_URL = `https://github.com/rsms/inter/releases/download/v${INTER_VERSION}/Inter-${INTER_VERSION}.zip`;
25
+ const INTER_SHA256 = '9883fdd4a49d4fb66bd8177ba6625ef9a64aa45899767dde3d36aa425756b11e';
26
+ const DOWNLOAD_TIMEOUT_MS = 60_000;
27
+ /** Faces used by chart text: Regular (labels), Medium (ticks, weight 500),
28
+ * SemiBold (titles), Bold */
29
+ const FACES = ['Inter-Regular.ttf', 'Inter-Medium.ttf', 'Inter-SemiBold.ttf', 'Inter-Bold.ttf'];
30
+ const LICENSE_ENTRY = 'LICENSE.txt';
31
+ const hasFontFiles = (dir) => {
32
+ try {
33
+ return readdirSync(dir).some(f => /\.(ttf|otf|woff2?)$/i.test(f));
34
+ }
35
+ catch {
36
+ return false;
37
+ }
38
+ };
39
+ function cacheDir() {
40
+ const base = process.env.XDG_CACHE_HOME || join(homedir(), '.cache');
41
+ return join(base, 'unovis-mcp', 'fonts', `inter-${INTER_VERSION}`);
42
+ }
43
+ async function downloadInter(targetDir) {
44
+ const response = await fetch(INTER_URL, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS), redirect: 'follow' });
45
+ if (!response.ok)
46
+ throw new Error(`HTTP ${response.status} for ${INTER_URL}`);
47
+ const zip = new Uint8Array(await response.arrayBuffer());
48
+ const digest = createHash('sha256').update(zip).digest('hex');
49
+ if (digest !== INTER_SHA256)
50
+ throw new Error(`checksum mismatch for ${INTER_URL}: ${digest}`);
51
+ const wanted = new Set([...FACES.map(f => `extras/ttf/${f}`), LICENSE_ENTRY]);
52
+ const entries = unzipSync(zip, { filter: file => wanted.has(file.name) });
53
+ const missing = [...wanted].filter(name => !entries[name]);
54
+ if (missing.length)
55
+ throw new Error(`entries missing from Inter archive: ${missing.join(', ')}`);
56
+ // Extract to a temp dir and move into place so a killed process can't
57
+ // leave a half-populated cache behind
58
+ const staging = join(tmpdir(), `unovis-mcp-fonts-${process.pid}`);
59
+ rmSync(staging, { recursive: true, force: true });
60
+ mkdirSync(staging, { recursive: true });
61
+ for (const [name, data] of Object.entries(entries)) {
62
+ writeFileSync(join(staging, name.split('/').pop()), data);
63
+ }
64
+ mkdirSync(join(targetDir, '..'), { recursive: true });
65
+ rmSync(targetDir, { recursive: true, force: true });
66
+ renameSync(staging, targetDir);
67
+ return true;
68
+ }
69
+ let ensurePromise;
70
+ /** Resolve a directory containing font files for text measurement, or
71
+ * undefined when none is available (system-font fallback). */
72
+ export function ensureFontsDir() {
73
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
74
+ if (!ensurePromise)
75
+ ensurePromise = resolveFontsDir();
76
+ return ensurePromise;
77
+ }
78
+ async function resolveFontsDir() {
79
+ const explicit = process.env.UNOVIS_MCP_FONTS_DIR;
80
+ if (explicit) {
81
+ if (hasFontFiles(explicit))
82
+ return explicit;
83
+ console.error(`unovis-mcp: UNOVIS_MCP_FONTS_DIR has no font files: ${explicit}`);
84
+ }
85
+ const packageFonts = fileURLToPath(new URL('../../fonts', import.meta.url));
86
+ if (hasFontFiles(packageFonts))
87
+ return packageFonts;
88
+ const cache = cacheDir();
89
+ if (hasFontFiles(cache))
90
+ return cache;
91
+ if (process.env.UNOVIS_MCP_NO_DOWNLOAD)
92
+ return undefined;
93
+ try {
94
+ await downloadInter(cache);
95
+ console.error(`unovis-mcp: downloaded Inter ${INTER_VERSION} (SIL OFL 1.1) to ${cache}`);
96
+ return cache;
97
+ }
98
+ catch (e) {
99
+ console.error(`unovis-mcp: Inter download skipped (${e instanceof Error ? e.message : e}) — using system fonts for text measurement`);
100
+ return undefined;
101
+ }
102
+ }
103
+ //# sourceMappingURL=fonts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fonts.js","sourceRoot":"","sources":["../../src/env/fonts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { DOMWindow } from 'jsdom';
2
+ import { RafQueue } from './raf-queue.js';
3
+ import type { VarMaps } from './computed-style.js';
4
+ export { defineElementSize } from './size.js';
5
+ export type UnovisLib = typeof import('@unovis/ts');
6
+ export interface RenderEnv {
7
+ window: DOMWindow;
8
+ document: Document;
9
+ lib: UnovisLib;
10
+ raf: RafQueue;
11
+ varMaps: VarMaps;
12
+ }
13
+ export declare function getRenderEnv(): Promise<RenderEnv>;
@@ -0,0 +1,121 @@
1
+ /** Headless rendering environment for @unovis/ts.
2
+ *
3
+ * Creates a single shared jsdom window, installs every browser API the
4
+ * library needs (in the right order — some are captured at module load),
5
+ * and only then dynamically imports '@unovis/ts'. Import order matters:
6
+ *
7
+ * - emotion inserts real <style> tags only if `document` exists at import
8
+ * - utils/text-measure snapshots a canvas 2D context at module scope
9
+ * - d3-timer binds `window.requestAnimationFrame` at module load
10
+ */
11
+ import { JSDOM } from 'jsdom';
12
+ import { RafQueue } from './raf-queue.js';
13
+ import { installCanvasHook, registerFontsFromDir } from './canvas.js';
14
+ import { ensureFontsDir } from './fonts.js';
15
+ import { installBBoxPolyfills } from './bbox.js';
16
+ import { installComputedStyle, setVarMaps, setFontRules } from './computed-style.js';
17
+ import { collectCssRules } from '../svg/collect-css.js';
18
+ export { defineElementSize } from './size.js';
19
+ /* eslint-disable @typescript-eslint/no-empty-function */
20
+ class NoopResizeObserver {
21
+ observe() { }
22
+ unobserve() { }
23
+ disconnect() { }
24
+ }
25
+ /* eslint-enable @typescript-eslint/no-empty-function */
26
+ function exposeGlobals(window, raf) {
27
+ const globalNames = [
28
+ 'document', 'location', 'navigator',
29
+ 'Element', 'HTMLElement', 'SVGElement', 'SVGGraphicsElement', 'HTMLCanvasElement',
30
+ 'Node', 'Text', 'DOMParser', 'XMLSerializer', 'MutationObserver',
31
+ 'CSS', 'DOMPoint', 'DOMRect', 'getComputedStyle',
32
+ ];
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ const g = globalThis;
35
+ g.window = window;
36
+ for (const name of globalNames) {
37
+ if (!(name in window))
38
+ continue;
39
+ try {
40
+ Object.defineProperty(g, name, { configurable: true, get: () => window[name] });
41
+ }
42
+ catch { /* some globals (e.g. navigator on newer Node) may resist redefinition */ }
43
+ }
44
+ g.requestAnimationFrame = raf.request;
45
+ g.cancelAnimationFrame = raf.cancel;
46
+ g.ResizeObserver = NoopResizeObserver;
47
+ }
48
+ /** Parse all emotion-injected CSS custom properties into light/dark maps */
49
+ function buildVarMapsFromRules(rules) {
50
+ const light = new Map();
51
+ const dark = new Map();
52
+ const darkSelector = /dark-theme|theme-dark|\[data-theme="?dark"?\]/;
53
+ for (const rule of rules) {
54
+ const isDark = darkSelector.test(rule.selector);
55
+ // Only :root-scoped declarations are global defaults. Class-scoped
56
+ // custom-property overrides (e.g. styleLargeSize from styles/sizes.ts)
57
+ // must not leak into the global maps.
58
+ if (!isDark && !rule.selector.includes(':root'))
59
+ continue;
60
+ for (const match of rule.block.matchAll(/(--[\w-]+)\s*:\s*([^;}]+)/g)) {
61
+ const [, name, value] = match;
62
+ (isDark ? dark : light).set(name, value.trim());
63
+ }
64
+ }
65
+ // The dark palette remap (--vis-colorN → --vis-dark-colorN) is declared
66
+ // under selectors jsdom can't apply; reproduce it here.
67
+ for (const [name, value] of light) {
68
+ const darkEquivalent = name.replace(/^--vis-color(\d+)$/, '--vis-dark-color$1');
69
+ if (darkEquivalent !== name && light.has(darkEquivalent)) {
70
+ if (!dark.has(name))
71
+ dark.set(name, light.get(darkEquivalent));
72
+ }
73
+ if (/^--vis-dark-/.test(name)) {
74
+ const lightName = name.replace('--vis-dark-', '--vis-');
75
+ if (!dark.has(lightName))
76
+ dark.set(lightName, value);
77
+ }
78
+ }
79
+ return { light, dark };
80
+ }
81
+ let envPromise;
82
+ export function getRenderEnv() {
83
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
84
+ if (!envPromise)
85
+ envPromise = createEnv();
86
+ return envPromise;
87
+ }
88
+ async function createEnv() {
89
+ // Provision measurement fonts before anything can measure text
90
+ // (best-effort: falls back to system fonts offline)
91
+ const fontsDir = await ensureFontsDir();
92
+ if (fontsDir)
93
+ registerFontsFromDir(fontsDir);
94
+ const dom = new JSDOM('<!doctype html><html><body></body></html>', {
95
+ url: 'http://localhost/',
96
+ pretendToBeVisual: false,
97
+ });
98
+ const window = dom.window;
99
+ const raf = new RafQueue();
100
+ // Install shims before the library import — several APIs are captured
101
+ // at module scope inside @unovis/ts and its dependencies.
102
+ window.requestAnimationFrame = raf.request;
103
+ window.cancelAnimationFrame = raf.cancel;
104
+ window.ResizeObserver = NoopResizeObserver;
105
+ installCanvasHook(window);
106
+ installBBoxPolyfills(window);
107
+ installComputedStyle(window);
108
+ exposeGlobals(window, raf);
109
+ const lib = await import('@unovis/ts');
110
+ const cssRules = collectCssRules(window.document);
111
+ const varMaps = buildVarMapsFromRules(cssRules);
112
+ // Unovis estimates text width as chars × fontSize × ratio (default 0.5) when
113
+ // reserving label space, but trims against real canvas metrics — Inter runs
114
+ // wider (~0.55), so marginal labels would get clipped. A slightly generous
115
+ // ratio makes reservations always cover measured text.
116
+ varMaps.light.set('--vis-font-wh-ratio', '0.58');
117
+ setVarMaps(varMaps);
118
+ setFontRules(cssRules);
119
+ return { window, document: window.document, lib, raf, varMaps };
120
+ }
121
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/env/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /** Flushable requestAnimationFrame queue.
2
+ *
3
+ * Unovis defers rendering to the next animation frame (`ContainerCore.render`),
4
+ * and several components schedule follow-up frames (axis, scatter, heatmap,
5
+ * sankey, annotations, text-overlap). Instead of waiting on real timers we
6
+ * queue callbacks and drain the queue synchronously until no new frames are
7
+ * scheduled.
8
+ */
9
+ type FrameCallback = (time: number) => void;
10
+ export declare class RafQueue {
11
+ private queue;
12
+ private nextId;
13
+ /** Errors thrown by frame callbacks (collected so one bad frame can't kill a render) */
14
+ errors: unknown[];
15
+ request: (cb: FrameCallback) => number;
16
+ cancel: (id: number) => void;
17
+ get size(): number;
18
+ /** Drain the queue, letting callbacks schedule follow-up frames, until it
19
+ * stays empty or the iteration cap is reached. Returns rounds executed. */
20
+ flushAll(cap?: number): number;
21
+ clear(): void;
22
+ }
23
+ export {};
@@ -0,0 +1,51 @@
1
+ /** Flushable requestAnimationFrame queue.
2
+ *
3
+ * Unovis defers rendering to the next animation frame (`ContainerCore.render`),
4
+ * and several components schedule follow-up frames (axis, scatter, heatmap,
5
+ * sankey, annotations, text-overlap). Instead of waiting on real timers we
6
+ * queue callbacks and drain the queue synchronously until no new frames are
7
+ * scheduled.
8
+ */
9
+ export class RafQueue {
10
+ queue = [];
11
+ nextId = 1;
12
+ /** Errors thrown by frame callbacks (collected so one bad frame can't kill a render) */
13
+ errors = [];
14
+ request = (cb) => {
15
+ const id = this.nextId++;
16
+ this.queue.push({ id, cb });
17
+ return id;
18
+ };
19
+ cancel = (id) => {
20
+ const index = this.queue.findIndex(entry => entry.id === id);
21
+ if (index >= 0)
22
+ this.queue.splice(index, 1);
23
+ };
24
+ get size() {
25
+ return this.queue.length;
26
+ }
27
+ /** Drain the queue, letting callbacks schedule follow-up frames, until it
28
+ * stays empty or the iteration cap is reached. Returns rounds executed. */
29
+ flushAll(cap = 32) {
30
+ let rounds = 0;
31
+ while (this.queue.length && rounds < cap) {
32
+ rounds += 1;
33
+ const batch = this.queue.splice(0, this.queue.length);
34
+ const time = performance.now();
35
+ for (const { cb } of batch) {
36
+ try {
37
+ cb(time);
38
+ }
39
+ catch (e) {
40
+ this.errors.push(e);
41
+ }
42
+ }
43
+ }
44
+ return rounds;
45
+ }
46
+ clear() {
47
+ this.queue.length = 0;
48
+ this.errors.length = 0;
49
+ }
50
+ }
51
+ //# sourceMappingURL=raf-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raf-queue.js","sourceRoot":"","sources":["../../src/env/raf-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,OAAO,QAAQ;IACX,KAAK,GAAwC,EAAE,CAAA;IAC/C,MAAM,GAAG,CAAC,CAAA;IAClB,wFAAwF;IACjF,MAAM,GAAc,EAAE,CAAA;IAE7B,OAAO,GAAG,CAAC,EAAiB,EAAU,EAAE;QACtC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAA;QACxB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QAC3B,OAAO,EAAE,CAAA;IACX,CAAC,CAAA;IAED,MAAM,GAAG,CAAC,EAAU,EAAQ,EAAE;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;QAC5D,IAAI,KAAK,IAAI,CAAC;YAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IAC7C,CAAC,CAAA;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAA;IAC1B,CAAC;IAED;+EAC2E;IAC3E,QAAQ,CAAE,GAAG,GAAG,EAAE;QAChB,IAAI,MAAM,GAAG,CAAC,CAAA;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;YACzC,MAAM,IAAI,CAAC,CAAA;YACX,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YACrD,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;YAC9B,KAAK,MAAM,EAAE,EAAE,EAAE,IAAI,KAAK,EAAE,CAAC;gBAC3B,IAAI,CAAC;oBACH,EAAE,CAAC,IAAI,CAAC,CAAA;gBACV,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;QACrB,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAA;IACxB,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ /** Element size shims.
2
+ *
3
+ * jsdom performs no layout: `clientWidth`/`clientHeight` are always 0 and
4
+ * `getBoundingClientRect()` returns a zero rect. Unovis containers read both
5
+ * to size charts (`ContainerCore.containerWidth/Height` — including
6
+ * `this.element.clientWidth` on the SVG element when explicit width/height
7
+ * are set in the config), so we define real values per element.
8
+ */
9
+ export declare function defineElementSize(element: Element, width: number, height: number): void;
@@ -0,0 +1,30 @@
1
+ /** Element size shims.
2
+ *
3
+ * jsdom performs no layout: `clientWidth`/`clientHeight` are always 0 and
4
+ * `getBoundingClientRect()` returns a zero rect. Unovis containers read both
5
+ * to size charts (`ContainerCore.containerWidth/Height` — including
6
+ * `this.element.clientWidth` on the SVG element when explicit width/height
7
+ * are set in the config), so we define real values per element.
8
+ */
9
+ export function defineElementSize(element, width, height) {
10
+ Object.defineProperties(element, {
11
+ clientWidth: { configurable: true, get: () => width },
12
+ clientHeight: { configurable: true, get: () => height },
13
+ });
14
+ const rect = {
15
+ x: 0,
16
+ y: 0,
17
+ top: 0,
18
+ left: 0,
19
+ right: width,
20
+ bottom: height,
21
+ width,
22
+ height,
23
+ toJSON: () => ({ width, height }),
24
+ };
25
+ Object.defineProperty(element, 'getBoundingClientRect', {
26
+ configurable: true,
27
+ value: () => rect,
28
+ });
29
+ }
30
+ //# sourceMappingURL=size.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"size.js","sourceRoot":"","sources":["../../src/env/size.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,UAAU,iBAAiB,CAAE,OAAgB,EAAE,KAAa,EAAE,MAAc;IAChF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE;QAC/B,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE;QACrD,YAAY,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE;KACxD,CAAC,CAAA;IAEF,MAAM,IAAI,GAAG;QACX,CAAC,EAAE,CAAC;QACJ,CAAC,EAAE,CAAC;QACJ,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,CAAC;QACP,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,MAAM;QACd,KAAK;QACL,MAAM;QACN,MAAM,EAAE,GAAY,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;KAC3C,CAAA;IACD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,uBAAuB,EAAE;QACtD,YAAY,EAAE,IAAI;QAClB,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI;KAClB,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { ChartSpec } from '../render/spec.js';
2
+ /** The compiled widget bundle (built by scripts/build-widget.mjs) */
3
+ export declare function widgetBundle(): string;
4
+ export interface ChartDocumentOptions {
5
+ /** Document <title>; defaults to the spec title */
6
+ documentTitle?: string;
7
+ /** Animation duration in ms. 0 renders immediately (deterministic tests,
8
+ * and useful when the chart is screenshotted right after load) */
9
+ duration?: number;
10
+ }
11
+ /** A standalone page that renders `spec` on load */
12
+ export declare function buildChartDocument(spec: ChartSpec, options?: ChartDocumentOptions): string;
13
+ /** A page that renders whatever spec it is sent over postMessage.
14
+ * Protocol: iframe posts `unovis:ready`, host posts `unovis:render` with a
15
+ * spec, iframe posts `unovis:size` after each render. */
16
+ export declare function buildEmbedDocument(): string;
@@ -0,0 +1,95 @@
1
+ /** Self-contained interactive chart documents.
2
+ *
3
+ * Emits one HTML file with the spec, the widget bundle and all styles inlined
4
+ * — no network, no build step, opens anywhere. Two shapes:
5
+ *
6
+ * - `buildChartDocument(spec)`: renders the spec on load (file deliverable)
7
+ * - `buildEmbedDocument()`: waits for a spec over postMessage (iframe/widget
8
+ * host, used for the ui:// resource and third-party embedding)
9
+ */
10
+ import { readFileSync } from 'node:fs';
11
+ import { fileURLToPath } from 'node:url';
12
+ let cachedBundle;
13
+ /** The compiled widget bundle (built by scripts/build-widget.mjs) */
14
+ export function widgetBundle() {
15
+ if (cachedBundle)
16
+ return cachedBundle;
17
+ // Resolve relative to this module so it works from dist/ and from src/
18
+ const candidates = [
19
+ new URL('../widget/bundle.js', import.meta.url),
20
+ new URL('../../dist/widget/bundle.js', import.meta.url),
21
+ ];
22
+ for (const candidate of candidates) {
23
+ try {
24
+ cachedBundle = readFileSync(fileURLToPath(candidate), 'utf8');
25
+ return cachedBundle;
26
+ }
27
+ catch { /* try the next candidate */ }
28
+ }
29
+ throw new Error('Widget bundle not found — run `pnpm build:widget`');
30
+ }
31
+ /** `</script` inside embedded JSON would close the host script element */
32
+ const escapeForScript = (json) => json.replace(/</g, '\\u003c');
33
+ const FONT_STACK = 'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif';
34
+ function styles(spec) {
35
+ const aspect = spec ? `${spec.width} / ${spec.height}` : '16 / 9';
36
+ return `
37
+ :root { --uv-bg: #ffffff; --uv-fg: #1f2937; --uv-muted: #6b7280; --uv-border: #e5e7eb; }
38
+ :root[data-theme="dark"] { --uv-bg: #292b34; --uv-fg: #f2f4f9; --uv-muted: #aab2c0; --uv-border: #3a3d47; }
39
+ html, body { margin: 0; padding: 0; background: var(--uv-bg); color: var(--uv-fg); font-family: ${FONT_STACK}; }
40
+ body { padding: 16px; box-sizing: border-box; }
41
+ .uv-root { display: flex; flex-direction: column; gap: 8px; max-width: 100%; }
42
+ .uv-title { font-size: 16px; font-weight: 600; }
43
+ .uv-legend { display: flex; flex-wrap: wrap; }
44
+ .uv-chart { width: 100%; aspect-ratio: ${aspect}; min-height: 240px; }
45
+ .uv-error { padding: 16px; border: 1px solid #e35a68; border-radius: 8px; color: #e35a68; font-family: ui-monospace, monospace; font-size: 13px; }
46
+ /* Tooltip / crosshair content (Unovis provides the container chrome) */
47
+ .uv-tt-title { font-weight: 600; margin-bottom: 4px; }
48
+ .uv-tt-row { display: flex; gap: 12px; justify-content: space-between; font-size: 12px; line-height: 1.6; }
49
+ .uv-tt-key { color: var(--uv-muted); }
50
+ .uv-tt-val { font-variant-numeric: tabular-nums; font-weight: 500; }
51
+ @media (max-width: 560px) { .uv-chart { aspect-ratio: 4 / 3; } }`;
52
+ }
53
+ /** A standalone page that renders `spec` on load */
54
+ export function buildChartDocument(spec, options = {}) {
55
+ const title = options.documentTitle ?? spec.title ?? 'Unovis chart';
56
+ return `<!doctype html>
57
+ <html lang="en"${spec.theme === 'dark' ? ' data-theme="dark"' : ''}>
58
+ <head>
59
+ <meta charset="utf-8">
60
+ <meta name="viewport" content="width=device-width, initial-scale=1">
61
+ <title>${title.replace(/</g, '&lt;')}</title>
62
+ <style>${styles(spec)}</style>
63
+ </head>
64
+ <body>
65
+ <div id="uv-root"></div>
66
+ <script type="application/json" id="uv-spec">${escapeForScript(JSON.stringify(spec))}</script>
67
+ <script type="application/json" id="uv-options">${escapeForScript(JSON.stringify({ duration: options.duration ?? 400 }))}</script>
68
+ <script>${widgetBundle()}</script>
69
+ </body>
70
+ </html>
71
+ `;
72
+ }
73
+ /** A page that renders whatever spec it is sent over postMessage.
74
+ * Protocol: iframe posts `unovis:ready`, host posts `unovis:render` with a
75
+ * spec, iframe posts `unovis:size` after each render. */
76
+ export function buildEmbedDocument() {
77
+ return `<!doctype html>
78
+ <html lang="en">
79
+ <head>
80
+ <meta charset="utf-8">
81
+ <meta name="viewport" content="width=device-width, initial-scale=1">
82
+ <title>Unovis chart</title>
83
+ <style>${styles()}
84
+ body { padding: 8px; }
85
+ </style>
86
+ </head>
87
+ <body>
88
+ <div id="uv-embed-root"></div>
89
+ <script>${widgetBundle()}</script>
90
+ <script>window.UnovisChart.startEmbed()</script>
91
+ </body>
92
+ </html>
93
+ `;
94
+ }
95
+ //# sourceMappingURL=document.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document.js","sourceRoot":"","sources":["../../src/html/document.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAIxC,IAAI,YAAgC,CAAA;AAEpC,qEAAqE;AACrE,MAAM,UAAU,YAAY;IAC1B,IAAI,YAAY;QAAE,OAAO,YAAY,CAAA;IACrC,uEAAuE;IACvE,MAAM,UAAU,GAAG;QACjB,IAAI,GAAG,CAAC,qBAAqB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QAC/C,IAAI,GAAG,CAAC,6BAA6B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;KACxD,CAAA;IACD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,YAAY,GAAG,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAA;YAC7D,OAAO,YAAY,CAAA;QACrB,CAAC;QAAC,MAAM,CAAC,CAAC,4BAA4B,CAAC,CAAC;IAC1C,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;AACtE,CAAC;AAED,0EAA0E;AAC1E,MAAM,eAAe,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;AAE/E,MAAM,UAAU,GAAG,6EAA6E,CAAA;AAEhG,SAAS,MAAM,CAAE,IAAgB;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAA;IACjE,OAAO;;;oGAG2F,UAAU;;;;;2CAKnE,MAAM;;;;;;;mEAOkB,CAAA;AACnE,CAAC;AAUD,oDAAoD;AACpD,MAAM,UAAU,kBAAkB,CAAE,IAAe,EAAE,UAAgC,EAAE;IACrF,MAAM,KAAK,GAAG,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,KAAK,IAAI,cAAc,CAAA;IACnE,OAAO;iBACQ,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE;;;;SAIzD,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SAC3B,MAAM,CAAC,IAAI,CAAC;;;;+CAI0B,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;kDAClC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,GAAG,EAAE,CAAC,CAAC;UAC9G,YAAY,EAAE;;;CAGvB,CAAA;AACD,CAAC;AAED;;yDAEyD;AACzD,MAAM,UAAU,kBAAkB;IAChC,OAAO;;;;;;SAMA,MAAM,EAAE;;;;;;UAMP,YAAY,EAAE;;;;CAIvB,CAAA;AACD,CAAC"}
@@ -0,0 +1,25 @@
1
+ /** @unovis/mcp — programmatic API.
2
+ *
3
+ * The package is primarily a CLI (`unovis-mcp`), but the renderer and server
4
+ * builder are exported for embedding:
5
+ *
6
+ * import { renderChart, buildServer, recipes } from '@unovis/mcp'
7
+ */
8
+ export { renderChart, ChartInputError } from './render/renderer.js';
9
+ export type { RenderOptions } from './render/renderer.js';
10
+ export { renderToSvg } from './render/headless.js';
11
+ export type { HeadlessRenderOptions, BuildContext, RenderedChart, RenderResult } from './render/headless.js';
12
+ export { buildChartDocument, buildEmbedDocument } from './html/document.js';
13
+ export type { ChartDocumentOptions } from './html/document.js';
14
+ export { svgToPng, themeBackground } from './render/rasterize.js';
15
+ export type { RasterizeOptions } from './render/rasterize.js';
16
+ export type { ChartSpec, ComponentSpec, AxisSpec, AccessorRef, LegendItemSpec } from './render/spec.js';
17
+ export { recipes, recipeByName } from './recipes/index.js';
18
+ export type { Recipe, AnyRecipe } from './recipes/index.js';
19
+ export { buildServer } from './server.js';
20
+ export { registerTools, activeRecipes } from './tools/register.js';
21
+ export type { ToolFilterOptions } from './tools/register.js';
22
+ export { getRenderEnv } from './env/index.js';
23
+ export type { RenderEnv, UnovisLib } from './env/index.js';
24
+ export { generateCode, formatGeneratedFiles, FRAMEWORKS } from './codegen/index.js';
25
+ export type { Framework, GeneratedFile } from './codegen/index.js';
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ /** @unovis/mcp — programmatic API.
2
+ *
3
+ * The package is primarily a CLI (`unovis-mcp`), but the renderer and server
4
+ * builder are exported for embedding:
5
+ *
6
+ * import { renderChart, buildServer, recipes } from '@unovis/mcp'
7
+ */
8
+ export { renderChart, ChartInputError } from './render/renderer.js';
9
+ // The headless primitive: render any Unovis chart to standalone SVG in Node
10
+ export { renderToSvg } from './render/headless.js';
11
+ export { buildChartDocument, buildEmbedDocument } from './html/document.js';
12
+ export { svgToPng, themeBackground } from './render/rasterize.js';
13
+ export { recipes, recipeByName } from './recipes/index.js';
14
+ export { buildServer } from './server.js';
15
+ export { registerTools, activeRecipes } from './tools/register.js';
16
+ export { getRenderEnv } from './env/index.js';
17
+ export { generateCode, formatGeneratedFiles, FRAMEWORKS } from './codegen/index.js';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAEnE,4EAA4E;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAElD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAE3E,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAGjE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAE1D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAElE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAE7C,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,66 @@
1
+ import { z } from 'zod';
2
+ import type { Recipe } from './types.js';
3
+ export declare const areaInputShape: {
4
+ width: z.ZodDefault<z.ZodNumber>;
5
+ height: z.ZodDefault<z.ZodNumber>;
6
+ theme: z.ZodDefault<z.ZodEnum<["light", "dark"]>>;
7
+ title: z.ZodOptional<z.ZodString>;
8
+ colors: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
9
+ framework: z.ZodDefault<z.ZodEnum<["ts", "react", "svelte", "vue", "angular", "solid"]>>;
10
+ outputType: z.ZodDefault<z.ZodEnum<["svg", "png", "html", "interactive", "config", "code"]>>;
11
+ outputPath: z.ZodOptional<z.ZodString>;
12
+ scale: z.ZodDefault<z.ZodNumber>;
13
+ xAxisLabel: z.ZodOptional<z.ZodString>;
14
+ yAxisLabel: z.ZodOptional<z.ZodString>;
15
+ showGridLines: z.ZodDefault<z.ZodBoolean>;
16
+ legend: z.ZodDefault<z.ZodBoolean>;
17
+ referenceLines: z.ZodOptional<z.ZodArray<z.ZodObject<{
18
+ axis: z.ZodDefault<z.ZodEnum<["x", "y"]>>;
19
+ value: z.ZodNumber;
20
+ label: z.ZodOptional<z.ZodString>;
21
+ color: z.ZodOptional<z.ZodString>;
22
+ lineWidth: z.ZodDefault<z.ZodNumber>;
23
+ style: z.ZodDefault<z.ZodEnum<["dashed", "solid", "dotted"]>>;
24
+ }, "strip", z.ZodTypeAny, {
25
+ value: number;
26
+ style: "solid" | "dashed" | "dotted";
27
+ axis: "x" | "y";
28
+ lineWidth: number;
29
+ label?: string | undefined;
30
+ color?: string | undefined;
31
+ }, {
32
+ value: number;
33
+ label?: string | undefined;
34
+ color?: string | undefined;
35
+ style?: "solid" | "dashed" | "dotted" | undefined;
36
+ axis?: "x" | "y" | undefined;
37
+ lineWidth?: number | undefined;
38
+ }>, "many">>;
39
+ referenceBands: z.ZodOptional<z.ZodArray<z.ZodObject<{
40
+ axis: z.ZodDefault<z.ZodEnum<["x", "y"]>>;
41
+ from: z.ZodNumber;
42
+ to: z.ZodNumber;
43
+ label: z.ZodOptional<z.ZodString>;
44
+ color: z.ZodOptional<z.ZodString>;
45
+ }, "strip", z.ZodTypeAny, {
46
+ axis: "x" | "y";
47
+ from: number;
48
+ to: number;
49
+ label?: string | undefined;
50
+ color?: string | undefined;
51
+ }, {
52
+ from: number;
53
+ to: number;
54
+ label?: string | undefined;
55
+ color?: string | undefined;
56
+ axis?: "x" | "y" | undefined;
57
+ }>, "many">>;
58
+ data: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>, "many">;
59
+ x: z.ZodString;
60
+ y: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
61
+ stacked: z.ZodDefault<z.ZodBoolean>;
62
+ curve: z.ZodDefault<z.ZodEnum<["linear", "monotoneX", "basis", "natural", "step", "stepAfter", "stepBefore"]>>;
63
+ xIsTime: z.ZodDefault<z.ZodBoolean>;
64
+ seriesLabels: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
65
+ };
66
+ export declare const areaRecipe: Recipe<typeof areaInputShape>;