@genome-spy/core 0.48.1 → 0.48.2

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.
@@ -12,25 +12,27 @@ export default class Collector extends FlowNode {
12
12
  params: import("../spec/transform.js").CollectParams;
13
13
  /** @type {(function(Collector):void)[]} */
14
14
  observers: ((arg0: Collector) => void)[];
15
- /** @type {Map<any | any[], import("./flowNode.js").Data>} TODO: proper type for key */
16
- facetBatches: Map<any | any[], import("./flowNode.js").Data>;
17
- _init(): void;
18
- /** @type {import("./flowNode.js").Data} */
19
- _data: import("./flowNode.js").Data;
15
+ /** @type {Map<import("../spec/channel.js").Scalar[], Data>} TODO: proper type for key */
16
+ facetBatches: Map<import("../spec/channel.js").Scalar[], import("./flowNode.js").Data>;
20
17
  /**
21
- * @returns {Iterable<import("./flowNode.js").Datum>}
18
+ * @returns {Iterable<Datum>}
22
19
  */
23
20
  getData(): Iterable<import("./flowNode.js").Datum>;
24
21
  /**
25
22
  *
26
- * @param {(datum: import("./flowNode.js").Datum) => void} visitor
23
+ * @param {(datum: Datum) => void} visitor
27
24
  */
28
25
  visitData(visitor: (datum: import("./flowNode.js").Datum) => void): void;
29
26
  /**
30
27
  * Returns the total number of data items collected.
31
28
  */
32
29
  getItemCount(): number;
33
- _checkStatus(): void;
30
+ /**
31
+ * Use an index to find a datum by its unique id.
32
+ *
33
+ * @param {number} uniqueId
34
+ */
35
+ findDatumByUniqueId(uniqueId: number): import("./flowNode.js").Datum;
34
36
  #private;
35
37
  }
36
38
  import FlowNode from "./flowNode.js";
@@ -1 +1 @@
1
- {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../../src/data/collector.js"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH;IAKI;;OAEG;IACH,qBAFW,OAAO,sBAAsB,EAAE,aAAa,EActD;IATG,qDAA2C;IAE3C,2CAA2C;IAC3C,WADW,QAAU,SAAS,KAAE,IAAI,CAAC,EAAE,CACpB;IAEnB,uFAAuF;IACvF,cADW,IAAI,GAAG,GAAG,GAAG,EAAE,EAAE,OAAO,eAAe,EAAE,IAAI,CAAC,CAC5B;IAKjC,cAOC;IANG,2CAA2C;IAC3C,OADW,OAAO,eAAe,EAAE,IAAI,CACxB;IA6GnB;;OAEG;IACH,WAFa,SAAS,OAAO,eAAe,EAAE,KAAK,CAAC,CAuBnD;IAED;;;OAGG;IACH,2BAFmB,OAAO,eAAe,EAAE,KAAK,KAAK,IAAI,QAUxD;IAED;;OAEG;IACH,uBAMC;IAED,qBAMC;;CACJ;qBAzMyD,eAAe"}
1
+ {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../../src/data/collector.js"],"names":[],"mappings":"AAUA;;;;;GAKG;AACH;IA8BI;;OAEG;IACH,qBAFW,OAAO,sBAAsB,EAAE,aAAa,EAetD;IAVG,qDAA2C;IAE3C,2CAA2C;IAC3C,WADW,QAAU,SAAS,KAAE,IAAI,CAAC,EAAE,CACpB;IAGnB,yFAAyF;IACzF,cADW,IAAI,OAAO,oBAAoB,EAAE,MAAM,EAAE,+BAAO,CACN;IAuHzD;;OAEG;IACH,mDAmBC;IAED;;;OAGG;IACH,6DAF6B,IAAI,QAUhC;IAED;;OAEG;IACH,uBAMC;IA8CD;;;;OAIG;IACH,8BAFW,MAAM,iCA4BhB;;CACJ;qBA3SyD,eAAe"}
@@ -1,10 +1,12 @@
1
1
  import { InternMap } from "internmap";
2
- import { group } from "d3-array";
2
+ import { bisector, group } from "d3-array";
3
3
  import { compare } from "vega-util";
4
4
  import iterateNestedMaps from "../utils/iterateNestedMaps.js";
5
5
  import FlowNode, { BEHAVIOR_COLLECTS, isFacetBatch } from "./flowNode.js";
6
6
  import { field } from "../utils/field.js";
7
7
  import { asArray } from "../utils/arrayUtils.js";
8
+ import { radixSortIntoLookupArray } from "../utils/radixSort.js";
9
+ import { UNIQUE_ID_KEY } from "./transforms/identifier.js";
8
10
 
9
11
  /**
10
12
  * Collects (materializes) the data that flows through this node.
@@ -13,6 +15,31 @@ import { asArray } from "../utils/arrayUtils.js";
13
15
  * Grouping is primarily intended for handling faceted data.
14
16
  */
15
17
  export default class Collector extends FlowNode {
18
+ /**
19
+ * @typedef {import("./flowNode.js").Datum} Datum
20
+ * @typedef {import("./flowNode.js").Data} Data
21
+ */
22
+
23
+ /**
24
+ * Current batch that is being collected.
25
+ * @type {Data}
26
+ */
27
+ #buffer = [];
28
+
29
+ #uniqueIdAccessor = field(UNIQUE_ID_KEY);
30
+
31
+ /**
32
+ * @type {number[]}
33
+ */
34
+ #uniqueIdIndex = [];
35
+
36
+ /**
37
+ * Start and end indices of all facets if they are concatenated into a single array.
38
+ * Used together with the uniqueIdIndex for looking up data items by their unique id.
39
+ * @type {{start: number, stop: number, facetId: import("../spec/channel.js").Scalar[]}[]}
40
+ */
41
+ #facetIndices;
42
+
16
43
  get behavior() {
17
44
  return BEHAVIOR_COLLECTS;
18
45
  }
@@ -28,32 +55,30 @@ export default class Collector extends FlowNode {
28
55
  /** @type {(function(Collector):void)[]} */
29
56
  this.observers = [];
30
57
 
31
- /** @type {Map<any | any[], import("./flowNode.js").Data>} TODO: proper type for key */
32
- this.facetBatches = undefined;
58
+ // TODO: Consider nested maps instead of InternMap
59
+ /** @type {Map<import("../spec/channel.js").Scalar[], Data>} TODO: proper type for key */
60
+ this.facetBatches = new InternMap([], JSON.stringify);
33
61
 
34
- this._init();
62
+ this.#init();
35
63
  }
36
64
 
37
- _init() {
38
- /** @type {import("./flowNode.js").Data} */
39
- this._data = [];
65
+ #init() {
66
+ this.#buffer = [];
40
67
 
41
- // TODO: Consider nested maps
42
- this.facetBatches = new InternMap([], JSON.stringify);
43
- this.facetBatches.set(undefined, this._data);
68
+ this.facetBatches.clear();
69
+ this.facetBatches.set(undefined, this.#buffer);
44
70
  }
45
71
 
46
72
  reset() {
47
73
  super.reset();
48
- this._init();
74
+ this.#init();
49
75
  }
50
76
 
51
77
  /**
52
- *
53
- * @param {import("./flowNode.js").Datum} datum
78
+ * @param {Datum} datum
54
79
  */
55
80
  handle(datum) {
56
- this._data.push(datum);
81
+ this.#buffer.push(datum);
57
82
  }
58
83
 
59
84
  /**
@@ -61,12 +86,15 @@ export default class Collector extends FlowNode {
61
86
  */
62
87
  beginBatch(flowBatch) {
63
88
  if (isFacetBatch(flowBatch)) {
64
- this._data = [];
65
- this.facetBatches.set(asArray(flowBatch.facetId), this._data);
89
+ this.#buffer = [];
90
+ this.facetBatches.set(asArray(flowBatch.facetId), this.#buffer);
66
91
  }
67
92
  }
68
93
 
69
94
  complete() {
95
+ // Free some memory
96
+ this.#buffer = [];
97
+
70
98
  const sort = this.params?.sort;
71
99
  // Vega's "compare" function is incredibly slow (uses megamorphic field accessor)
72
100
  // TODO: Implement a replacement for static data types
@@ -84,6 +112,8 @@ export default class Collector extends FlowNode {
84
112
  throw new Error("TODO: Support faceted data!");
85
113
  }
86
114
 
115
+ const data = this.facetBatches.get(undefined);
116
+
87
117
  const accessors = this.params.groupby.map((fieldName) =>
88
118
  field(fieldName)
89
119
  );
@@ -91,10 +121,10 @@ export default class Collector extends FlowNode {
91
121
  accessors.length > 1
92
122
  ? // There's something strange in d3-array's typings
93
123
  /** @type {Map<any, any>} */ /** @type {any} */ (
94
- group(this._data, ...accessors)
124
+ group(data, ...accessors)
95
125
  )
96
126
  : // D3's group is SLOW!
97
- groupBy(this._data, accessors[0]);
127
+ groupBy(data, accessors[0]);
98
128
 
99
129
  this.facetBatches.clear();
100
130
  for (const [key, data] of iterateNestedMaps(groups)) {
@@ -107,6 +137,7 @@ export default class Collector extends FlowNode {
107
137
  sortData(data);
108
138
  }
109
139
 
140
+ this.#buildUniqueIdIndex();
110
141
  this.#propagateToChildren();
111
142
 
112
143
  super.complete();
@@ -118,16 +149,16 @@ export default class Collector extends FlowNode {
118
149
 
119
150
  #propagateToChildren() {
120
151
  if (this.children.length) {
121
- for (const [key, data] of this.facetBatches.entries()) {
122
- if (key) {
152
+ for (const [facetId, data] of this.facetBatches.entries()) {
153
+ if (facetId) {
123
154
  /** @type {import("../types/flowBatch.js").FacetBatch} */
124
- const facetBatch = { type: "facet", facetId: key };
155
+ const facetBatch = { type: "facet", facetId };
125
156
  for (const child of this.children) {
126
157
  child.beginBatch(facetBatch);
127
158
  }
128
159
  }
129
- for (const datum of data) {
130
- this._propagate(datum);
160
+ for (let i = 0, n = data.length; i < n; i++) {
161
+ this._propagate(data[i]);
131
162
  }
132
163
  }
133
164
  }
@@ -146,10 +177,10 @@ export default class Collector extends FlowNode {
146
177
  }
147
178
 
148
179
  /**
149
- * @returns {Iterable<import("./flowNode.js").Datum>}
180
+ * @returns {Iterable<Datum>}
150
181
  */
151
182
  getData() {
152
- this._checkStatus();
183
+ this.#checkStatus();
153
184
 
154
185
  switch (this.facetBatches.size) {
155
186
  case 0:
@@ -161,9 +192,7 @@ export default class Collector extends FlowNode {
161
192
  return {
162
193
  [Symbol.iterator]: function* generator() {
163
194
  for (const data of groups.values()) {
164
- for (let i = 0; i < data.length; i++) {
165
- yield data[i];
166
- }
195
+ yield* data;
167
196
  }
168
197
  },
169
198
  };
@@ -173,10 +202,10 @@ export default class Collector extends FlowNode {
173
202
 
174
203
  /**
175
204
  *
176
- * @param {(datum: import("./flowNode.js").Datum) => void} visitor
205
+ * @param {(datum: Datum) => void} visitor
177
206
  */
178
207
  visitData(visitor) {
179
- this._checkStatus();
208
+ this.#checkStatus();
180
209
 
181
210
  for (const data of this.facetBatches.values()) {
182
211
  for (let i = 0; i < data.length; i++) {
@@ -196,21 +225,90 @@ export default class Collector extends FlowNode {
196
225
  return count;
197
226
  }
198
227
 
199
- _checkStatus() {
228
+ #checkStatus() {
200
229
  if (!this.completed) {
201
230
  throw new Error(
202
231
  "Data propagation is not completed! No data are available."
203
232
  );
204
233
  }
205
234
  }
235
+
236
+ /**
237
+ * Builds an index for looking up data items by their unique id.
238
+ * Using a sorted index and binary search for O(log n) complexity.
239
+ */
240
+ #buildUniqueIdIndex() {
241
+ this.#facetIndices = [];
242
+
243
+ /** @type {Datum} */
244
+ const obj = this.facetBatches.values().next().value?.[0];
245
+ if (obj == null || !(UNIQUE_ID_KEY in obj)) {
246
+ return; // No unique ids in the data
247
+ }
248
+
249
+ let cumulativePos = 0;
250
+
251
+ /** @type {number[]} */
252
+ const ids = [];
253
+
254
+ const a = this.#uniqueIdAccessor;
255
+
256
+ for (const [facetId, data] of this.facetBatches) {
257
+ this.#facetIndices.push({
258
+ start: cumulativePos,
259
+ stop: cumulativePos + data.length,
260
+ facetId,
261
+ });
262
+ cumulativePos += data.length;
263
+
264
+ for (let i = 0, n = data.length; i < n; i++) {
265
+ ids.push(a(data[i]));
266
+ }
267
+ }
268
+
269
+ this.#uniqueIdIndex = radixSortIntoLookupArray(ids);
270
+ }
271
+
272
+ /**
273
+ * Use an index to find a datum by its unique id.
274
+ *
275
+ * @param {number} uniqueId
276
+ */
277
+ findDatumByUniqueId(uniqueId) {
278
+ if (!this.#uniqueIdIndex.length) {
279
+ return;
280
+ }
281
+
282
+ const facetBisector = bisector((f) => f.start).right;
283
+ const a = this.#uniqueIdAccessor;
284
+ const indexBisector = bisector((i) => a(getDatum(i))).left;
285
+
286
+ const getDatum = (/** @type {number} */ i) => {
287
+ const fi = facetBisector(this.#facetIndices, i);
288
+ const facet = this.#facetIndices[fi - 1];
289
+ if (!facet || i >= facet.stop) {
290
+ return;
291
+ }
292
+ const data = this.facetBatches.get(facet.facetId);
293
+ return data[i - facet.start];
294
+ };
295
+
296
+ const index = indexBisector(this.#uniqueIdIndex, uniqueId);
297
+ if (index >= 0) {
298
+ const datum = getDatum(this.#uniqueIdIndex[index]);
299
+ if (datum && a(datum) === uniqueId) {
300
+ return datum;
301
+ }
302
+ }
303
+ }
206
304
  }
207
305
 
208
306
  /**
209
307
  * Like D3's group but without InternMap, which is slow.
210
308
  * TODO: Implement multi-level grouping
211
309
  *
212
- * @param {import("./flowNode.js").Datum[]} data
213
- * @param {(data: import("./flowNode.js").Datum) => import("../spec/channel.js").Scalar} accessor
310
+ * @param {Datum[]} data
311
+ * @param {(data: Datum) => import("../spec/channel.js").Scalar} accessor
214
312
  */
215
313
  function groupBy(data, accessor) {
216
314
  const groups = new Map();
@@ -1,6 +1,7 @@
1
- import { expect, test } from "vitest";
1
+ import { describe, expect, test } from "vitest";
2
2
 
3
3
  import Collector from "./collector.js";
4
+ import { UNIQUE_ID_KEY } from "./transforms/identifier.js";
4
5
 
5
6
  const data = [1, 5, 2, 4, 3].map((x) => ({ x }));
6
7
 
@@ -82,3 +83,56 @@ test("Collector throws on incomplete flow", () => {
82
83
 
83
84
  expect(() => collector.getData()).toThrow();
84
85
  });
86
+
87
+ describe("Indexing unique ids", () => {
88
+ test("Collector builds a working index when ids are available", () => {
89
+ const collector = new Collector({
90
+ type: "collect",
91
+ groupby: ["a"],
92
+ });
93
+
94
+ const data = [
95
+ { a: 1, x: 1, [UNIQUE_ID_KEY]: 8 },
96
+ { a: 1, x: 2, [UNIQUE_ID_KEY]: 2 },
97
+ { a: 1, x: 3, [UNIQUE_ID_KEY]: 4 },
98
+ { a: 1, x: 4, [UNIQUE_ID_KEY]: 6 },
99
+ { a: 2, x: 5, [UNIQUE_ID_KEY]: 9 },
100
+ { a: 2, x: 6, [UNIQUE_ID_KEY]: 7 },
101
+ { a: 2, x: 7, [UNIQUE_ID_KEY]: 3 },
102
+ { a: 2, x: 8, [UNIQUE_ID_KEY]: 1 },
103
+ ];
104
+
105
+ for (const d of data) {
106
+ collector.handle(d);
107
+ }
108
+ collector.complete();
109
+
110
+ expect(collector.findDatumByUniqueId(8)).toEqual(data[0]);
111
+ expect(collector.findDatumByUniqueId(2)).toEqual(data[1]);
112
+ expect(collector.findDatumByUniqueId(4)).toEqual(data[2]);
113
+ expect(collector.findDatumByUniqueId(6)).toEqual(data[3]);
114
+ expect(collector.findDatumByUniqueId(9)).toEqual(data[4]);
115
+ expect(collector.findDatumByUniqueId(7)).toEqual(data[5]);
116
+ expect(collector.findDatumByUniqueId(3)).toEqual(data[6]);
117
+ expect(collector.findDatumByUniqueId(1)).toEqual(data[7]);
118
+ });
119
+
120
+ test("Collector returns undefined when ids are not available", () => {
121
+ const collector = new Collector({
122
+ type: "collect",
123
+ groupby: ["a"],
124
+ });
125
+
126
+ const data = [
127
+ { a: 1, x: 1 },
128
+ { a: 2, x: 5 },
129
+ ];
130
+
131
+ for (const d of data) {
132
+ collector.handle(d);
133
+ }
134
+ collector.complete();
135
+
136
+ expect(collector.findDatumByUniqueId(0)).toBeUndefined();
137
+ });
138
+ });
@@ -1,4 +1,4 @@
1
- export const DEFAULT_AS: "_uniqueId";
1
+ export const UNIQUE_ID_KEY: "_uniqueId";
2
2
  export const BLOCK_SIZE: 10000;
3
3
  /**
4
4
  * Assigns unique identifiers for tuples that pass through this transform.
@@ -1 +1 @@
1
- {"version":3,"file":"identifier.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/identifier.js"],"names":[],"mappings":"AAEA,qCAAsC;AAEtC,+BAAgC;AAehC;;;;;;;GAOG;AACH;IAKI;;;OAGG;IACH,oBAFW,OAAO,yBAAyB,EAAE,gBAAgB,EAuB5D;IAnBG,2DAAoB;IAEpB,WAAiC;IAEjC;;;OAGG;IACH,SAFU,MAAM,EAAE,CAED;IAEjB;;OAEG;IACH,oBAAoB;IAEpB;;OAEG;IACH,YAAa;IAuBjB;;OAEG;IACH,WAFa,MAAM,CAOlB;IAED,oBAMC;IAED,wBAOC;CACJ;qBAzG2C,gBAAgB"}
1
+ {"version":3,"file":"identifier.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/identifier.js"],"names":[],"mappings":"AAEA,wCAAyC;AAEzC,+BAAgC;AAehC;;;;;;;GAOG;AACH;IAKI;;;OAGG;IACH,oBAFW,OAAO,yBAAyB,EAAE,gBAAgB,EAuB5D;IAnBG,2DAAoB;IAEpB,WAAoC;IAEpC;;;OAGG;IACH,SAFU,MAAM,EAAE,CAED;IAEjB;;OAEG;IACH,oBAAoB;IAEpB;;OAEG;IACH,YAAa;IAuBjB;;OAEG;IACH,WAFa,MAAM,CAOlB;IAED,oBAMC;IAED,wBAOC;CACJ;qBAzG2C,gBAAgB"}
@@ -1,6 +1,6 @@
1
1
  import FlowNode, { BEHAVIOR_MODIFIES } from "../flowNode.js";
2
2
 
3
- export const DEFAULT_AS = "_uniqueId";
3
+ export const UNIQUE_ID_KEY = "_uniqueId";
4
4
 
5
5
  export const BLOCK_SIZE = 10000;
6
6
 
@@ -38,7 +38,7 @@ export default class IdentifierTransform extends FlowNode {
38
38
  super();
39
39
  this.params = params;
40
40
 
41
- this.as = params.as ?? DEFAULT_AS;
41
+ this.as = params.as ?? UNIQUE_ID_KEY;
42
42
 
43
43
  /**
44
44
  * The block indexes reserved by this transform instance.
@@ -1,7 +1,10 @@
1
1
  import { expect, test } from "vitest";
2
2
  import { range } from "d3-array";
3
3
  import { processData } from "../flowTestUtils.js";
4
- import IdentifierTransform, { BLOCK_SIZE, DEFAULT_AS } from "./identifier.js";
4
+ import IdentifierTransform, {
5
+ BLOCK_SIZE,
6
+ UNIQUE_ID_KEY,
7
+ } from "./identifier.js";
5
8
 
6
9
  test("An IdentifierTransform adds identifiers correctly", () => {
7
10
  const data = range(BLOCK_SIZE * 2).map((x) => ({ data: x }));
@@ -14,15 +17,18 @@ test("An IdentifierTransform adds identifiers correctly", () => {
14
17
  // The fist block is skipped
15
18
  const firstId = BLOCK_SIZE;
16
19
 
17
- expect(identifiedData[0]).toEqual({ data: 0, [DEFAULT_AS]: firstId });
18
- expect(identifiedData[1]).toEqual({ data: 1, [DEFAULT_AS]: firstId + 1 });
20
+ expect(identifiedData[0]).toEqual({ data: 0, [UNIQUE_ID_KEY]: firstId });
21
+ expect(identifiedData[1]).toEqual({
22
+ data: 1,
23
+ [UNIQUE_ID_KEY]: firstId + 1,
24
+ });
19
25
  expect(identifiedData[BLOCK_SIZE]).toEqual({
20
26
  data: BLOCK_SIZE,
21
- [DEFAULT_AS]: firstId + BLOCK_SIZE,
27
+ [UNIQUE_ID_KEY]: firstId + BLOCK_SIZE,
22
28
  });
23
29
  expect(identifiedData[BLOCK_SIZE + 1]).toEqual({
24
30
  data: BLOCK_SIZE + 1,
25
- [DEFAULT_AS]: firstId + BLOCK_SIZE + 1,
31
+ [UNIQUE_ID_KEY]: firstId + BLOCK_SIZE + 1,
26
32
  });
27
33
  });
28
34
 
@@ -37,15 +43,18 @@ test("Another transform instance adds identifiers correctly", () => {
37
43
  // The fist block was skipped and the previous test case consumed two blocks
38
44
  const firstId = BLOCK_SIZE * 3;
39
45
 
40
- expect(identifiedData[0]).toEqual({ data: 0, [DEFAULT_AS]: firstId });
41
- expect(identifiedData[1]).toEqual({ data: 1, [DEFAULT_AS]: firstId + 1 });
46
+ expect(identifiedData[0]).toEqual({ data: 0, [UNIQUE_ID_KEY]: firstId });
47
+ expect(identifiedData[1]).toEqual({
48
+ data: 1,
49
+ [UNIQUE_ID_KEY]: firstId + 1,
50
+ });
42
51
  expect(identifiedData[BLOCK_SIZE]).toEqual({
43
52
  data: BLOCK_SIZE,
44
- [DEFAULT_AS]: firstId + BLOCK_SIZE,
53
+ [UNIQUE_ID_KEY]: firstId + BLOCK_SIZE,
45
54
  });
46
55
  expect(identifiedData[BLOCK_SIZE + 1]).toEqual({
47
56
  data: BLOCK_SIZE + 1,
48
- [DEFAULT_AS]: firstId + BLOCK_SIZE + 1,
57
+ [UNIQUE_ID_KEY]: firstId + BLOCK_SIZE + 1,
49
58
  });
50
59
  });
51
60
 
@@ -57,10 +66,10 @@ test("IdentifierTransform recycles allocated blocks", () => {
57
66
 
58
67
  let firstId = BLOCK_SIZE * 5;
59
68
 
60
- expect(identifiedData[0]).toEqual({ data: 0, [DEFAULT_AS]: firstId });
69
+ expect(identifiedData[0]).toEqual({ data: 0, [UNIQUE_ID_KEY]: firstId });
61
70
  expect(identifiedData[BLOCK_SIZE]).toEqual({
62
71
  data: BLOCK_SIZE,
63
- [DEFAULT_AS]: firstId + BLOCK_SIZE,
72
+ [UNIQUE_ID_KEY]: firstId + BLOCK_SIZE,
64
73
  });
65
74
 
66
75
  data = range(BLOCK_SIZE * 3).map((x) => ({ data: x }));
@@ -69,15 +78,15 @@ test("IdentifierTransform recycles allocated blocks", () => {
69
78
  transform.reset();
70
79
  identifiedData = processData(transform, data);
71
80
 
72
- expect(identifiedData[0]).toEqual({ data: 0, [DEFAULT_AS]: firstId });
81
+ expect(identifiedData[0]).toEqual({ data: 0, [UNIQUE_ID_KEY]: firstId });
73
82
  expect(identifiedData[BLOCK_SIZE]).toEqual({
74
83
  data: BLOCK_SIZE,
75
- [DEFAULT_AS]: firstId + BLOCK_SIZE,
84
+ [UNIQUE_ID_KEY]: firstId + BLOCK_SIZE,
76
85
  });
77
86
 
78
87
  // ... and reserve one extra
79
88
  expect(identifiedData[BLOCK_SIZE * 2]).toEqual({
80
89
  data: BLOCK_SIZE * 2,
81
- [DEFAULT_AS]: firstId + BLOCK_SIZE * 2,
90
+ [UNIQUE_ID_KEY]: firstId + BLOCK_SIZE * 2,
82
91
  });
83
92
  });
@@ -1 +1 @@
1
- {"version":3,"file":"genomeSpy.d.ts","sourceRoot":"","sources":["../../src/genomeSpy.js"],"names":[],"mappings":"AA+CA;IACI;;;;;OAKG;IAEH;;;;;OAKG;IACH,uBAJW,WAAW,qDAEX,OAAO,qBAAqB,EAAE,YAAY,EA2FpD;IAxFG,uBAA0B;IAC1B,oDAAsB;IAItB,6BAA6B;IAC7B,uBADW,CAAC,MAAM,IAAI,CAAC,EAAE,CACM;IAE/B,sCAAsC;IACtC,wCAAgB;IAEhB,iCAA4C;IAC5C,yBAAoC;IAEpC,4CAA4C;IAC5C,oBADW,QAAU,MAAM,KAAE,MAAM,EAAE,CAAC,EAAE,CACZ;IAE5B,mBAAoD;IAEpD,0BAA0B;IAC1B,aADW,WAAW,CACM;IAE5B;;;;;OAKG;IACH,qEAF0B,OAAO,CAE8B;IAE/D,2CAA2C;IAC3C,mBADW,4BAA4B,CACL;IAClC,2CAA2C;IAC3C,iBADW,4BAA4B,CACP;IAEhC,oDAAoD;IACpD,6BAAgC;IAEhC;;;OAGG;IACH,eAFU;QAAE,IAAI,EAAE,OAAO,iBAAiB,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,oBAAoB,EAAE,KAAK,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAEpF;IAE9B,uBAA+C;IAE/C;;;OAGG;IACH,oBAFU,IAAI,MAAM,EAAE,QAAU,aAAa,KAAE,IAAI,CAAC,EAAE,CAAC,CAEpB;IAEnC;;;;;;OAMG;IACH,yCAFkC,GAAG,KAAK,IAAI,GAEd;IAEhC;;;OAGG;IACH,kDAFkC,GAAG,KAAK,IAAI,GAEL;IAEzC,oFAAoF;IACpF,iBADW,OAAO,MAAM,EAAE,OAAO,6BAA6B,EAAE,cAAc,CAAC,CAK9E;IAED,mBAAmB;IACnB,2CAAyB;IAEzB;;;;OAIG;IACH;gBAF8B,OAAO,wBAAwB,EAAE,iBAAiB;iBAAW,MAAM;OAEnE;IAE9B;;OAEG;IACH,wBAFU,WAAW,CAEkB;IA2C3C;;;OAGG;IACH,2CAFkB,MAAM,KAAK,GAAG,EAAE,QAIjC;IAED;;OAEG;IACH,+BAFW,MAAM,YAShB;IAED;;;;OAIG;IACH,sBAHW,MAAM,QACN,GAAG,EAAE,QAaf;IAED;;;;;OAKG;IACH,gBAHW,kBAAkB,YAClB,GAAG,QAQb;IAED;;;OAGG;IACH,iCAqDC;IA0DG,uBAQC;IAGD,mCAGE;IAOF,sCAEE;IAGF,iBAAyC;IAW7C;;OAEG;IACH,gBAuBC;IAED,sCA8MC;IAED;;;OAGG;IACH,UAFa,QAAQ,OAAO,CAAC,CA6B5B;IAED,4BAqJC;IA9He,iCAAoC;IAgIpD;;;OAGG;IACH,kBAHW,MAAM,KACN,MAAM,QAsEhB;IAED;;;;;;;OAOG;IACH,oDAHuB,QAAQ,MAAM,GAAG,WAAW,GAAG,OAAO,KAAK,EAAE,cAAc,CAAC,QAYlF;IAED,sBA6CC;IAED,kBAIC;IAED,iCAOC;IAED,iCASC;IAED,qFAWC;;CACJ;;;;iCAx7BY,eAAe,GAAG,YAAY,GAAG,QAAQ,GAAG,gBAAgB;4BAlC7C,uBAAuB;4BA2BP,uBAAuB;qBAZ9C,qBAAqB;wBAIlB,yBAAyB;yCARR,yDAAyD;oBAYvD,oBAAoB;wBAdvC,qBAAqB;oBAXzB,uBAAuB;qBAStB,oBAAoB"}
1
+ {"version":3,"file":"genomeSpy.d.ts","sourceRoot":"","sources":["../../src/genomeSpy.js"],"names":[],"mappings":"AA+CA;IACI;;;;;OAKG;IAEH;;;;;OAKG;IACH,uBAJW,WAAW,qDAEX,OAAO,qBAAqB,EAAE,YAAY,EA2FpD;IAxFG,uBAA0B;IAC1B,oDAAsB;IAItB,6BAA6B;IAC7B,uBADW,CAAC,MAAM,IAAI,CAAC,EAAE,CACM;IAE/B,sCAAsC;IACtC,wCAAgB;IAEhB,iCAA4C;IAC5C,yBAAoC;IAEpC,4CAA4C;IAC5C,oBADW,QAAU,MAAM,KAAE,MAAM,EAAE,CAAC,EAAE,CACZ;IAE5B,mBAAoD;IAEpD,0BAA0B;IAC1B,aADW,WAAW,CACM;IAE5B;;;;;OAKG;IACH,qEAF0B,OAAO,CAE8B;IAE/D,2CAA2C;IAC3C,mBADW,4BAA4B,CACL;IAClC,2CAA2C;IAC3C,iBADW,4BAA4B,CACP;IAEhC,oDAAoD;IACpD,6BAAgC;IAEhC;;;OAGG;IACH,eAFU;QAAE,IAAI,EAAE,OAAO,iBAAiB,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,oBAAoB,EAAE,KAAK,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAEpF;IAE9B,uBAA+C;IAE/C;;;OAGG;IACH,oBAFU,IAAI,MAAM,EAAE,QAAU,aAAa,KAAE,IAAI,CAAC,EAAE,CAAC,CAEpB;IAEnC;;;;;;OAMG;IACH,yCAFkC,GAAG,KAAK,IAAI,GAEd;IAEhC;;;OAGG;IACH,kDAFkC,GAAG,KAAK,IAAI,GAEL;IAEzC,oFAAoF;IACpF,iBADW,OAAO,MAAM,EAAE,OAAO,6BAA6B,EAAE,cAAc,CAAC,CAK9E;IAED,mBAAmB;IACnB,2CAAyB;IAEzB;;;;OAIG;IACH;gBAF8B,OAAO,wBAAwB,EAAE,iBAAiB;iBAAW,MAAM;OAEnE;IAE9B;;OAEG;IACH,wBAFU,WAAW,CAEkB;IA2C3C;;;OAGG;IACH,2CAFkB,MAAM,KAAK,GAAG,EAAE,QAIjC;IAED;;OAEG;IACH,+BAFW,MAAM,YAShB;IAED;;;;OAIG;IACH,sBAHW,MAAM,QACN,GAAG,EAAE,QAaf;IAED;;;;;OAKG;IACH,gBAHW,kBAAkB,YAClB,GAAG,QAQb;IAED;;;OAGG;IACH,iCAqDC;IA0DG,uBAQC;IAGD,mCAGE;IAOF,sCAEE;IAGF,iBAAyC;IAW7C;;OAEG;IACH,gBAuBC;IAED,sCA8MC;IAED;;;OAGG;IACH,UAFa,QAAQ,OAAO,CAAC,CA6B5B;IAED,4BAqJC;IA9He,iCAAoC;IAgIpD;;;OAGG;IACH,kBAHW,MAAM,KACN,MAAM,QAqEhB;IAED;;;;;;;OAOG;IACH,oDAHuB,QAAQ,MAAM,GAAG,WAAW,GAAG,OAAO,KAAK,EAAE,cAAc,CAAC,QAYlF;IAED,sBA6CC;IAED,kBAIC;IAED,iCAOC;IAED,iCASC;IAED,qFAWC;;CACJ;;;;iCAv7BY,eAAe,GAAG,YAAY,GAAG,QAAQ,GAAG,gBAAgB;4BAlC7C,uBAAuB;4BA2BP,uBAAuB;qBAZ9C,qBAAqB;wBAIlB,yBAAyB;yCARR,yDAAyD;oBAYvD,oBAAoB;wBAdvC,qBAAqB;oBAXzB,uBAAuB;qBAStB,oBAAoB"}
@@ -822,7 +822,10 @@ export default class GenomeSpy {
822
822
  const pixelValue = this._glHelper.readPickingPixel(x, y);
823
823
 
824
824
  const uniqueId =
825
- pixelValue[0] | (pixelValue[1] << 8) | (pixelValue[2] << 16);
825
+ pixelValue[0] |
826
+ (pixelValue[1] << 8) |
827
+ (pixelValue[2] << 16) |
828
+ (pixelValue[3] << 24);
826
829
 
827
830
  if (uniqueId == 0) {
828
831
  this._currentHover = null;
@@ -834,10 +837,6 @@ export default class GenomeSpy {
834
837
  }
835
838
 
836
839
  if (!this._currentHover) {
837
- // We are doing an exhaustive search of the data. This is a bit slow with
838
- // millions of items.
839
- // TODO: Optimize by indexing or something
840
-
841
840
  this.viewRoot.visit((view) => {
842
841
  if (view instanceof UnitView) {
843
842
  if (
@@ -846,16 +845,16 @@ export default class GenomeSpy {
846
845
  coords.containsPoint(x, y)
847
846
  )
848
847
  ) {
849
- const accessor = view.mark.encoders.uniqueId.accessor;
850
- view.getCollector().visitData((d) => {
851
- if (accessor(d) == uniqueId) {
852
- this._currentHover = {
853
- mark: view.mark,
854
- datum: d,
855
- uniqueId,
856
- };
857
- }
858
- });
848
+ const datum = view
849
+ .getCollector()
850
+ .findDatumByUniqueId(uniqueId);
851
+ if (datum) {
852
+ this._currentHover = {
853
+ mark: view.mark,
854
+ datum,
855
+ uniqueId,
856
+ };
857
+ }
859
858
  }
860
859
  if (this._currentHover) {
861
860
  return VISIT_STOP;
@@ -60,7 +60,7 @@ export class GeometryBuilder {
60
60
  addToXIndex(datum: import("../data/flowNode.js").Datum): void;
61
61
  xIndexer: {
62
62
  (datum: any, startVertexIndex: number, endVertexIndex: number): void;
63
- getIndex: () => import("../utils/binnedIndex.js").Lookup;
63
+ getIndex: () => import("../utils/binnedIndex.js").Lookup; /** @param {Encoder} encoder */
64
64
  };
65
65
  toArrays(): {
66
66
  /** @type {Record<string, {data: Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array, numComponents: number, divisor?: number}>} */
@@ -1 +1 @@
1
- {"version":3,"file":"dataToVertices.d.ts","sourceRoot":"","sources":["../../../src/gl/dataToVertices.js"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH;IACI;;;OAGG;IAEH;;;;;;OAMG;IACH;;qBAJW,MAAM,EAAE;sBACR,MAAM;OA6EhB;IAzEG,gEAAwB;IAGxB;;MAKC;IAQD,0BAAoC;IAEpC,8BAAoD;IAmDpD,mBAAmB;IAEnB,yFAAyF;IACzF,UADW,IAAI,GAAG,EAAE,UAAU,CAAC,CACkB;IAGrD;;;;OAIG;IACH,mBAFW,GAAG,QAcb;IAED;;OAEG;IACH,oBAFW,IAAI,GAAG,EAAE,MAAM,EAAE,CAAC,QAM5B;IAED;;;OAGG;IACH,cAHW,GAAG,QACH,MAAM,EAAE,kCAYlB;IAED;;;;OAIG;IACH,sBAJW,OAAO,qBAAqB,EAAE,IAAI,OAClC,MAAM,OACN,MAAM,QA+DhB;IAED;;;;;OAKG;IACH,mBAFW,OAAO,qBAAqB,EAAE,KAAK,QAI7C;IA/DO;;;MAAyB;IAiEjC;QAEQ,kJAAkJ;gBAAvI,OAAO,MAAM,EAAE;YAAC,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,CAAC;YAAC,aAAa,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAC,CAAC;QAE9I,8BAA8B;;QAE9B,8CAA8C;;;MAIrD;CACJ;AAED;IACI;;;;;;OAMG;IACH;;oBAHW,MAAM,EAAE;mBACR,MAAM;OA+BhB;IAnBG,qBAkBW;CA8BlB;AAED;IACI;;;;;;;;;OASG;IACH;;oBANW,MAAM,EAAE;gCACR,MAAM;uBAEN,MAAM,EAAE;mBACR,MAAM;OAwBhB;IARG,uBAAgC;IAEhC,8BAA8D;IAE9D,6CAA+D;IAC/D,4CAA6D;CA6CpE;AAED;IACI;;;;;;OAMG;IACH;;oBAHW,MAAM,EAAE;mBACR,MAAM;OAShB;CACJ;AAED;IACI;;;;;OAKG;IACH;;oBAHW,MAAM,EAAE;mBACR,MAAM;OAShB;CAYJ;AAED;IACI;;;;;;;;;OASG;IACH;;oBANW,MAAM,EAAE;qBACR,OAAO,2BAA2B,EAAE,aAAa;oBACjD,OAAO,MAAM,EAAE,GAAG,CAAC;wBACnB,MAAM;sBACN,OAAO;OA8CjB;IA/BG,4DAA2B;IAC3B,2DAA0B;IAE1B,gCAA4B;IAQ5B,qCAAqC;IACrC,sBADmB,GAAG,KAAK,MAAM,CAMf;IAElB,oDAGC;IACD,qDAGC;IAED,8CAAiE;CAgJxE;;;;;;;;YAvmBS,MAAM;;;;WACN,MAAM;YACN,OAAO,yBAAyB,EAAE,MAAM;;yBAjBzB,mBAAmB"}
1
+ {"version":3,"file":"dataToVertices.d.ts","sourceRoot":"","sources":["../../../src/gl/dataToVertices.js"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH;IACI;;;OAGG;IAEH;;;;;;OAMG;IACH;;qBAJW,MAAM,EAAE;sBACR,MAAM;OAgFhB;IA5EG,gEAAwB;IAGxB;;MAKC;IAQD,0BAAoC;IAEpC,8BAAoD;IAsDpD,mBAAmB;IAEnB,yFAAyF;IACzF,UADW,IAAI,GAAG,EAAE,UAAU,CAAC,CACkB;IAGrD;;;;OAIG;IACH,mBAFW,GAAG,QAcb;IAED;;OAEG;IACH,oBAFW,IAAI,GAAG,EAAE,MAAM,EAAE,CAAC,QAM5B;IAED;;;OAGG;IACH,cAHW,GAAG,QACH,MAAM,EAAE,kCAYlB;IAED;;;;OAIG;IACH,sBAJW,OAAO,qBAAqB,EAAE,IAAI,OAClC,MAAM,OACN,MAAM,QA+DhB;IAED;;;;;OAKG;IACH,mBAFW,OAAO,qBAAqB,EAAE,KAAK,QAI7C;IA/DO;;kEAcJ,+BAA+B;MAdF;IAiEjC;QAEQ,kJAAkJ;gBAAvI,OAAO,MAAM,EAAE;YAAC,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,CAAC;YAAC,aAAa,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAC,CAAC;QAE9I,8BAA8B;;QAE9B,8CAA8C;;;MAIrD;CACJ;AAED;IACI;;;;;;OAMG;IACH;;oBAHW,MAAM,EAAE;mBACR,MAAM;OA+BhB;IAnBG,qBAkBW;CA8BlB;AAED;IACI;;;;;;;;;OASG;IACH;;oBANW,MAAM,EAAE;gCACR,MAAM;uBAEN,MAAM,EAAE;mBACR,MAAM;OAwBhB;IARG,uBAAgC;IAEhC,8BAA8D;IAE9D,6CAA+D;IAC/D,4CAA6D;CA6CpE;AAED;IACI;;;;;;OAMG;IACH;;oBAHW,MAAM,EAAE;mBACR,MAAM;OAShB;CACJ;AAED;IACI;;;;;OAKG;IACH;;oBAHW,MAAM,EAAE;mBACR,MAAM;OAShB;CAYJ;AAED;IACI;;;;;;;;;OASG;IACH;;oBANW,MAAM,EAAE;qBACR,OAAO,2BAA2B,EAAE,aAAa;oBACjD,OAAO,MAAM,EAAE,GAAG,CAAC;wBACnB,MAAM;sBACN,OAAO;OA8CjB;IA/BG,4DAA2B;IAC3B,2DAA0B;IAE1B,gCAA4B;IAQ5B,qCAAqC;IACrC,sBADmB,GAAG,KAAK,MAAM,CAMf;IAElB,oDAGC;IACD,qDAGC;IAED,8CAAiE;CAgJxE;;;;;;;;YA1mBS,MAAM;;;;WACN,MAAM;YACN,OAAO,yBAAyB,EAAE,MAAM;;yBAjBzB,mBAAmB"}
@@ -95,11 +95,14 @@ export class GeometryBuilder {
95
95
  f,
96
96
  numComponents: largeHp ? 2 : 1,
97
97
  arrayReference: largeHp ? largeHpArray : undefined,
98
- targetArrayType: isDiscrete(ce.scale.type)
99
- ? Uint16Array
100
- : hp
101
- ? Uint32Array
102
- : Float32Array,
98
+ targetArrayType:
99
+ channel == "uniqueId"
100
+ ? Uint32Array
101
+ : isDiscrete(ce.scale.type)
102
+ ? Uint16Array
103
+ : hp
104
+ ? Uint32Array
105
+ : Float32Array,
103
106
  });
104
107
  }
105
108
 
@@ -171,7 +171,7 @@ export function generateScaleGlsl(
171
171
  ? "uvec2"
172
172
  : hp
173
173
  ? "uint"
174
- : discrete
174
+ : discrete || channel == "uniqueId"
175
175
  ? "uint"
176
176
  : "float";
177
177
 
@@ -1,2 +1,2 @@
1
- const shader = "/**Based on concepts presented at:*https:*https:*/out highp vec4 vPickingColor;/***Passes the unique id to the fragment shader as a color if picking is enabled.*Returns true if picking is enabled.*/bool setupPicking(){if(uPickingEnabled){\n#ifdef uniqueId_DEFINED\nint id=int(getScaled_uniqueId());vPickingColor=vec4(ivec4(id>>0,id>>8,id>>16,0xFF)&0xFF)/float(0xFF);\n#else\nvPickingColor=vec4(1.0);\n#endif\nreturn true;}return false;}";
1
+ const shader = "/**Based on concepts presented at:*https:*https:*/out highp vec4 vPickingColor;/***Passes the unique id to the fragment shader as a color if picking is enabled.*Returns true if picking is enabled.*/bool setupPicking(){if(uPickingEnabled){\n#ifdef uniqueId_DEFINED\nuint id=attr_uniqueId;vPickingColor=vec4(ivec4(id>>0,id>>8,id>>16,id>>24)&0xFF)/float(0xFF);\n#else\nvPickingColor=vec4(1.0);\n#endif\nreturn true;}return false;}";
2
2
  export default shader;
@@ -1 +1 @@
1
- {"version":3,"file":"animator.d.ts","sourceRoot":"","sources":["../../../src/utils/animator.js"],"names":[],"mappings":"AAoFA;;;;;;;;;;;;;;GAcG;AACH,6EARW,OAAO,sBAAsB,EAAE,OAAO,0BACxB,IAAI,YAClB,MAAM,UACN,MAAM,oCAEY,IAAI;UAAY,MAAM,IAAI;EAgFtD;AA9KD;IACI;;;OAGG;IACH,mCAFoB,MAAM,KAAE,IAAI,EAS/B;IANG,wBAHgB,MAAM,KAAE,IAAI,CAGS;IACrC,0BAA6B;IAC7B,eAAkB;IAElB,wCAAwC;IACxC,aADW,QAAU,MAAM,KAAE,IAAI,CAAC,EAAE,CACf;IAGzB;;;;;;;;;OASG;IACH,mCAFoB,MAAM,KAAE,IAAI,QAM/B;IAED;;OAEG;IACH,kCAFoB,MAAM,KAAE,IAAI,QAO/B;IAED;;;;OAIG;IACH,sBAoBC;IAED;;;;;OAKG;IACH,oBAFW,OAAO,iBAAiB,EAAE,iBAAiB,gBAQrD;CACJ"}
1
+ {"version":3,"file":"animator.d.ts","sourceRoot":"","sources":["../../../src/utils/animator.js"],"names":[],"mappings":"AAoFA;;;;;;;;;;;;;;GAcG;AACH,6EARW,OAAO,sBAAsB,EAAE,OAAO,0BACxB,IAAI,YAClB,MAAM,UACN,MAAM,oCAEY,IAAI;UAAY,MAAM,IAAI;EAkFtD;AAhLD;IACI;;;OAGG;IACH,mCAFoB,MAAM,KAAE,IAAI,EAS/B;IANG,wBAHgB,MAAM,KAAE,IAAI,CAGS;IACrC,0BAA6B;IAC7B,eAAkB;IAElB,wCAAwC;IACxC,aADW,QAAU,MAAM,KAAE,IAAI,CAAC,EAAE,CACf;IAGzB;;;;;;;;;OASG;IACH,mCAFoB,MAAM,KAAE,IAAI,QAM/B;IAED;;OAEG;IACH,kCAFoB,MAAM,KAAE,IAAI,QAO/B;IAED;;;;OAIG;IACH,sBAoBC;IAED;;;;;OAKG;IACH,oBAFW,OAAO,iBAAiB,EAAE,iBAAiB,gBAQrD;CACJ"}
@@ -151,7 +151,9 @@ export function makeLerpSmoother(
151
151
  current = target;
152
152
  callback(current);
153
153
  settled = true;
154
- animator.requestRender();
154
+ if (maxDiff != 0) {
155
+ animator.requestRender();
156
+ }
155
157
  } else {
156
158
  animator.requestTransition((t) => smoothUpdate(t));
157
159
  }
@@ -1 +1 @@
1
- {"version":3,"file":"inertia.d.ts","sourceRoot":"","sources":["../../../src/utils/inertia.js"],"names":[],"mappings":"AAoEA;;;GAGG;AACH,8EAiBC;AArFD;;GAEG;AACH;IACI;;;OAGG;IACH,sBAHW,OAAO,eAAe,EAAE,OAAO,aAC/B,OAAO,EA0BjB;IAvBG,0CAAwB;IACxB,kBAA0B;IAG1B,oBAAsB;IAEtB,oCAAoC;IACpC,iBADoB,MAAM,KAAE,IAAI,CACZ;IAEpB,oBAAoB;IACpB,kBAAkB;IAElB;;;;MAUC;IAGL,eAIC;IAED;;;;OAIG;IACH,mBAHW,MAAM,mBACG,MAAM,KAAE,IAAI,QAkB/B;CACJ"}
1
+ {"version":3,"file":"inertia.d.ts","sourceRoot":"","sources":["../../../src/utils/inertia.js"],"names":[],"mappings":"AAwEA;;;GAGG;AACH,8EAiBC;AAzFD;;GAEG;AACH;IACI;;;OAGG;IACH,sBAHW,OAAO,eAAe,EAAE,OAAO,aAC/B,OAAO,EA0BjB;IAvBG,0CAAwB;IACxB,kBAA0B;IAG1B,oBAAsB;IAEtB,oCAAoC;IACpC,iBADoB,MAAM,KAAE,IAAI,CACZ;IAEpB,oBAAoB;IACpB,kBAAkB;IAElB;;;;MAUC;IAGL,eAQC;IAED;;;;OAIG;IACH,mBAHW,MAAM,mBACG,MAAM,KAAE,IAAI,QAkB/B;CACJ"}