@opendata-ai/openchart-vanilla 8.4.0 → 8.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -0
- package/dist/chunk-2OJZBMXM.js +377 -0
- package/dist/chunk-2OJZBMXM.js.map +1 -0
- package/dist/{chunk-45XZOWYC.js → chunk-5KV3ZBBL.js} +58 -437
- package/dist/chunk-5KV3ZBBL.js.map +1 -0
- package/dist/{chunk-HGRNXLDF.js → chunk-5RX6ZQGZ.js} +10 -1
- package/dist/chunk-5RX6ZQGZ.js.map +1 -0
- package/dist/{chunk-UOB422LY.js → chunk-6B5OBGIO.js} +2 -2
- package/dist/chunk-NG7CVCI2.js +58 -0
- package/dist/chunk-NG7CVCI2.js.map +1 -0
- package/dist/{chunk-FETYAVTZ.js → chunk-RYVV3YIG.js} +3 -3
- package/dist/{chunk-LNPRDSK3.js → chunk-UAK6HWOC.js} +2 -2
- package/dist/chunk-WOLX5EZT.js +3577 -0
- package/dist/chunk-WOLX5EZT.js.map +1 -0
- package/dist/{chunk-YGYMB7KB.js → chunk-XGII4ZRT.js} +55 -30
- package/dist/chunk-XGII4ZRT.js.map +1 -0
- package/dist/export-gif.js +3 -3
- package/dist/graph-3d/index.d.ts +272 -0
- package/dist/graph-3d/index.js +1556 -0
- package/dist/graph-3d/index.js.map +1 -0
- package/dist/index.d.ts +4 -252
- package/dist/index.js +27 -3471
- package/dist/index.js.map +1 -1
- package/dist/renderer-registry-B5tW6yAZ.d.ts +376 -0
- package/dist/static.js +4 -3
- package/dist/static.js.map +1 -1
- package/dist/story/index.js +10 -7
- package/dist/story/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/package.json +26 -5
- package/dist/chunk-45XZOWYC.js.map +0 -1
- package/dist/chunk-HGRNXLDF.js.map +0 -1
- package/dist/chunk-YGYMB7KB.js.map +0 -1
- /package/dist/{chunk-UOB422LY.js.map → chunk-6B5OBGIO.js.map} +0 -0
- /package/dist/{chunk-FETYAVTZ.js.map → chunk-RYVV3YIG.js.map} +0 -0
- /package/dist/{chunk-LNPRDSK3.js.map → chunk-UAK6HWOC.js.map} +0 -0
|
@@ -9,6 +9,14 @@ function setAttrs(el, attrs) {
|
|
|
9
9
|
el.setAttribute(key, String(value));
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
+
function applyKnockoutHalo(el, color, fontSize) {
|
|
13
|
+
setAttrs(el, {
|
|
14
|
+
stroke: color,
|
|
15
|
+
"stroke-width": Math.round(fontSize * 0.3),
|
|
16
|
+
"stroke-linejoin": "round",
|
|
17
|
+
"paint-order": "stroke"
|
|
18
|
+
});
|
|
19
|
+
}
|
|
12
20
|
function applyTextStyle(el, style) {
|
|
13
21
|
const inline = el.style;
|
|
14
22
|
inline.setProperty("fill", style.fill);
|
|
@@ -111,8 +119,9 @@ export {
|
|
|
111
119
|
XLINK_NS,
|
|
112
120
|
createSVGElement,
|
|
113
121
|
setAttrs,
|
|
122
|
+
applyKnockoutHalo,
|
|
114
123
|
applyTextStyle,
|
|
115
124
|
buildThemeStyleBlock,
|
|
116
125
|
injectThemeStyleBlock
|
|
117
126
|
};
|
|
118
|
-
//# sourceMappingURL=chunk-
|
|
127
|
+
//# sourceMappingURL=chunk-5RX6ZQGZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/renderers/svg-dom.ts","../src/theme-style-block.ts"],"sourcesContent":["/**\n * Shared SVG DOM helpers used across the per-concern renderers.\n *\n * Pure, stateless utilities. No layout/theme knowledge.\n */\n\nimport type { TextStyle } from '@opendata-ai/openchart-core';\n\nexport const SVG_NS = 'http://www.w3.org/2000/svg';\nexport const XLINK_NS = 'http://www.w3.org/1999/xlink';\n\nexport function createSVGElement(tag: string): SVGElement {\n return document.createElementNS(SVG_NS, tag);\n}\n\nexport function setAttrs(el: SVGElement, attrs: Record<string, string | number>): void {\n for (const [key, value] of Object.entries(attrs)) {\n el.setAttribute(key, String(value));\n }\n}\n\n/**\n * Cut a knockout halo behind text so it stays legible where it crosses\n * gridlines, marks, or a neighbouring series: a surface-colored stroke painted\n * under the glyphs.\n *\n * Presentation attributes, not inline styles, so a stylesheet can still\n * override the halo. The width scales with the font size -- a fixed width rings\n * small glyphs and disappears behind large ones.\n */\nexport function applyKnockoutHalo(el: SVGElement, color: string, fontSize: number): void {\n setAttrs(el, {\n stroke: color,\n 'stroke-width': Math.round(fontSize * 0.3),\n 'stroke-linejoin': 'round',\n 'paint-order': 'stroke',\n });\n}\n\nexport function applyTextStyle(el: SVGElement, style: TextStyle): void {\n // Use inline styles so engine-computed values take priority over CSS class\n // defaults (e.g. .oc-title { font-size: var(--oc-title-size) } would otherwise\n // override the responsive scaling applied by the chrome layout).\n const inline = (el as SVGElement & ElementCSSInlineStyle).style;\n inline.setProperty('fill', style.fill);\n inline.setProperty('font-size', `${style.fontSize}px`);\n inline.setProperty('font-weight', String(style.fontWeight));\n inline.setProperty('font-family', style.fontFamily);\n if (style.textAnchor) {\n el.setAttribute('text-anchor', style.textAnchor);\n }\n if (style.dominantBaseline) {\n el.setAttribute('dominant-baseline', style.dominantBaseline);\n }\n if (style.fontVariant) {\n el.setAttribute('font-variant', style.fontVariant);\n }\n}\n","/**\n * Theme `<style>` block for self-contained SVG export.\n *\n * Charts render most fills as inline SVG attributes, but a handful of chrome\n * elements (metric cells, the brand watermark dot, legend text, endpoint labels)\n * take their fill from CSS classes in `chrome.css` via `--oc-*` variables. That\n * works on-screen because the live SVG inherits the page stylesheet — but a\n * serialized/rasterized export (PNG/JPG/GIF) is detached from the page, so those\n * class-based fills vanish. This module builds a `<style>` block that resolves\n * every such rule against a concrete `ResolvedTheme`, so injecting it into an\n * export clone makes the SVG fully self-contained.\n *\n * Both the headless renderer (`static.ts`) and the browser export path use this,\n * so class-based styling round-trips identically no matter which path produced\n * the SVG. Browser-safe (no Node imports) so the browser exporters can import it.\n */\n\nimport type { ResolvedTheme } from '@opendata-ai/openchart-core';\nimport { adaptForLightLineStroke, cssTokenDefault } from '@opendata-ai/openchart-core';\nimport { SVG_NS } from './renderers/svg-dom';\n\n/**\n * Build the theme `<style>` block CSS text for a resolved theme. Sets the\n * `--oc-*` custom properties on `svg.oc-chart` and defines every class-based\n * chrome rule against them.\n */\nexport function buildThemeStyleBlock(theme: ResolvedTheme): string {\n const accent = theme.colors.categorical[0] ?? cssTokenDefault('--oc-accent', 'light');\n const bg = theme.colors.neutral.surface;\n\n const props = [\n `--oc-font-family: ${theme.fonts.family}`,\n `--oc-font-mono: ${theme.fonts.mono}`,\n `--oc-title-size: ${theme.chrome.title.fontSize}px`,\n `--oc-title-weight: ${theme.chrome.title.fontWeight}`,\n `--oc-title-tracking: ${cssTokenDefault('--oc-title-tracking', 'light')}`,\n `--oc-subtitle-size: ${theme.chrome.subtitle.fontSize}px`,\n `--oc-subtitle-weight: ${theme.chrome.subtitle.fontWeight}`,\n `--oc-source-size: ${theme.chrome.source.fontSize}px`,\n `--oc-source-weight: ${theme.chrome.source.fontWeight}`,\n `--oc-body-size: ${theme.fonts.sizes.body}px`,\n `--oc-eyebrow-size: ${theme.chrome.eyebrow.fontSize}px`,\n `--oc-eyebrow-weight: ${theme.chrome.eyebrow.fontWeight}`,\n `--oc-eyebrow-tracking: ${cssTokenDefault('--oc-eyebrow-tracking', 'light')}`,\n `--oc-bg: ${bg}`,\n `--oc-text: ${theme.colors.text}`,\n `--oc-text-muted: ${theme.colors.axis}`,\n `--oc-text-secondary: ${theme.colors.neutral.secondary}`,\n `--oc-text-faint: ${theme.colors.neutral.faint}`,\n `--oc-border: ${theme.colors.neutral.border}`,\n `--oc-gridline: ${theme.colors.gridline}`,\n // Hairline, not the tick-label ink.\n `--oc-axis: ${theme.colors.hairline}`,\n `--oc-border-radius: ${theme.borderRadius}px`,\n `--oc-accent: ${accent}`,\n `--oc-accent-strong: ${adaptForLightLineStroke(accent)}`,\n `--oc-positive: ${theme.colors.positive}`,\n `--oc-negative: ${theme.colors.negative}`,\n `--oc-legend-text: ${theme.isDark ? cssTokenDefault('--oc-legend-text', 'dark') : cssTokenDefault('--oc-legend-text', 'light')}`,\n `--oc-space-2: ${theme.spacing.chromeGap * 2}px`,\n `--oc-space-4: ${theme.spacing.padding}px`,\n ];\n\n const rules = [\n // Tabular figures everywhere in the chart's own text: axis ticks, value\n // labels and legend entries all line up column-wise.\n `svg.oc-chart { ${props.join('; ')}; font-variant-numeric: tabular-nums; }`,\n `.oc-chrome { font-family: var(--oc-font-family); }`,\n `.oc-eyebrow { font-size: var(--oc-eyebrow-size); font-weight: var(--oc-eyebrow-weight); letter-spacing: var(--oc-eyebrow-tracking); text-transform: uppercase; fill: var(--oc-accent); }`,\n `.oc-title { font-size: var(--oc-title-size); font-weight: var(--oc-title-weight); letter-spacing: var(--oc-title-tracking); fill: var(--oc-text); }`,\n `.oc-subtitle { font-size: var(--oc-subtitle-size); font-weight: var(--oc-subtitle-weight); fill: var(--oc-text-muted); }`,\n `.oc-source, .oc-byline, .oc-footer { font-size: var(--oc-source-size); font-weight: var(--oc-source-weight); fill: var(--oc-text-muted); }`,\n `.oc-brand { font-size: 11px; font-weight: 500; letter-spacing: 0.02em; fill: var(--oc-text-faint); }`,\n `.oc-brand-dot { fill: var(--oc-accent); }`,\n `.oc-eyebrow-dot { fill: var(--oc-accent); }`,\n `.oc-metrics { font-family: var(--oc-font-family); }`,\n `.oc-metric-label { font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; fill: var(--oc-text-muted); }`,\n `.oc-metric-value { font-size: 22px; font-weight: 600; letter-spacing: -0.02em; fill: var(--oc-text); font-variant-numeric: tabular-nums; }`,\n `.oc-metric-delta-up { fill: var(--oc-positive); font-size: 12px; font-weight: 500; }`,\n `.oc-metric-delta-down { fill: var(--oc-negative); font-size: 12px; font-weight: 500; }`,\n `.oc-axis-tick-inline { font-size: 11px; font-weight: 400; fill: var(--oc-text-muted); }`,\n `.oc-endpoint-labels { font-family: var(--oc-font-family); }`,\n `.oc-endpoint-label { fill: var(--oc-endpoint-label-color, var(--oc-text)); }`,\n `.oc-endpoint-value { fill: var(--oc-endpoint-value-color, var(--oc-text-muted)); }`,\n `.oc-endpoint-leader { stroke: var(--oc-endpoint-leader-color, currentColor); }`,\n `.oc-annotation-subtitle { fill: var(--oc-annotation-subtitle-color, var(--oc-text-muted)); }`,\n `.oc-metric-secondary { fill: var(--oc-text-muted); font-size: 12px; font-weight: 400; }`,\n `.oc-legend { font-family: var(--oc-font-family); font-size: var(--oc-body-size); }`,\n `.oc-legend-entry { cursor: default; }`,\n `.oc-legend text { fill: var(--oc-legend-text); }`,\n ];\n\n return rules.join('\\n');\n}\n\n/**\n * Inject the theme style block into an SVG clone's `<defs>` so class-based fills\n * survive serialization. Idempotent-ish: adds one `<style data-oc-theme>` at the\n * front of `<defs>`; call once per clone before serializing. No-op if `theme` is\n * undefined (nothing to resolve against).\n */\nexport function injectThemeStyleBlock(svg: SVGElement, theme: ResolvedTheme | undefined): void {\n if (!theme) return;\n let defs = svg.querySelector('defs');\n if (!defs) {\n defs = document.createElementNS(SVG_NS, 'defs');\n svg.insertBefore(defs, svg.firstChild);\n }\n const style = document.createElementNS(SVG_NS, 'style');\n style.setAttribute('data-oc-theme', '');\n style.textContent = buildThemeStyleBlock(theme);\n defs.insertBefore(style, defs.firstChild);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
injectThemeStyleBlock
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5RX6ZQGZ.js";
|
|
4
4
|
|
|
5
5
|
// src/export.ts
|
|
6
6
|
function getSVGDimensions(svg) {
|
|
@@ -279,4 +279,4 @@ export {
|
|
|
279
279
|
exportJPG,
|
|
280
280
|
exportCSV
|
|
281
281
|
};
|
|
282
|
-
//# sourceMappingURL=chunk-
|
|
282
|
+
//# sourceMappingURL=chunk-6B5OBGIO.js.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// src/theme-tokens.ts
|
|
2
|
+
import { adaptForLightLineStroke, cssTokenDefault } from "@opendata-ai/openchart-core";
|
|
3
|
+
function resolvedSurface(theme) {
|
|
4
|
+
return theme.colors.neutral.surface;
|
|
5
|
+
}
|
|
6
|
+
function stampThemeProperties(el, theme) {
|
|
7
|
+
const accent = theme.colors.categorical[0] ?? cssTokenDefault("--oc-accent", "light");
|
|
8
|
+
const bg = resolvedSurface(theme);
|
|
9
|
+
const n = theme.colors.neutral;
|
|
10
|
+
const props = [
|
|
11
|
+
["--oc-font-family", theme.fonts.family],
|
|
12
|
+
["--oc-font-mono", theme.fonts.mono],
|
|
13
|
+
["--oc-title-size", `${theme.chrome.title.fontSize}px`],
|
|
14
|
+
["--oc-title-weight", `${theme.chrome.title.fontWeight}`],
|
|
15
|
+
["--oc-subtitle-size", `${theme.chrome.subtitle.fontSize}px`],
|
|
16
|
+
["--oc-subtitle-weight", `${theme.chrome.subtitle.fontWeight}`],
|
|
17
|
+
["--oc-source-size", `${theme.chrome.source.fontSize}px`],
|
|
18
|
+
["--oc-source-weight", `${theme.chrome.source.fontWeight}`],
|
|
19
|
+
["--oc-body-size", `${theme.fonts.sizes.body}px`],
|
|
20
|
+
["--oc-eyebrow-size", `${theme.chrome.eyebrow.fontSize}px`],
|
|
21
|
+
["--oc-eyebrow-weight", `${theme.chrome.eyebrow.fontWeight}`],
|
|
22
|
+
["--oc-bg", bg],
|
|
23
|
+
["--oc-text", theme.colors.text],
|
|
24
|
+
["--oc-text-muted", theme.colors.axis],
|
|
25
|
+
// Secondary grays are derived from the theme's own text/background pair
|
|
26
|
+
// (ResolvedTheme.colors.neutral), so a warm or cool theme gets warm or
|
|
27
|
+
// cool grays instead of zinc. One direction only: theme -> CSS.
|
|
28
|
+
["--oc-text-secondary", n.secondary],
|
|
29
|
+
["--oc-text-faint", n.faint],
|
|
30
|
+
["--oc-border", n.border],
|
|
31
|
+
["--oc-gray-100", n[100]],
|
|
32
|
+
["--oc-gray-200", n[200]],
|
|
33
|
+
["--oc-gray-300", n[300]],
|
|
34
|
+
["--oc-gray-400", n[400]],
|
|
35
|
+
["--oc-gray-600", n[600]],
|
|
36
|
+
["--oc-gray-800", n[800]],
|
|
37
|
+
["--oc-gridline", theme.colors.gridline],
|
|
38
|
+
// --oc-axis is the hairline the axis line is drawn with, not the ink its
|
|
39
|
+
// tick labels take (that is --oc-text-muted, above).
|
|
40
|
+
["--oc-axis", theme.colors.hairline],
|
|
41
|
+
["--oc-border-radius", `${theme.borderRadius}px`],
|
|
42
|
+
["--oc-accent", accent],
|
|
43
|
+
["--oc-accent-strong", adaptForLightLineStroke(accent)],
|
|
44
|
+
["--oc-positive", theme.colors.positive],
|
|
45
|
+
["--oc-negative", theme.colors.negative],
|
|
46
|
+
["--oc-space-2", `${theme.spacing.chromeGap * 2}px`],
|
|
47
|
+
["--oc-space-4", `${theme.spacing.padding}px`]
|
|
48
|
+
];
|
|
49
|
+
for (const [name, value] of props) {
|
|
50
|
+
el.style.setProperty(name, value);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export {
|
|
55
|
+
resolvedSurface,
|
|
56
|
+
stampThemeProperties
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=chunk-NG7CVCI2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/theme-tokens.ts"],"sourcesContent":["/**\n * Generate CSS custom properties from a resolved JS theme.\n *\n * Stamped on the .oc-root container at mount time so CSS consumers\n * read from the same source of truth as the JS engine. The static\n * values in tokens.css / dark.css serve as fallback defaults for\n * contexts where JS hasn't mounted (SSR, static HTML).\n */\n\nimport type { ResolvedTheme } from '@opendata-ai/openchart-core';\nimport { adaptForLightLineStroke, cssTokenDefault } from '@opendata-ai/openchart-core';\n\n/**\n * The opaque surface a theme paints on. A transparent theme background has no\n * color of its own, so it resolves to the static `--oc-bg` token for the mode --\n * the same value the engine's knockout strokes are cut in. Resolved once in\n * core, on `colors.neutral.surface`; this is a named read of it.\n */\nexport function resolvedSurface(theme: ResolvedTheme): string {\n return theme.colors.neutral.surface;\n}\n\nexport function stampThemeProperties(el: HTMLElement, theme: ResolvedTheme): void {\n const accent = theme.colors.categorical[0] ?? cssTokenDefault('--oc-accent', 'light');\n const bg = resolvedSurface(theme);\n\n const n = theme.colors.neutral;\n\n const props: [string, string][] = [\n ['--oc-font-family', theme.fonts.family],\n ['--oc-font-mono', theme.fonts.mono],\n ['--oc-title-size', `${theme.chrome.title.fontSize}px`],\n ['--oc-title-weight', `${theme.chrome.title.fontWeight}`],\n ['--oc-subtitle-size', `${theme.chrome.subtitle.fontSize}px`],\n ['--oc-subtitle-weight', `${theme.chrome.subtitle.fontWeight}`],\n ['--oc-source-size', `${theme.chrome.source.fontSize}px`],\n ['--oc-source-weight', `${theme.chrome.source.fontWeight}`],\n ['--oc-body-size', `${theme.fonts.sizes.body}px`],\n ['--oc-eyebrow-size', `${theme.chrome.eyebrow.fontSize}px`],\n ['--oc-eyebrow-weight', `${theme.chrome.eyebrow.fontWeight}`],\n ['--oc-bg', bg],\n ['--oc-text', theme.colors.text],\n ['--oc-text-muted', theme.colors.axis],\n // Secondary grays are derived from the theme's own text/background pair\n // (ResolvedTheme.colors.neutral), so a warm or cool theme gets warm or\n // cool grays instead of zinc. One direction only: theme -> CSS.\n ['--oc-text-secondary', n.secondary],\n ['--oc-text-faint', n.faint],\n ['--oc-border', n.border],\n ['--oc-gray-100', n[100]],\n ['--oc-gray-200', n[200]],\n ['--oc-gray-300', n[300]],\n ['--oc-gray-400', n[400]],\n ['--oc-gray-600', n[600]],\n ['--oc-gray-800', n[800]],\n ['--oc-gridline', theme.colors.gridline],\n // --oc-axis is the hairline the axis line is drawn with, not the ink its\n // tick labels take (that is --oc-text-muted, above).\n ['--oc-axis', theme.colors.hairline],\n ['--oc-border-radius', `${theme.borderRadius}px`],\n ['--oc-accent', accent],\n ['--oc-accent-strong', adaptForLightLineStroke(accent)],\n ['--oc-positive', theme.colors.positive],\n ['--oc-negative', theme.colors.negative],\n ['--oc-space-2', `${theme.spacing.chromeGap * 2}px`],\n ['--oc-space-4', `${theme.spacing.padding}px`],\n ];\n\n for (const [name, value] of props) {\n el.style.setProperty(name, value);\n }\n}\n"],"mappings":";AAUA,SAAS,yBAAyB,uBAAuB;AAQlD,SAAS,gBAAgB,OAA8B;AAC5D,SAAO,MAAM,OAAO,QAAQ;AAC9B;AAEO,SAAS,qBAAqB,IAAiB,OAA4B;AAChF,QAAM,SAAS,MAAM,OAAO,YAAY,CAAC,KAAK,gBAAgB,eAAe,OAAO;AACpF,QAAM,KAAK,gBAAgB,KAAK;AAEhC,QAAM,IAAI,MAAM,OAAO;AAEvB,QAAM,QAA4B;AAAA,IAChC,CAAC,oBAAoB,MAAM,MAAM,MAAM;AAAA,IACvC,CAAC,kBAAkB,MAAM,MAAM,IAAI;AAAA,IACnC,CAAC,mBAAmB,GAAG,MAAM,OAAO,MAAM,QAAQ,IAAI;AAAA,IACtD,CAAC,qBAAqB,GAAG,MAAM,OAAO,MAAM,UAAU,EAAE;AAAA,IACxD,CAAC,sBAAsB,GAAG,MAAM,OAAO,SAAS,QAAQ,IAAI;AAAA,IAC5D,CAAC,wBAAwB,GAAG,MAAM,OAAO,SAAS,UAAU,EAAE;AAAA,IAC9D,CAAC,oBAAoB,GAAG,MAAM,OAAO,OAAO,QAAQ,IAAI;AAAA,IACxD,CAAC,sBAAsB,GAAG,MAAM,OAAO,OAAO,UAAU,EAAE;AAAA,IAC1D,CAAC,kBAAkB,GAAG,MAAM,MAAM,MAAM,IAAI,IAAI;AAAA,IAChD,CAAC,qBAAqB,GAAG,MAAM,OAAO,QAAQ,QAAQ,IAAI;AAAA,IAC1D,CAAC,uBAAuB,GAAG,MAAM,OAAO,QAAQ,UAAU,EAAE;AAAA,IAC5D,CAAC,WAAW,EAAE;AAAA,IACd,CAAC,aAAa,MAAM,OAAO,IAAI;AAAA,IAC/B,CAAC,mBAAmB,MAAM,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA,IAIrC,CAAC,uBAAuB,EAAE,SAAS;AAAA,IACnC,CAAC,mBAAmB,EAAE,KAAK;AAAA,IAC3B,CAAC,eAAe,EAAE,MAAM;AAAA,IACxB,CAAC,iBAAiB,EAAE,GAAG,CAAC;AAAA,IACxB,CAAC,iBAAiB,EAAE,GAAG,CAAC;AAAA,IACxB,CAAC,iBAAiB,EAAE,GAAG,CAAC;AAAA,IACxB,CAAC,iBAAiB,EAAE,GAAG,CAAC;AAAA,IACxB,CAAC,iBAAiB,EAAE,GAAG,CAAC;AAAA,IACxB,CAAC,iBAAiB,EAAE,GAAG,CAAC;AAAA,IACxB,CAAC,iBAAiB,MAAM,OAAO,QAAQ;AAAA;AAAA;AAAA,IAGvC,CAAC,aAAa,MAAM,OAAO,QAAQ;AAAA,IACnC,CAAC,sBAAsB,GAAG,MAAM,YAAY,IAAI;AAAA,IAChD,CAAC,eAAe,MAAM;AAAA,IACtB,CAAC,sBAAsB,wBAAwB,MAAM,CAAC;AAAA,IACtD,CAAC,iBAAiB,MAAM,OAAO,QAAQ;AAAA,IACvC,CAAC,iBAAiB,MAAM,OAAO,QAAQ;AAAA,IACvC,CAAC,gBAAgB,GAAG,MAAM,QAAQ,YAAY,CAAC,IAAI;AAAA,IACnD,CAAC,gBAAgB,GAAG,MAAM,QAAQ,OAAO,IAAI;AAAA,EAC/C;AAEA,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO;AACjC,OAAG,MAAM,YAAY,MAAM,KAAK;AAAA,EAClC;AACF;","names":[]}
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
getSVGBackgroundColor,
|
|
6
6
|
getSVGDimensions,
|
|
7
7
|
rasterizeSVGToCanvas
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-6B5OBGIO.js";
|
|
9
9
|
import {
|
|
10
10
|
injectThemeStyleBlock
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-5RX6ZQGZ.js";
|
|
12
12
|
|
|
13
13
|
// src/gif-encode.ts
|
|
14
14
|
function readCanvasSRGB(canvas) {
|
|
@@ -231,4 +231,4 @@ export {
|
|
|
231
231
|
applyFrameState,
|
|
232
232
|
exportGIF
|
|
233
233
|
};
|
|
234
|
-
//# sourceMappingURL=chunk-
|
|
234
|
+
//# sourceMappingURL=chunk-RYVV3YIG.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
renderChromeElement,
|
|
4
4
|
renderLegend,
|
|
5
5
|
stampAnimationVars
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XGII4ZRT.js";
|
|
7
7
|
|
|
8
8
|
// src/tilemap-renderer.ts
|
|
9
9
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
@@ -327,4 +327,4 @@ function renderTileMapSVG(layout, opts) {
|
|
|
327
327
|
export {
|
|
328
328
|
renderTileMapSVG
|
|
329
329
|
};
|
|
330
|
-
//# sourceMappingURL=chunk-
|
|
330
|
+
//# sourceMappingURL=chunk-UAK6HWOC.js.map
|