shadertown 0.16.0 → 0.18.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/CHANGELOG.md CHANGED
@@ -6,6 +6,34 @@ deploys, not by this file.
6
6
  This project follows [semantic versioning](https://semver.org). Before 1.0 the
7
7
  minor number carries breaking changes, so pin it if that matters to you.
8
8
 
9
+ ## 0.18.0 — 2026-09-09
10
+
11
+ - `ShaderCanvas` draws a shadertown credit in a corner of the canvas, as a
12
+ visible link in the server-rendered HTML. `setBadge(false)` removes it from
13
+ every canvas on the page, `badge={false}` from one, and `badge="top-left"` —
14
+ or `setBadgePosition` — moves it between the four corners. Free shader
15
+ sources now ship a licence that asks for the credit; a paid licence lifts the
16
+ condition. Nothing in the runtime checks a licence or contacts a server.
17
+ - **Breaking:** `ShaderCanvas` wraps its canvas in a `span`, and `className` and
18
+ `style` now apply to that wrapper rather than to the canvas. The canvas fills
19
+ the wrapper, so a parent-sized layout is unchanged; a rule that targeted the
20
+ canvas element itself may need moving. The wrapper is present whether or not
21
+ the credit is drawn.
22
+ - `toConfigSource`, `toReactSource`, `toVanillaSource` and `toExampleSource`
23
+ take an optional `SnippetOptions`, and emit a licence notice unless it says
24
+ `creditRequired: false`. `toFreeLicense` is new beside `toLicense`.
25
+
26
+ ## 0.17.0 — 2026-09-09
27
+
28
+ - Add `liquid-light`, a glass wave with layered refraction, studio reflections,
29
+ procedural floor caustics, and independent geometry, material, and motion controls.
30
+ - Smooth highlights with temporal antialiasing and reset frame history when
31
+ parameters, quality, size, or time change. Cap internal resolution to keep
32
+ the glass passes bounded on large displays.
33
+ - Expand the shared Params buffer from 128 to 160 bytes with slots `h` through
34
+ `n`, preserving existing field offsets. Custom renderers must allocate the
35
+ larger buffer; SDK renderers handle this automatically.
36
+
9
37
  ## 0.16.0 — 2026-09-07
10
38
 
11
39
  - Give Meadow curated randomization ranges for readable lighting, grass size,
@@ -0,0 +1,60 @@
1
+ /**
2
+ * The credit a canvas carries, and the one switch that removes it.
3
+ *
4
+ * A free shader is paid for in links. The badge is how: a small, real,
5
+ * followed anchor to the shader's own page, drawn in the corner of the canvas
6
+ * it credits. It is deliberately not clever — no hidden text, no anchor with
7
+ * no size, no URL smuggled into a comment. A credit that a reader cannot see
8
+ * is worth nothing to a search engine and is against their policies besides.
9
+ *
10
+ * Nothing here checks a licence, and nothing here reaches the network. The
11
+ * runtime stays MIT and stays offline: `setBadge(false)` is one call, it works
12
+ * for everybody, and what makes it honest is the LICENSE file that ships beside
13
+ * a free shader, not a lock in this file. Enforcement in a bundle a reader can
14
+ * edit is theatre, and theatre is worse than terms.
15
+ *
16
+ * The setting is page-wide for the same reason `setQualityTier` is: an app
17
+ * either credits or it does not, and passing the same prop to forty canvases
18
+ * is how one gets missed.
19
+ */
20
+ /**
21
+ * Which corner the credit sits in.
22
+ *
23
+ * Four corners and nothing else — no offset, no opacity, no class to style it
24
+ * with. A badge that collides with a reader's own controls is a reason to strip
25
+ * it rather than move it, so moving it has to be easy. Every other knob anyone
26
+ * would ask for is a knob for hiding it while claiming it is on, and there is
27
+ * already a switch for turning it off honestly.
28
+ */
29
+ export type BadgeCorner = "bottom-right" | "bottom-left" | "top-right" | "top-left";
30
+ /** The inset of each corner, in pixels from the two edges it touches. */
31
+ export declare const BADGE_CORNERS: Record<BadgeCorner, Record<string, number>>;
32
+ /**
33
+ * Show or hide the credit on every canvas on the page.
34
+ *
35
+ * Call it at module scope, in a module both the server and the browser load.
36
+ * The badge is rendered, not mounted — setting this inside an effect would
37
+ * render one on the server and none in the browser, which is a hydration
38
+ * mismatch rather than a hidden badge.
39
+ */
40
+ export declare function setBadge(shown: boolean): void;
41
+ /** Whether the page credits shadertown. Defaults to true. */
42
+ export declare function badgeShown(): boolean;
43
+ /**
44
+ * Put the credit in a different corner of every canvas on the page. Same rule
45
+ * as `setBadge`: module scope, where the server and the browser both run it.
46
+ */
47
+ export declare function setBadgePosition(corner: BadgeCorner): void;
48
+ /** The corner the page puts the credit in. Defaults to `bottom-right`. */
49
+ export declare function badgePosition(): BadgeCorner;
50
+ /**
51
+ * Where a badge points: the page for the shader it is drawn on, not the home
52
+ * page. One badge per shader spreads the links across the catalogue the way a
53
+ * hand-written link would, and it takes the reader to the thing they just saw
54
+ * rather than to a pitch.
55
+ */
56
+ export declare function badgeHref(shader: string): string;
57
+ /** The anchor text. The brand, and enough words to say what the link is. */
58
+ export declare const BADGE_PREFIX = "Shaders by";
59
+ export declare const BADGE_NAME = "shadertown";
60
+ //# sourceMappingURL=badge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../src/badge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,aAAa,GAAG,WAAW,GAAG,UAAU,CAAC;AAEpF,yEAAyE;AACzE,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKrE,CAAC;AAKF;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAE7C;AAED,6DAA6D;AAC7D,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAE1D;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,IAAI,WAAW,CAE3C;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,4EAA4E;AAC5E,eAAO,MAAM,YAAY,eAAe,CAAC;AACzC,eAAO,MAAM,UAAU,eAAe,CAAC"}
package/dist/badge.js ADDED
@@ -0,0 +1,69 @@
1
+ /**
2
+ * The credit a canvas carries, and the one switch that removes it.
3
+ *
4
+ * A free shader is paid for in links. The badge is how: a small, real,
5
+ * followed anchor to the shader's own page, drawn in the corner of the canvas
6
+ * it credits. It is deliberately not clever — no hidden text, no anchor with
7
+ * no size, no URL smuggled into a comment. A credit that a reader cannot see
8
+ * is worth nothing to a search engine and is against their policies besides.
9
+ *
10
+ * Nothing here checks a licence, and nothing here reaches the network. The
11
+ * runtime stays MIT and stays offline: `setBadge(false)` is one call, it works
12
+ * for everybody, and what makes it honest is the LICENSE file that ships beside
13
+ * a free shader, not a lock in this file. Enforcement in a bundle a reader can
14
+ * edit is theatre, and theatre is worse than terms.
15
+ *
16
+ * The setting is page-wide for the same reason `setQualityTier` is: an app
17
+ * either credits or it does not, and passing the same prop to forty canvases
18
+ * is how one gets missed.
19
+ */
20
+ /** The canonical host. The apex redirects, so a badge must never point at it. */
21
+ const HOME = "https://www.shadertown.com";
22
+ /** The inset of each corner, in pixels from the two edges it touches. */
23
+ export const BADGE_CORNERS = {
24
+ "bottom-right": { bottom: 10, right: 10 },
25
+ "bottom-left": { bottom: 10, left: 10 },
26
+ "top-right": { top: 10, right: 10 },
27
+ "top-left": { top: 10, left: 10 },
28
+ };
29
+ let pageBadge = true;
30
+ let pageCorner = "bottom-right";
31
+ /**
32
+ * Show or hide the credit on every canvas on the page.
33
+ *
34
+ * Call it at module scope, in a module both the server and the browser load.
35
+ * The badge is rendered, not mounted — setting this inside an effect would
36
+ * render one on the server and none in the browser, which is a hydration
37
+ * mismatch rather than a hidden badge.
38
+ */
39
+ export function setBadge(shown) {
40
+ pageBadge = shown;
41
+ }
42
+ /** Whether the page credits shadertown. Defaults to true. */
43
+ export function badgeShown() {
44
+ return pageBadge;
45
+ }
46
+ /**
47
+ * Put the credit in a different corner of every canvas on the page. Same rule
48
+ * as `setBadge`: module scope, where the server and the browser both run it.
49
+ */
50
+ export function setBadgePosition(corner) {
51
+ pageCorner = corner;
52
+ }
53
+ /** The corner the page puts the credit in. Defaults to `bottom-right`. */
54
+ export function badgePosition() {
55
+ return pageCorner;
56
+ }
57
+ /**
58
+ * Where a badge points: the page for the shader it is drawn on, not the home
59
+ * page. One badge per shader spreads the links across the catalogue the way a
60
+ * hand-written link would, and it takes the reader to the thing they just saw
61
+ * rather than to a pitch.
62
+ */
63
+ export function badgeHref(shader) {
64
+ return `${HOME}/shaders/${shader}?ref=badge`;
65
+ }
66
+ /** The anchor text. The brand, and enough words to say what the link is. */
67
+ export const BADGE_PREFIX = "Shaders by";
68
+ export const BADGE_NAME = "shadertown";
69
+ //# sourceMappingURL=badge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge.js","sourceRoot":"","sources":["../src/badge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,iFAAiF;AACjF,MAAM,IAAI,GAAG,4BAA4B,CAAC;AAa1C,yEAAyE;AACzE,MAAM,CAAC,MAAM,aAAa,GAAgD;IACxE,cAAc,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;IACzC,aAAa,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IACvC,WAAW,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;IACnC,UAAU,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;CAClC,CAAC;AAEF,IAAI,SAAS,GAAG,IAAI,CAAC;AACrB,IAAI,UAAU,GAAgB,cAAc,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,SAAS,GAAG,KAAK,CAAC;AACpB,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,UAAU;IACxB,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAmB;IAClD,UAAU,GAAG,MAAM,CAAC;AACtB,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,aAAa;IAC3B,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,OAAO,GAAG,IAAI,YAAY,MAAM,YAAY,CAAC;AAC/C,CAAC;AAED,4EAA4E;AAC5E,MAAM,CAAC,MAAM,YAAY,GAAG,YAAY,CAAC;AACzC,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { type ShaderGraph } from "./graph.js";
2
+ import type { ShaderName } from "./registry.js";
3
+ import type { Stage } from "./stage.js";
4
+ export declare function createDielectricGraph(stage: Stage, name: ShaderName, width: number, height: number): ShaderGraph;
5
+ //# sourceMappingURL=dielectric.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dielectric.d.ts","sourceRoot":"","sources":["../src/dielectric.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAOxC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAgHhH"}
@@ -0,0 +1,135 @@
1
+ import { draw, effect, sampler, target } from "vgpu";
2
+ import { shaderSources } from "./generated/sources.js";
3
+ import { createBloomChain } from "./graph.js";
4
+ const SAMPLE_OFFSETS = [
5
+ [0, -1 / 6], [-1 / 4, 1 / 6], [1 / 4, -7 / 18], [-3 / 8, -1 / 18],
6
+ [1 / 8, 5 / 18], [-1 / 8, -5 / 18], [3 / 8, 1 / 18], [-7 / 16, 7 / 18],
7
+ ];
8
+ export function createDielectricGraph(stage, name, width, height) {
9
+ const gpu = stage.gpu;
10
+ const source = shaderSources[name];
11
+ const label = `shadertown:${name}`;
12
+ const sizeOf = (w, h) => [Math.max(1, Math.floor(w)), Math.max(1, Math.floor(h))];
13
+ // Bound expensive glass rays independently of the display pixel ratio.
14
+ const renderSize = (w, h, low) => {
15
+ const [displayWidth, displayHeight] = sizeOf(w, h);
16
+ const scale = Math.min(1, Math.sqrt((low ? 230400 : 921600) / (displayWidth * displayHeight)));
17
+ return sizeOf(displayWidth * scale, displayHeight * scale);
18
+ };
19
+ let low = false;
20
+ let size = renderSize(width, height, low);
21
+ const owned = (suffix) => target(gpu, {
22
+ size, format: "rgba16float", label: `${label}:${suffix}`,
23
+ });
24
+ const backdrop = owned("pearl-backdrop");
25
+ const glass = owned("glass");
26
+ const resolved = owned("resolved");
27
+ const history = owned("history");
28
+ let samples = 0;
29
+ let previousParams = "";
30
+ let previousTime = 0;
31
+ const linearSampler = sampler(gpu, { minFilter: "linear", magFilter: "linear" });
32
+ const pass = (fragment, set) => draw(gpu, {
33
+ shader: source, entry: { vertex: "vs_fullscreen", fragment }, vertices: 3,
34
+ depth: false, label: `${label}:${fragment}`, set: { linearSampler, ...set },
35
+ });
36
+ const ground = pass("fs_backdrop", {});
37
+ const surface = pass("fs_glass", { t_backdrop: backdrop });
38
+ const resolve = pass("fs_resolve", { t_glass: glass, t_history: history });
39
+ const remember = pass("fs_history", { t_glass: resolved });
40
+ const bloom = createBloomChain(gpu, source, label, resolved, {
41
+ threshold: 1.4, smoothWidth: 0.8, strength: 0.12, radius: 0.45,
42
+ kernelRadii: [6, 10, 14, 18, 22], factors: [1, 0.8, 0.6, 0.4, 0.2], bright: "fs_brightAlpha",
43
+ });
44
+ const present = effect(gpu, source, {
45
+ label: `${label}:present`, set: { t_scene: resolved, t_bloom: bloom.output, linearSampler },
46
+ });
47
+ let destroyed = false;
48
+ const resize = () => {
49
+ const next = renderSize(width, height, low);
50
+ if (next[0] === size[0] && next[1] === size[1])
51
+ return;
52
+ size = next;
53
+ backdrop.resize(size);
54
+ glass.resize(size);
55
+ resolved.resize(size);
56
+ history.resize(size);
57
+ samples = 0;
58
+ surface.set({ t_backdrop: backdrop });
59
+ resolve.set({ t_glass: glass, t_history: history });
60
+ remember.set({ t_glass: resolved });
61
+ bloom.rebind(resolved, size);
62
+ present.set({ t_scene: resolved, t_bloom: bloom.output });
63
+ };
64
+ return {
65
+ present,
66
+ encode(frame, uniforms) {
67
+ if (destroyed)
68
+ return;
69
+ if (low !== (uniforms.quality < 0.5)) {
70
+ low = uniforms.quality < 0.5;
71
+ resize();
72
+ }
73
+ ground.set({ params: uniforms });
74
+ const clock = uniforms.time * uniforms.speed * 0.7;
75
+ const curl = Math.min(2, Math.max(0.3, uniforms.h + uniforms.warp * 0.35 * Math.sin(clock * 0.85)));
76
+ const radius = 1.18 / Math.sqrt(curl);
77
+ const height = uniforms.i * (1 + uniforms.warp * 0.18 * Math.sin(clock)) * 1.18 / radius;
78
+ const heading = (uniforms.l + uniforms.time * uniforms.speed * uniforms.n) * Math.PI / 180;
79
+ const turn = 0.58 + heading + uniforms.warp * 0.24 * Math.sin(clock * 0.7);
80
+ const lean = uniforms.m * Math.PI / 180;
81
+ const { time: _time, ...settings } = uniforms;
82
+ const key = JSON.stringify(settings);
83
+ if (key !== previousParams || uniforms.time < previousTime || uniforms.time - previousTime > 0.25) {
84
+ samples = 0;
85
+ previousParams = key;
86
+ }
87
+ previousTime = uniforms.time;
88
+ const jitter = SAMPLE_OFFSETS[samples % SAMPLE_OFFSETS.length];
89
+ const historyWeight = Math.max(0.45, 0.85 - uniforms.speed * (uniforms.warp * 0.12 + Math.abs(uniforms.n) * 0.01));
90
+ const pose = {
91
+ shape: [clock, height, radius, 2 + (curl - 1) * 1.65 + Math.sin(clock) * 0.45 * uniforms.warp],
92
+ turn: [Math.cos(turn), Math.sin(turn), Math.cos(lean), Math.sin(lean)],
93
+ sample: [jitter[0], jitter[1], samples > 0 ? historyWeight : 0, 0],
94
+ };
95
+ surface.set({ params: uniforms, pose });
96
+ resolve.set({ pose });
97
+ samples++;
98
+ frame.pass(backdrop, ground);
99
+ frame.pass(glass, surface);
100
+ frame.pass(resolved, resolve);
101
+ frame.pass(history, remember);
102
+ bloom.encode(frame);
103
+ },
104
+ resize(w, h) {
105
+ if (destroyed)
106
+ return;
107
+ width = w;
108
+ height = h;
109
+ resize();
110
+ },
111
+ async compile() {
112
+ const results = await Promise.allSettled([ground.compile(backdrop), surface.compile(glass), resolve.compile(resolved), remember.compile(history), ...bloom.compile()]);
113
+ const failed = results.find((result) => result.status === "rejected");
114
+ if (failed?.status === "rejected")
115
+ throw failed.reason;
116
+ },
117
+ destroy() {
118
+ if (destroyed)
119
+ return;
120
+ destroyed = true;
121
+ const failures = [];
122
+ for (const release of [() => bloom.destroy(), () => history.destroy(), () => resolved.destroy(), () => glass.destroy(), () => backdrop.destroy()]) {
123
+ try {
124
+ release();
125
+ }
126
+ catch (error) {
127
+ failures.push(error);
128
+ }
129
+ }
130
+ if (failures.length)
131
+ throw failures[0];
132
+ },
133
+ };
134
+ }
135
+ //# sourceMappingURL=dielectric.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dielectric.js","sourceRoot":"","sources":["../src/dielectric.ts"],"names":[],"mappings":"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"}
package/dist/export.d.ts CHANGED
@@ -5,17 +5,28 @@ import { type ShaderName, type ShaderParams } from "./registry.js";
5
5
  * changing anyone's pinned look.
6
6
  */
7
7
  export declare function diffParams<K extends ShaderName>(name: K, params: ShaderParams<K>): Record<string, number | string>;
8
+ export interface SnippetOptions {
9
+ /**
10
+ * Whether the reader has to keep the credit — true for a Free shader taken
11
+ * without paying, which is the only case worth a notice in the file.
12
+ *
13
+ * Defaults to true, the same way round as the LICENSE the registry picks:
14
+ * the worst a mistake here can do is tell someone who paid about a condition
15
+ * that does not bind them.
16
+ */
17
+ readonly creditRequired?: boolean;
18
+ }
8
19
  /** A `shader.config.ts` module: the tuned preset, typed against the registry. */
9
- export declare function toConfigSource<K extends ShaderName>(name: K, params: ShaderParams<K>): string;
20
+ export declare function toConfigSource<K extends ShaderName>(name: K, params: ShaderParams<K>, options?: SnippetOptions): string;
10
21
  /** A drop-in React usage snippet for the current settings. */
11
- export declare function toReactSource<K extends ShaderName>(name: K, params: ShaderParams<K>): string;
22
+ export declare function toReactSource<K extends ShaderName>(name: K, params: ShaderParams<K>, options?: SnippetOptions): string;
12
23
  /** The imperative form, for codebases that are not React. */
13
- export declare function toVanillaSource<K extends ShaderName>(name: K, params: ShaderParams<K>): string;
24
+ export declare function toVanillaSource<K extends ShaderName>(name: K, params: ShaderParams<K>, options?: SnippetOptions): string;
14
25
  /** The complete, self-contained WGSL for this shader. */
15
26
  export declare function toWgslSource<K extends ShaderName>(name: K): string;
16
27
  export declare function toInstallCommand<K extends ShaderName>(name: K): string;
17
28
  /** A paste-ready component wired with the tuned parameters. */
18
- export declare function toExampleSource<K extends ShaderName>(name: K, params: ShaderParams<K>): string;
29
+ export declare function toExampleSource<K extends ShaderName>(name: K, params: ShaderParams<K>, options?: SnippetOptions): string;
19
30
  /**
20
31
  * Per-shader documentation, generated from the registry rather than written by
21
32
  * hand — the control table cannot drift out of date with the shader.
@@ -25,6 +36,23 @@ export interface LicenceHolder {
25
36
  readonly name?: string;
26
37
  readonly order?: string;
27
38
  }
28
- /** The licence that ships with a purchased shader, issued to the buyer. */
39
+ /**
40
+ * The licence that ships with a Free shader, taken by anyone, unpaid.
41
+ *
42
+ * The obligation it carries — leave the credit on — is stated here and nowhere
43
+ * else. `setBadge(false)` is one call and always will be: a check inside a
44
+ * bundle the holder can edit would stop nobody and would break the promise that
45
+ * the runtime never phones home. The terms are what bind; the code is not.
46
+ *
47
+ * Kept in step with the /license page, which is the full version of the same
48
+ * grant. Change one and change the other.
49
+ */
50
+ export declare function toFreeLicense<K extends ShaderName>(name: K): string;
51
+ /**
52
+ * The licence that ships with a purchased shader, issued to the buyer.
53
+ *
54
+ * Kept in step with the /license page, which is the full version of the same
55
+ * grant. Change one and change the other.
56
+ */
29
57
  export declare function toLicense<K extends ShaderName>(name: K, holder?: LicenceHolder): string;
30
58
  //# sourceMappingURL=export.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../src/export.ts"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,UAAU,EACf,KAAK,YAAY,EAClB,MAAM,eAAe,CAAC;AAevB;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,UAAU,EAC7C,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GACtB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAQjC;AAgBD,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,CAAC,SAAS,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,CAW7F;AAED,8DAA8D;AAC9D,wBAAgB,aAAa,CAAC,CAAC,SAAS,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,CAoB5F;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,CAAC,SAAS,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,CAuB9F;AAED,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,CAAC,SAAS,UAAU,EAAE,IAAI,EAAE,CAAC,GAAG,MAAM,CAElE;AAED,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,UAAU,EAAE,IAAI,EAAE,CAAC,GAAG,MAAM,CAEtE;AAOD,+DAA+D;AAC/D,wBAAgB,eAAe,CAAC,CAAC,SAAS,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,CAwB9F;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,CAyTvF;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,CAAC,SAAS,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,GAAE,aAAkB,GAAG,MAAM,CA0B3F"}
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../src/export.ts"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,UAAU,EACf,KAAK,YAAY,EAClB,MAAM,eAAe,CAAC;AAevB;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,UAAU,EAC7C,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GACtB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAQjC;AAgBD,MAAM,WAAW,cAAc;IAC7B;;;;;;;OAOG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CACnC;AA6BD,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,CAAC,SAAS,UAAU,EACjD,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,OAAO,GAAE,cAAmB,GAC3B,MAAM,CAWR;AAED,8DAA8D;AAC9D,wBAAgB,aAAa,CAAC,CAAC,SAAS,UAAU,EAChD,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,OAAO,GAAE,cAAmB,GAC3B,MAAM,CAoBR;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,CAAC,SAAS,UAAU,EAClD,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,OAAO,GAAE,cAAmB,GAC3B,MAAM,CAuBR;AAED,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,CAAC,SAAS,UAAU,EAAE,IAAI,EAAE,CAAC,GAAG,MAAM,CAElE;AAED,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,UAAU,EAAE,IAAI,EAAE,CAAC,GAAG,MAAM,CAEtE;AAOD,+DAA+D;AAC/D,wBAAgB,eAAe,CAAC,CAAC,SAAS,UAAU,EAClD,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,OAAO,GAAE,cAAmB,GAC3B,MAAM,CAwBR;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,CAoYvF;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,UAAU,EAAE,IAAI,EAAE,CAAC,GAAG,MAAM,CA+DnE;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,GAAE,aAAkB,GAAG,MAAM,CAuD3F"}