@fusion.dev/helix-plot 0.0.0-dev
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/LICENSE +21 -0
- package/README.md +147 -0
- package/dist/connect-plot/connect-plot.d.ts +125 -0
- package/dist/connect-plot/connect-plot.d.ts.map +1 -0
- package/dist/connect-plot/connect-plot.js +130 -0
- package/dist/connect-plot/connect-plot.js.map +1 -0
- package/dist/connect-spatial-heatmap/connect-spatial-heatmap.d.ts +43 -0
- package/dist/connect-spatial-heatmap/connect-spatial-heatmap.d.ts.map +1 -0
- package/dist/connect-spatial-heatmap/connect-spatial-heatmap.js +15 -0
- package/dist/connect-spatial-heatmap/connect-spatial-heatmap.js.map +1 -0
- package/dist/connect-spatial-scatter-chart/connect-spatial-scatter-chart.d.ts +34 -0
- package/dist/connect-spatial-scatter-chart/connect-spatial-scatter-chart.d.ts.map +1 -0
- package/dist/connect-spatial-scatter-chart/connect-spatial-scatter-chart.js +7 -0
- package/dist/connect-spatial-scatter-chart/connect-spatial-scatter-chart.js.map +1 -0
- package/dist/connect-spatial-surface-chart/connect-spatial-surface-chart.d.ts +39 -0
- package/dist/connect-spatial-surface-chart/connect-spatial-surface-chart.d.ts.map +1 -0
- package/dist/connect-spatial-surface-chart/connect-spatial-surface-chart.js +7 -0
- package/dist/connect-spatial-surface-chart/connect-spatial-surface-chart.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/three/heatmap-driver.d.ts +36 -0
- package/dist/three/heatmap-driver.d.ts.map +1 -0
- package/dist/three/heatmap-driver.js +120 -0
- package/dist/three/heatmap-driver.js.map +1 -0
- package/dist/three/index.d.ts +4 -0
- package/dist/three/index.d.ts.map +1 -0
- package/dist/three/index.js +4 -0
- package/dist/three/index.js.map +1 -0
- package/dist/three/scatter-driver.d.ts +38 -0
- package/dist/three/scatter-driver.d.ts.map +1 -0
- package/dist/three/scatter-driver.js +85 -0
- package/dist/three/scatter-driver.js.map +1 -0
- package/dist/three/stage.d.ts +66 -0
- package/dist/three/stage.d.ts.map +1 -0
- package/dist/three/stage.js +446 -0
- package/dist/three/stage.js.map +1 -0
- package/dist/three/surface-driver.d.ts +39 -0
- package/dist/three/surface-driver.d.ts.map +1 -0
- package/dist/three/surface-driver.js +150 -0
- package/dist/three/surface-driver.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { SpatialHeatmapDriver } from '../connect-spatial-heatmap/connect-spatial-heatmap.js';
|
|
2
|
+
/** How the three.js heatmap driver behaves where the page does not say. */
|
|
3
|
+
export interface ThreeHeatmapDriverOptions {
|
|
4
|
+
/**
|
|
5
|
+
* How many pixels the drawing has for each of the page's. By default, on a
|
|
6
|
+
* screen worked with a mouse, half as many again as the screen has, at
|
|
7
|
+
* least two and at most three; on a touch screen, as many as the screen
|
|
8
|
+
* has, at most two.
|
|
9
|
+
*/
|
|
10
|
+
density?: number | undefined;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Draws a spatial heatmap's readings as prisms in three dimensions with
|
|
14
|
+
* three.js. Pass it to `connectSpatialHeatmap` with the element in the
|
|
15
|
+
* chart's `renderer` slot:
|
|
16
|
+
*
|
|
17
|
+
* ```js
|
|
18
|
+
* import { connectSpatialHeatmap } from '@fusion.dev/helix-plot'
|
|
19
|
+
* import { threeHeatmapDriver } from '@fusion.dev/helix-plot/three'
|
|
20
|
+
*
|
|
21
|
+
* connectSpatialHeatmap(chart, threeHeatmapDriver(chart.querySelector('[slot="renderer"]')))
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* **Each reading is a prism on a slab**, as tall as the chart's own drawing
|
|
25
|
+
* stands it and in its tone, lit from above and the upper left, with each
|
|
26
|
+
* edge set a little apart from its face. A day with nothing in it is a tile.
|
|
27
|
+
*
|
|
28
|
+
* **Dragging turns the relief, and the wheel and a pinch bring it nearer.**
|
|
29
|
+
* Shift with an arrow on the chart turns it a step. It never turns by itself.
|
|
30
|
+
* It draws only while something moves, asks for no frames at rest, and
|
|
31
|
+
* shares the page's WebGL contexts with every three.js drawing Helix makes.
|
|
32
|
+
*
|
|
33
|
+
* The renderer is the driver's own, and `disconnect()` frees it.
|
|
34
|
+
*/
|
|
35
|
+
export declare const threeHeatmapDriver: (container: HTMLElement, options?: ThreeHeatmapDriverOptions) => SpatialHeatmapDriver;
|
|
36
|
+
//# sourceMappingURL=heatmap-driver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heatmap-driver.d.ts","sourceRoot":"","sources":["../../src/three/heatmap-driver.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EACV,oBAAoB,EAErB,MAAM,uDAAuD,CAAA;AAG9D,2EAA2E;AAC3E,MAAM,WAAW,yBAAyB;IACxC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC7B;AA6BD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,kBAAkB,cAClB,WAAW,YACb,yBAAyB,KACjC,oBAqIF,CAAA"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { BoxGeometry, BufferGeometry, Color, DirectionalLight, EdgesGeometry, Float32BufferAttribute, HemisphereLight, LineBasicMaterial, LineSegments, Mesh, MeshLambertMaterial, Vector3, } from 'three';
|
|
2
|
+
import { mergeGeometries } from 'three/addons/utils/BufferGeometryUtils.js';
|
|
3
|
+
import { createStage } from './stage.js';
|
|
4
|
+
const FOOTPRINT = 0.84;
|
|
5
|
+
const MARGIN = 0.3;
|
|
6
|
+
const THICKNESS = 0.25;
|
|
7
|
+
const TILE = 0.05;
|
|
8
|
+
const FLOOR = -0.3;
|
|
9
|
+
const SPAN = 1.9;
|
|
10
|
+
const edgeOf = (face) => {
|
|
11
|
+
const hsl = { h: 0, l: 0, s: 0 };
|
|
12
|
+
face.getHSL(hsl);
|
|
13
|
+
return face.clone().lerp(new Color(hsl.l < 0.5 ? 0xffffff : 0x000000), hsl.l < 0.5 ? 0.22 : 0.18);
|
|
14
|
+
};
|
|
15
|
+
export const threeHeatmapDriver = (container, options = {}) => {
|
|
16
|
+
let field;
|
|
17
|
+
let framed = false;
|
|
18
|
+
let cornered;
|
|
19
|
+
let unfollow;
|
|
20
|
+
let tops = [];
|
|
21
|
+
const prismMaterial = new MeshLambertMaterial({
|
|
22
|
+
polygonOffset: true,
|
|
23
|
+
polygonOffsetFactor: 1,
|
|
24
|
+
polygonOffsetUnits: 1,
|
|
25
|
+
vertexColors: true,
|
|
26
|
+
});
|
|
27
|
+
const prisms = new Mesh(new BufferGeometry(), prismMaterial);
|
|
28
|
+
const edgeMaterial = new LineBasicMaterial({ vertexColors: true });
|
|
29
|
+
const edges = new LineSegments(new BufferGeometry(), edgeMaterial);
|
|
30
|
+
const baseMaterial = new MeshLambertMaterial();
|
|
31
|
+
const base = new Mesh(new BoxGeometry(1, 1, 1), baseMaterial);
|
|
32
|
+
base.visible = false;
|
|
33
|
+
const stage = createStage(container, {
|
|
34
|
+
density: options.density,
|
|
35
|
+
pick: (ray) => {
|
|
36
|
+
const hit = ray.intersectObject(prisms)[0];
|
|
37
|
+
return hit?.faceIndex === undefined || hit.faceIndex === null || !field
|
|
38
|
+
? -1
|
|
39
|
+
: Math.min(Math.floor(hit.faceIndex / 12), field.cells.length - 1);
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
const sky = new HemisphereLight(0xffffff, 0xffffff, 2.2);
|
|
43
|
+
const sun = new DirectionalLight(0xffffff, 1);
|
|
44
|
+
sun.position.set(-2, 4, 1);
|
|
45
|
+
stage.scene.add(base, prisms, edges, sky, sun);
|
|
46
|
+
const painted = (geometry, color) => {
|
|
47
|
+
const count = geometry.getAttribute('position').count;
|
|
48
|
+
const colors = new Float32Array(count * 3);
|
|
49
|
+
for (let at = 0; at < count; at++) {
|
|
50
|
+
colors.set([color.r, color.g, color.b], at * 3);
|
|
51
|
+
}
|
|
52
|
+
geometry.setAttribute('color', new Float32BufferAttribute(colors, 3));
|
|
53
|
+
return geometry;
|
|
54
|
+
};
|
|
55
|
+
return {
|
|
56
|
+
draw: (next, colors) => {
|
|
57
|
+
field = next;
|
|
58
|
+
const unit = SPAN / Math.max(next.columns, next.rows, 1);
|
|
59
|
+
const tile = new Color(colors.extra.tile ?? colors.ground);
|
|
60
|
+
const solids = [];
|
|
61
|
+
const lines = [];
|
|
62
|
+
tops = next.cells.map((cell) => {
|
|
63
|
+
const color = cell.tone ? new Color(colors.extra[`tone-${cell.tone}`] ?? colors.ink) : tile;
|
|
64
|
+
const tall = Math.max(cell.height, TILE) * unit;
|
|
65
|
+
const x = (cell.column + 0.5 - next.columns / 2) * unit;
|
|
66
|
+
const z = (cell.row + 0.5 - next.rows / 2) * unit;
|
|
67
|
+
const box = new BoxGeometry(unit * FOOTPRINT, tall, unit * FOOTPRINT);
|
|
68
|
+
box.translate(x, FLOOR + tall / 2, z);
|
|
69
|
+
solids.push(painted(box, color));
|
|
70
|
+
lines.push(painted(new EdgesGeometry(box), edgeOf(color)));
|
|
71
|
+
return new Vector3(x, FLOOR + tall, z);
|
|
72
|
+
});
|
|
73
|
+
prisms.geometry.dispose();
|
|
74
|
+
edges.geometry.dispose();
|
|
75
|
+
prisms.geometry = (solids.length > 0 && mergeGeometries(solids)) || new BufferGeometry();
|
|
76
|
+
edges.geometry = (lines.length > 0 && mergeGeometries(lines)) || new BufferGeometry();
|
|
77
|
+
for (const one of [...solids, ...lines]) {
|
|
78
|
+
one.dispose();
|
|
79
|
+
}
|
|
80
|
+
base.scale.set((next.columns + 2 * MARGIN) * unit, THICKNESS * unit, (next.rows + 2 * MARGIN) * unit);
|
|
81
|
+
base.position.set(0, FLOOR - (THICKNESS * unit) / 2, 0);
|
|
82
|
+
baseMaterial.color.setStyle(colors.extra.base ?? colors.grid);
|
|
83
|
+
base.visible = next.cells.length > 0;
|
|
84
|
+
const tallest = Math.max(TILE, ...next.cells.map((cell) => cell.height)) * unit;
|
|
85
|
+
const wide = (next.columns + 2 * MARGIN) * unit;
|
|
86
|
+
const deep = (next.rows + 2 * MARGIN) * unit;
|
|
87
|
+
const high = tallest + THICKNESS * unit;
|
|
88
|
+
stage.frame(new Vector3(-wide / 2, FLOOR - THICKNESS * unit, -deep / 2), new Vector3(wide / 2, FLOOR - THICKNESS * unit + high, deep / 2), framed ? undefined : new Vector3(1, 1, 1));
|
|
89
|
+
framed = true;
|
|
90
|
+
unfollow?.();
|
|
91
|
+
const foot = FLOOR - THICKNESS * unit;
|
|
92
|
+
unfollow = stage.track([new Vector3(-wide / 2, foot, deep / 2), new Vector3(wide / 2, foot, deep / 2)], (at) => {
|
|
93
|
+
cornered?.(at ? { end: at[1], start: at[0] } : undefined);
|
|
94
|
+
});
|
|
95
|
+
},
|
|
96
|
+
focus: (index) => {
|
|
97
|
+
stage.setMarker(tops[index]);
|
|
98
|
+
},
|
|
99
|
+
onCorners: (listener) => {
|
|
100
|
+
cornered = listener;
|
|
101
|
+
return () => {
|
|
102
|
+
cornered = undefined;
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
onHover: (listener) => stage.onHover(listener),
|
|
106
|
+
onPlace: (listener) => stage.onPlace(listener),
|
|
107
|
+
onPress: (listener) => stage.onPress(listener),
|
|
108
|
+
stop: () => {
|
|
109
|
+
prisms.geometry.dispose();
|
|
110
|
+
prismMaterial.dispose();
|
|
111
|
+
edges.geometry.dispose();
|
|
112
|
+
edgeMaterial.dispose();
|
|
113
|
+
base.geometry.dispose();
|
|
114
|
+
baseMaterial.dispose();
|
|
115
|
+
stage.stop();
|
|
116
|
+
},
|
|
117
|
+
turnBy: (across, up, animate) => stage.turnBy(across, up, animate),
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=heatmap-driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heatmap-driver.js","sourceRoot":"","sources":["../../src/three/heatmap-driver.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,cAAc,EACd,KAAK,EACL,gBAAgB,EAChB,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,IAAI,EACJ,mBAAmB,EACnB,OAAO,GACR,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAA;AAM3E,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAcxC,MAAM,SAAS,GAAG,IAAI,CAAA;AAGtB,MAAM,MAAM,GAAG,GAAG,CAAA;AAClB,MAAM,SAAS,GAAG,IAAI,CAAA;AAGtB,MAAM,IAAI,GAAG,IAAI,CAAA;AAGjB,MAAM,KAAK,GAAG,CAAC,GAAG,CAAA;AAGlB,MAAM,IAAI,GAAG,GAAG,CAAA;AAOhB,MAAM,MAAM,GAAG,CAAC,IAAW,EAAS,EAAE;IACpC,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;IAChC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAChB,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;AACnG,CAAC,CAAA;AAyBD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,SAAsB,EACtB,OAAO,GAA8B,EAAE,EACjB,EAAE;IACxB,IAAI,KAAsC,CAAA;IAE1C,IAAI,MAAM,GAAG,KAAK,CAAA;IAElB,IAAI,QAA8E,CAAA;IAClF,IAAI,QAAkC,CAAA;IAEtC,IAAI,IAAI,GAAc,EAAE,CAAA;IAExB,MAAM,aAAa,GAAG,IAAI,mBAAmB,CAAC;QAC5C,aAAa,EAAE,IAAI;QACnB,mBAAmB,EAAE,CAAC;QACtB,kBAAkB,EAAE,CAAC;QACrB,YAAY,EAAE,IAAI;KACnB,CAAC,CAAA;IACF,MAAM,MAAM,GAAG,IAAI,IAAI,CAAiB,IAAI,cAAc,EAAE,EAAE,aAAa,CAAC,CAAA;IAC5E,MAAM,YAAY,GAAG,IAAI,iBAAiB,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAA;IAClE,MAAM,KAAK,GAAG,IAAI,YAAY,CAAiB,IAAI,cAAc,EAAE,EAAE,YAAY,CAAC,CAAA;IAClF,MAAM,YAAY,GAAG,IAAI,mBAAmB,EAAE,CAAA;IAC9C,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,CAAC,CAAA;IAC7D,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;IAEpB,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,EAAE;QACnC,OAAO,EAAE,OAAO,CAAC,OAAO;QAGxB,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;YACZ,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;YAC1C,OAAO,GAAG,EAAE,SAAS,KAAK,SAAS,IAAI,GAAG,CAAC,SAAS,KAAK,IAAI,IAAI,CAAC,KAAK;gBACrE,CAAC,CAAC,CAAC,CAAC;gBACJ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QACtE,CAAC;KACF,CAAC,CAAA;IACF,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAA;IACxD,MAAM,GAAG,GAAG,IAAI,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;IAC7C,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAC1B,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IAG9C,MAAM,OAAO,GAAG,CAAC,QAAwB,EAAE,KAAY,EAAkB,EAAE;QACzE,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,KAAK,CAAA;QACrD,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;QAC1C,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC;YAClC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAA;QACjD,CAAC;QACD,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,sBAAsB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAA;QACrE,OAAO,QAAQ,CAAA;IACjB,CAAC,CAAA;IAED,OAAO;QACL,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;YACrB,KAAK,GAAG,IAAI,CAAA;YACZ,MAAM,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;YACxD,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,CAAA;YAC1D,MAAM,MAAM,GAAqB,EAAE,CAAA;YACnC,MAAM,KAAK,GAAqB,EAAE,CAAA;YAClC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;gBAC3F,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,CAAA;gBAC/C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,CAAA;gBACvD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAA;gBACjD,MAAM,GAAG,GAAG,IAAI,WAAW,CAAC,IAAI,GAAG,SAAS,EAAE,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,CAAA;gBACrE,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;gBACrC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;gBAChC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;gBAC1D,OAAO,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,CAAC,CAAC,CAAA;YACxC,CAAC,CAAC,CAAA;YACF,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAA;YACzB,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAA;YACxB,MAAM,CAAC,QAAQ,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,cAAc,EAAE,CAAA;YACxF,KAAK,CAAC,QAAQ,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,cAAc,EAAE,CAAA;YACrF,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;gBACxC,GAAG,CAAC,OAAO,EAAE,CAAA;YACf,CAAC;YAED,IAAI,CAAC,KAAK,CAAC,GAAG,CACZ,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,EAClC,SAAS,GAAG,IAAI,EAChB,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,CAChC,CAAA;YACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;YACvD,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,CAAA;YAC7D,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;YAKpC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAA;YAC/E,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,CAAA;YAC/C,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,CAAA;YAC5C,MAAM,IAAI,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,CAAA;YACvC,KAAK,CAAC,KAAK,CACT,IAAI,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,EAC3D,IAAI,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,EAChE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAC1C,CAAA;YACD,MAAM,GAAG,IAAI,CAAA;YAIb,QAAQ,EAAE,EAAE,CAAA;YACZ,MAAM,IAAI,GAAG,KAAK,GAAG,SAAS,GAAG,IAAI,CAAA;YACrC,QAAQ,GAAG,KAAK,CAAC,KAAK,CACpB,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,EAAE,IAAI,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,EAC/E,CAAC,EAAE,EAAE,EAAE;gBACL,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAU,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;YAC7E,CAAC,CACF,CAAA;QACH,CAAC;QACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;YACf,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QAC9B,CAAC;QACD,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE;YACtB,QAAQ,GAAG,QAAQ,CAAA;YACnB,OAAO,GAAG,EAAE;gBACV,QAAQ,GAAG,SAAS,CAAA;YACtB,CAAC,CAAA;QACH,CAAC;QACD,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC9C,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC9C,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC9C,IAAI,EAAE,GAAG,EAAE;YACT,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAA;YACzB,aAAa,CAAC,OAAO,EAAE,CAAA;YACvB,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAA;YACxB,YAAY,CAAC,OAAO,EAAE,CAAA;YACtB,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAA;YACvB,YAAY,CAAC,OAAO,EAAE,CAAA;YACtB,KAAK,CAAC,IAAI,EAAE,CAAA;QACd,CAAC;QACD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC;KACnE,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { type ThreeHeatmapDriverOptions, threeHeatmapDriver } from './heatmap-driver.js';
|
|
2
|
+
export { type ThreeScatterDriverOptions, threeScatterDriver } from './scatter-driver.js';
|
|
3
|
+
export { type ThreeSurfaceDriverOptions, threeSurfaceDriver } from './surface-driver.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/three/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxF,OAAO,EAAE,KAAK,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxF,OAAO,EAAE,KAAK,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/three/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkC,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxF,OAAO,EAAkC,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxF,OAAO,EAAkC,kBAAkB,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { SpatialScatterChartDriver } from '../connect-spatial-scatter-chart/connect-spatial-scatter-chart.js';
|
|
2
|
+
/** How the three.js scatter driver behaves where the page does not say. */
|
|
3
|
+
export interface ThreeScatterDriverOptions {
|
|
4
|
+
/**
|
|
5
|
+
* How many pixels the drawing has for each of the page's. By default, on a
|
|
6
|
+
* screen worked with a mouse, half as many again as the screen has, at
|
|
7
|
+
* least two and at most three; on a touch screen, as many as the screen
|
|
8
|
+
* has, at most two.
|
|
9
|
+
*/
|
|
10
|
+
density?: number | undefined;
|
|
11
|
+
/** How large a point is drawn, in CSS pixels, at any distance. 9 by default. */
|
|
12
|
+
pointSize?: number | undefined;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Draws a Spatial Scatter Chart's points in three dimensions with three.js. Pass
|
|
16
|
+
* it to `connectSpatialScatterChart` with the element to draw in, which the chart
|
|
17
|
+
* holds in its plot:
|
|
18
|
+
*
|
|
19
|
+
* ```js
|
|
20
|
+
* import { connectSpatialScatterChart } from '@fusion.dev/helix-plot'
|
|
21
|
+
* import { threeScatterDriver } from '@fusion.dev/helix-plot/three'
|
|
22
|
+
*
|
|
23
|
+
* connectSpatialScatterChart(chart, threeScatterDriver(chart.querySelector('div')))
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* **The points stand in a box**, each axis' range from one side of it to the
|
|
27
|
+
* other, with a grid on its floor and two of its walls at the ticks, and the
|
|
28
|
+
* axes named along its edges. Each group is a color of the theme's series.
|
|
29
|
+
*
|
|
30
|
+
* **Dragging turns the box, and the wheel and a pinch bring it nearer.**
|
|
31
|
+
* Shift with an arrow on the chart turns it a step. It never turns by itself.
|
|
32
|
+
* It draws only while something moves, asks for no frames at rest, and
|
|
33
|
+
* shares the page's WebGL contexts with every three.js drawing Helix makes.
|
|
34
|
+
*
|
|
35
|
+
* The renderer is the driver's own, and `disconnect()` frees it.
|
|
36
|
+
*/
|
|
37
|
+
export declare const threeScatterDriver: (container: HTMLElement, options?: ThreeScatterDriverOptions) => SpatialScatterChartDriver;
|
|
38
|
+
//# sourceMappingURL=scatter-driver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scatter-driver.d.ts","sourceRoot":"","sources":["../../src/three/scatter-driver.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAEV,yBAAyB,EAC1B,MAAM,mEAAmE,CAAA;AAG1E,2EAA2E;AAC3E,MAAM,WAAW,yBAAyB;IACxC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC/B;AAmBD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,kBAAkB,cAClB,WAAW,YACb,yBAAyB,KACjC,yBAsFF,CAAA"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { BufferGeometry, CanvasTexture, Color, Float32BufferAttribute, Points, PointsMaterial, Vector3, } from 'three';
|
|
2
|
+
import { createStage, inBox } from './stage.js';
|
|
3
|
+
const REACH = 0.03;
|
|
4
|
+
const dot = () => {
|
|
5
|
+
const canvas = document.createElement('canvas');
|
|
6
|
+
canvas.width = canvas.height = 64;
|
|
7
|
+
const context = canvas.getContext('2d');
|
|
8
|
+
if (context) {
|
|
9
|
+
context.beginPath();
|
|
10
|
+
context.arc(32, 32, 28, 0, Math.PI * 2);
|
|
11
|
+
context.fillStyle = '#fff';
|
|
12
|
+
context.fill();
|
|
13
|
+
}
|
|
14
|
+
return new CanvasTexture(canvas);
|
|
15
|
+
};
|
|
16
|
+
export const threeScatterDriver = (container, options = {}) => {
|
|
17
|
+
let field;
|
|
18
|
+
const placeOf = (index) => {
|
|
19
|
+
const point = field?.points[index];
|
|
20
|
+
if (!field || !point) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
return new Vector3(inBox(field.axes.x, point.x), inBox(field.axes.y, point.y), inBox(field.axes.z, point.z));
|
|
24
|
+
};
|
|
25
|
+
const pointTexture = dot();
|
|
26
|
+
const pointMaterial = new PointsMaterial({
|
|
27
|
+
alphaTest: 0.5,
|
|
28
|
+
map: pointTexture,
|
|
29
|
+
size: options.pointSize ?? 9,
|
|
30
|
+
sizeAttenuation: false,
|
|
31
|
+
vertexColors: true,
|
|
32
|
+
});
|
|
33
|
+
const points = new Points(new BufferGeometry(), pointMaterial);
|
|
34
|
+
const stage = createStage(container, {
|
|
35
|
+
density: options.density,
|
|
36
|
+
pick: (ray) => {
|
|
37
|
+
ray.params.Points = { threshold: 0.2 };
|
|
38
|
+
let found = -1;
|
|
39
|
+
let nearest = REACH;
|
|
40
|
+
for (const hit of ray.intersectObject(points)) {
|
|
41
|
+
const away = (hit.distanceToRay ?? Number.POSITIVE_INFINITY) / Math.max(hit.distance, 1e-6);
|
|
42
|
+
if (hit.index !== undefined && away < nearest) {
|
|
43
|
+
nearest = away;
|
|
44
|
+
found = hit.index;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return found;
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
stage.scene.add(points);
|
|
51
|
+
return {
|
|
52
|
+
draw: (next, colors, font) => {
|
|
53
|
+
field = next;
|
|
54
|
+
const positions = [];
|
|
55
|
+
const tints = [];
|
|
56
|
+
const tint = new Color();
|
|
57
|
+
next.points.forEach((point, index) => {
|
|
58
|
+
const at = placeOf(index);
|
|
59
|
+
positions.push(at.x, at.y, at.z);
|
|
60
|
+
tint.setStyle(colors.groups[point.groupIndex % colors.groups.length] ?? colors.ink);
|
|
61
|
+
tints.push(tint.r, tint.g, tint.b);
|
|
62
|
+
});
|
|
63
|
+
points.geometry.dispose();
|
|
64
|
+
const geometry = new BufferGeometry();
|
|
65
|
+
geometry.setAttribute('position', new Float32BufferAttribute(positions, 3));
|
|
66
|
+
geometry.setAttribute('color', new Float32BufferAttribute(tints, 3));
|
|
67
|
+
points.geometry = geometry;
|
|
68
|
+
stage.setAxes(next.axes, colors, font);
|
|
69
|
+
},
|
|
70
|
+
focus: (index) => {
|
|
71
|
+
stage.setMarker(placeOf(index));
|
|
72
|
+
},
|
|
73
|
+
onHover: (listener) => stage.onHover(listener),
|
|
74
|
+
onPlace: (listener) => stage.onPlace(listener),
|
|
75
|
+
onPress: (listener) => stage.onPress(listener),
|
|
76
|
+
stop: () => {
|
|
77
|
+
points.geometry.dispose();
|
|
78
|
+
pointMaterial.dispose();
|
|
79
|
+
pointTexture.dispose();
|
|
80
|
+
stage.stop();
|
|
81
|
+
},
|
|
82
|
+
turnBy: (across, up, animate) => stage.turnBy(across, up, animate),
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
//# sourceMappingURL=scatter-driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scatter-driver.js","sourceRoot":"","sources":["../../src/three/scatter-driver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Raycaster, Scene, Vector3 } from 'three';
|
|
2
|
+
import type { Axis, PlotColors } from '../connect-plot/connect-plot.js';
|
|
3
|
+
/** The box's half edge, in three.js's units: what is plotted stands between -1 and 1 on each axis. */
|
|
4
|
+
export declare const HALF = 1;
|
|
5
|
+
/** A number on an axis, written short enough for a tick. */
|
|
6
|
+
export declare const tickText: (value: number) => string;
|
|
7
|
+
/** Where a number stands in the box, from -1 at its axis' low end to 1 at its high end. */
|
|
8
|
+
export declare const inBox: (axis: Axis, value: number) => number;
|
|
9
|
+
/** The plot's three axes: across, up, and in depth. */
|
|
10
|
+
export interface Axes {
|
|
11
|
+
x: Axis;
|
|
12
|
+
y: Axis;
|
|
13
|
+
z: Axis;
|
|
14
|
+
}
|
|
15
|
+
/** What a stage is asked for. */
|
|
16
|
+
export interface StageOptions {
|
|
17
|
+
/** How many pixels the drawing has for each of the page's, as each driver's `density`. */
|
|
18
|
+
density?: number | undefined;
|
|
19
|
+
}
|
|
20
|
+
/** Where a reading is drawn, as fractions of the box the drawing fills, from its top left. */
|
|
21
|
+
export interface Place {
|
|
22
|
+
x: number;
|
|
23
|
+
y: number;
|
|
24
|
+
}
|
|
25
|
+
/** What moved a reading: the kinds of pointer a chart's readings name. */
|
|
26
|
+
export type PointerKind = 'mouse' | 'pen' | 'touch';
|
|
27
|
+
/**
|
|
28
|
+
* The stage a 3D plot is drawn on, in `container`.
|
|
29
|
+
*
|
|
30
|
+
* `pick` is asked which reading a ray through the pointer meets, `-1` for
|
|
31
|
+
* none. `onHover` hears the reading a mouse or a pen rests on, `onPress` a
|
|
32
|
+
* press that did not drag, and `onPlace` where the ringed reading is drawn
|
|
33
|
+
* after each frame, which is where the chart points its tooltip.
|
|
34
|
+
*/
|
|
35
|
+
export declare const createStage: (container: HTMLElement, options: StageOptions & {
|
|
36
|
+
pick: (ray: Raycaster) => number;
|
|
37
|
+
}) => {
|
|
38
|
+
/**
|
|
39
|
+
* Holds the box from `low` to `high` around what is drawn in view, from
|
|
40
|
+
* `toward` where given, a direction from the middle toward the camera, or
|
|
41
|
+
* from where the camera stands. Again on every resize, from wherever the
|
|
42
|
+
* camera stands then.
|
|
43
|
+
*/
|
|
44
|
+
frame: (low: Vector3, high: Vector3, toward?: Vector3) => void;
|
|
45
|
+
invalidate: () => void;
|
|
46
|
+
/** Hears the reading a mouse or a pen rests on, `-1` for none. Returns what stops listening. */
|
|
47
|
+
onHover: (listener: (index: number, kind: PointerKind) => void) => (() => void);
|
|
48
|
+
/** Hears where the ringed reading is drawn after each frame that moves it, or that none is. */
|
|
49
|
+
onPlace: (listener: (at: Place | undefined) => void) => (() => void);
|
|
50
|
+
onPress: (listener: (index: number, kind: PointerKind) => void) => (() => void);
|
|
51
|
+
scene: Scene<import("three").Object3DEventMap>;
|
|
52
|
+
/** Draws the box and its grid for `next` axes, in `nextColors`. */
|
|
53
|
+
setAxes: (next: Axes, nextColors: PlotColors, nextFont: string) => void;
|
|
54
|
+
/** Rings the reading the keys rest on, or none. */
|
|
55
|
+
setMarker: (at: Vector3 | undefined) => void;
|
|
56
|
+
stop: () => void;
|
|
57
|
+
/**
|
|
58
|
+
* Follows `points` in the scene on the page: `heard` is told where each is
|
|
59
|
+
* drawn, as fractions of the box from its top left, after every frame
|
|
60
|
+
* that moves one, and `undefined` while one is behind the camera. Returns
|
|
61
|
+
* what stops following.
|
|
62
|
+
*/
|
|
63
|
+
track: (points: Vector3[], heard: (at: Place[] | undefined) => void) => (() => void);
|
|
64
|
+
turnBy: (across: number, up: number, animate: boolean) => void;
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=stage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stage.d.ts","sourceRoot":"","sources":["../../src/three/stage.ts"],"names":[],"mappings":"AACA,OAAO,EAOL,SAAS,EACT,KAAK,EAKL,OAAO,EAER,MAAM,OAAO,CAAA;AAEd,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAgBvE,sGAAsG;AACtG,eAAO,MAAM,IAAI,IAAI,CAAA;AAKrB,4DAA4D;AAC5D,eAAO,MAAM,QAAQ,UAAW,MAAM,KAAG,MAA8C,CAAA;AAEvF,2FAA2F;AAC3F,eAAO,MAAM,KAAK,SAAU,IAAI,SAAS,MAAM,KAAG,MAGjD,CAAA;AAiBD,uDAAuD;AACvD,MAAM,WAAW,IAAI;IACnB,CAAC,EAAE,IAAI,CAAA;IACP,CAAC,EAAE,IAAI,CAAA;IACP,CAAC,EAAE,IAAI,CAAA;CACR;AAED,iCAAiC;AACjC,MAAM,WAAW,YAAY;IAC3B,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC7B;AAED,8FAA8F;AAC9F,MAAM,WAAW,KAAK;IACpB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV;AAED,0EAA0E;AAC1E,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO,CAAA;AAgCnD;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,cACX,WAAW,WACb,YAAY,GAAG;IACtB,IAAI,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,MAAM,CAAA;CACjC;IAoYC;;;;;OAKG;iBACU,OAAO,QAAQ,OAAO,WAAW,OAAO,KAAG,IAAI;sBAhOvC,IAAI;IAyOzB,gGAAgG;wBAC5E,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC;IAM7E,+FAA+F;wBAC3E,CAAC,EAAE,EAAE,KAAK,GAAG,SAAS,KAAK,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC;wBAO9C,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC;;IAO7E,mEAAmE;oBACnD,IAAI,cAAc,UAAU,YAAY,MAAM,KAAG,IAAI;IAcrE,mDAAmD;oBACnC,OAAO,GAAG,SAAS,KAAG,IAAI;gBAQhC,IAAI;IAqBd;;;;;OAKG;oBACa,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,SAAS,KAAK,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC;qBAOjE,MAAM,MAAM,MAAM,WAAW,OAAO,KAAG,IAAI;CAe/D,CAAA"}
|