@genome-spy/core 0.74.0 → 0.75.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/dist/bundle/index.es.js +4660 -4468
- package/dist/bundle/index.js +81 -81
- package/dist/schema.json +220 -12
- package/dist/src/data/sources/dataUtils.d.ts +25 -0
- package/dist/src/data/sources/dataUtils.d.ts.map +1 -1
- package/dist/src/data/sources/dataUtils.js +23 -0
- package/dist/src/data/sources/inlineSource.js +2 -2
- package/dist/src/data/sources/urlSource.d.ts.map +1 -1
- package/dist/src/data/sources/urlSource.js +8 -3
- package/dist/src/encoder/encoder.d.ts +2 -2
- package/dist/src/encoder/encoder.d.ts.map +1 -1
- package/dist/src/genome/scaleLocus.d.ts.map +1 -1
- package/dist/src/genome/scaleLocus.js +8 -3
- package/dist/src/genomeSpy/interactionController.d.ts.map +1 -1
- package/dist/src/genomeSpy/interactionController.js +91 -51
- package/dist/src/gl/dataToVertices.d.ts +12 -14
- package/dist/src/gl/dataToVertices.d.ts.map +1 -1
- package/dist/src/gl/dataToVertices.js +116 -95
- package/dist/src/gl/glslScaleGenerator.d.ts +3 -0
- package/dist/src/gl/glslScaleGenerator.d.ts.map +1 -1
- package/dist/src/gl/glslScaleGenerator.js +10 -8
- package/dist/src/gl/vertexRangeIndex.d.ts +23 -0
- package/dist/src/gl/vertexRangeIndex.d.ts.map +1 -0
- package/dist/src/gl/vertexRangeIndex.js +150 -0
- package/dist/src/marks/mark.d.ts +1 -1
- package/dist/src/paramRuntime/expressionCompiler.d.ts +2 -1
- package/dist/src/paramRuntime/expressionCompiler.d.ts.map +1 -1
- package/dist/src/paramRuntime/expressionCompiler.js +3 -2
- package/dist/src/paramRuntime/expressionRef.d.ts +4 -1
- package/dist/src/paramRuntime/expressionRef.d.ts.map +1 -1
- package/dist/src/paramRuntime/expressionRef.js +10 -3
- package/dist/src/paramRuntime/graphRuntime.d.ts.map +1 -1
- package/dist/src/paramRuntime/graphRuntime.js +15 -6
- package/dist/src/paramRuntime/paramRuntime.d.ts +8 -2
- package/dist/src/paramRuntime/paramRuntime.d.ts.map +1 -1
- package/dist/src/paramRuntime/paramRuntime.js +10 -5
- package/dist/src/paramRuntime/types.d.ts +1 -0
- package/dist/src/paramRuntime/types.d.ts.map +1 -1
- package/dist/src/paramRuntime/types.js +1 -0
- package/dist/src/paramRuntime/viewParamRuntime.d.ts +5 -4
- package/dist/src/paramRuntime/viewParamRuntime.d.ts.map +1 -1
- package/dist/src/paramRuntime/viewParamRuntime.js +17 -6
- package/dist/src/scale/scale.d.ts.map +1 -1
- package/dist/src/scale/scale.js +1 -0
- package/dist/src/scales/domainPlanner.d.ts +57 -11
- package/dist/src/scales/domainPlanner.d.ts.map +1 -1
- package/dist/src/scales/domainPlanner.js +182 -83
- package/dist/src/scales/scaleInstanceManager.d.ts.map +1 -1
- package/dist/src/scales/scaleInstanceManager.js +7 -2
- package/dist/src/scales/scalePropsResolver.d.ts +3 -3
- package/dist/src/scales/scalePropsResolver.d.ts.map +1 -1
- package/dist/src/scales/scalePropsResolver.js +28 -5
- package/dist/src/scales/scaleResolution.d.ts +12 -1
- package/dist/src/scales/scaleResolution.d.ts.map +1 -1
- package/dist/src/scales/scaleResolution.js +171 -18
- package/dist/src/screenshotExport.d.ts +23 -0
- package/dist/src/screenshotExport.d.ts.map +1 -0
- package/dist/src/screenshotExport.js +44 -0
- package/dist/src/screenshotHarness.d.ts.map +1 -1
- package/dist/src/screenshotHarness.js +26 -24
- package/dist/src/spec/axis.d.ts +2 -2
- package/dist/src/spec/channel.d.ts +4 -4
- package/dist/src/spec/data.d.ts +12 -0
- package/dist/src/spec/scale.d.ts +13 -1
- package/dist/src/utils/expression.d.ts +16 -8
- package/dist/src/utils/expression.d.ts.map +1 -1
- package/dist/src/utils/expression.js +291 -11
- package/dist/src/view/flowBuilder.d.ts +1 -1
- package/dist/src/view/flowBuilder.d.ts.map +1 -1
- package/dist/src/view/flowBuilder.js +11 -7
- package/dist/src/view/resolutionPlanner.d.ts +9 -0
- package/dist/src/view/resolutionPlanner.d.ts.map +1 -0
- package/dist/src/view/resolutionPlanner.js +302 -0
- package/dist/src/view/unitView.d.ts +1 -1
- package/dist/src/view/unitView.d.ts.map +1 -1
- package/dist/src/view/unitView.js +5 -152
- package/dist/src/view/view.d.ts.map +1 -1
- package/dist/src/view/view.js +2 -1
- package/package.json +2 -2
|
@@ -40,12 +40,11 @@ export default class InteractionController {
|
|
|
40
40
|
#mouseDownCoords;
|
|
41
41
|
/** @type {Point | undefined} */
|
|
42
42
|
#lastPointerPoint;
|
|
43
|
-
|
|
44
|
-
#
|
|
45
|
-
|
|
46
|
-
#hoverTrackingSuspensionCount;
|
|
47
|
-
|
|
48
|
-
#postRenderHoverRefreshRequested;
|
|
43
|
+
#tooltipUpdateRequested = false;
|
|
44
|
+
#longPressPending = false;
|
|
45
|
+
#suppressTooltipUntilMouseMove = false;
|
|
46
|
+
#hoverTrackingSuspensionCount = 0;
|
|
47
|
+
#postRenderHoverRefreshRequested = false;
|
|
49
48
|
/**
|
|
50
49
|
* @param {object} options
|
|
51
50
|
* @param {import("../view/view.js").default} options.viewRoot
|
|
@@ -89,10 +88,6 @@ export default class InteractionController {
|
|
|
89
88
|
/** @type {Point} */
|
|
90
89
|
this.#mouseDownCoords = undefined;
|
|
91
90
|
this.#lastPointerPoint = undefined;
|
|
92
|
-
|
|
93
|
-
this.#tooltipUpdateRequested = false;
|
|
94
|
-
this.#hoverTrackingSuspensionCount = 0;
|
|
95
|
-
this.#postRenderHoverRefreshRequested = false;
|
|
96
91
|
}
|
|
97
92
|
|
|
98
93
|
getCurrentHover() {
|
|
@@ -101,6 +96,10 @@ export default class InteractionController {
|
|
|
101
96
|
|
|
102
97
|
suspendHoverTracking() {
|
|
103
98
|
this.#hoverTrackingSuspensionCount++;
|
|
99
|
+
if (this.#longPressPending) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
104
103
|
this.#tooltip.clear();
|
|
105
104
|
this.#tooltipUpdateRequested = false;
|
|
106
105
|
}
|
|
@@ -173,7 +172,7 @@ export default class InteractionController {
|
|
|
173
172
|
uiEvent
|
|
174
173
|
);
|
|
175
174
|
|
|
176
|
-
if (!this.#tooltipUpdateRequested) {
|
|
175
|
+
if (!this.#tooltipUpdateRequested && !this.#longPressPending) {
|
|
177
176
|
this.#tooltip.clear();
|
|
178
177
|
}
|
|
179
178
|
|
|
@@ -208,6 +207,7 @@ export default class InteractionController {
|
|
|
208
207
|
!wheeling &&
|
|
209
208
|
this.#hoverTrackingSuspensionCount === 0
|
|
210
209
|
) {
|
|
210
|
+
this.#suppressTooltipUntilMouseMove = false;
|
|
211
211
|
this.#tooltip.handleMouseMove(event);
|
|
212
212
|
this.#tooltipUpdateRequested = false;
|
|
213
213
|
|
|
@@ -343,6 +343,82 @@ export default class InteractionController {
|
|
|
343
343
|
}
|
|
344
344
|
};
|
|
345
345
|
|
|
346
|
+
canvas.addEventListener("mousedown", (/** @type {MouseEvent} */ e) => {
|
|
347
|
+
this.#mouseDownCoords = Point.fromMouseEvent(e);
|
|
348
|
+
this.#longPressPending = false;
|
|
349
|
+
const hasModifier = e.shiftKey || e.ctrlKey || e.metaKey;
|
|
350
|
+
|
|
351
|
+
if (this.#tooltip.sticky) {
|
|
352
|
+
this.#tooltip.sticky = false;
|
|
353
|
+
this.#suppressTooltipUntilMouseMove = true;
|
|
354
|
+
this.#tooltip.clear();
|
|
355
|
+
// Dismiss the sticky tooltip before routing the press so the
|
|
356
|
+
// click only affects the tooltip state.
|
|
357
|
+
longPressTriggered = true;
|
|
358
|
+
} else {
|
|
359
|
+
longPressTriggered = false;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const disableTooltip = () => {
|
|
363
|
+
document.addEventListener(
|
|
364
|
+
"mouseup",
|
|
365
|
+
() => this.#tooltip.popEnabledState(),
|
|
366
|
+
{
|
|
367
|
+
once: true,
|
|
368
|
+
capture: true,
|
|
369
|
+
}
|
|
370
|
+
);
|
|
371
|
+
this.#tooltip.pushEnabledState(false);
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
// Right-click opens the context menu and disables tooltips.
|
|
375
|
+
// Left-button presses keep the current tooltip visible through the
|
|
376
|
+
// press; plain clicks may still promote it to sticky mode.
|
|
377
|
+
if (e.button == 2) {
|
|
378
|
+
disableTooltip();
|
|
379
|
+
} else if (e.button == 0 && this.#tooltip.visible) {
|
|
380
|
+
// Preserve the current tooltip through the press. Plain clicks
|
|
381
|
+
// may also escalate this state into a sticky tooltip.
|
|
382
|
+
this.#longPressPending = true;
|
|
383
|
+
|
|
384
|
+
/** @type {ReturnType<typeof setTimeout> | undefined} */
|
|
385
|
+
let timeout;
|
|
386
|
+
if (!hasModifier) {
|
|
387
|
+
// Make tooltip sticky if the user long-presses
|
|
388
|
+
timeout = setTimeout(() => {
|
|
389
|
+
longPressTriggered = true;
|
|
390
|
+
this.#longPressPending = false;
|
|
391
|
+
this.#tooltip.sticky = true;
|
|
392
|
+
}, 400);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* @param {boolean} clearTooltipOnMove
|
|
397
|
+
*/
|
|
398
|
+
const clear = (clearTooltipOnMove) => {
|
|
399
|
+
clearTimeout(timeout);
|
|
400
|
+
if (!this.#longPressPending) {
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
this.#longPressPending = false;
|
|
405
|
+
if (
|
|
406
|
+
clearTooltipOnMove &&
|
|
407
|
+
this.#hoverTrackingSuspensionCount > 0
|
|
408
|
+
) {
|
|
409
|
+
this.#tooltip.clear();
|
|
410
|
+
this.#tooltipUpdateRequested = false;
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
document.addEventListener("mouseup", () => clear(false), {
|
|
414
|
+
once: true,
|
|
415
|
+
});
|
|
416
|
+
document.addEventListener("mousemove", () => clear(true), {
|
|
417
|
+
once: true,
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
|
|
346
422
|
[
|
|
347
423
|
"mousedown",
|
|
348
424
|
"mouseup",
|
|
@@ -511,46 +587,6 @@ export default class InteractionController {
|
|
|
511
587
|
passive: false,
|
|
512
588
|
});
|
|
513
589
|
|
|
514
|
-
canvas.addEventListener("mousedown", (/** @type {MouseEvent} */ e) => {
|
|
515
|
-
this.#mouseDownCoords = Point.fromMouseEvent(e);
|
|
516
|
-
if (this.#tooltip.sticky) {
|
|
517
|
-
this.#tooltip.sticky = false;
|
|
518
|
-
this.#tooltip.clear();
|
|
519
|
-
// A hack to prevent selection if the tooltip is sticky.
|
|
520
|
-
// Let the tooltip be destickified first.
|
|
521
|
-
longPressTriggered = true;
|
|
522
|
-
} else {
|
|
523
|
-
longPressTriggered = false;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
const disableTooltip = () => {
|
|
527
|
-
document.addEventListener(
|
|
528
|
-
"mouseup",
|
|
529
|
-
() => this.#tooltip.popEnabledState(),
|
|
530
|
-
{
|
|
531
|
-
once: true,
|
|
532
|
-
capture: true,
|
|
533
|
-
}
|
|
534
|
-
);
|
|
535
|
-
this.#tooltip.pushEnabledState(false);
|
|
536
|
-
};
|
|
537
|
-
|
|
538
|
-
// Opening context menu or using modifier keys disables the tooltip
|
|
539
|
-
if (e.button == 2 || e.shiftKey || e.ctrlKey || e.metaKey) {
|
|
540
|
-
disableTooltip();
|
|
541
|
-
} else if (this.#tooltip.visible) {
|
|
542
|
-
// Make tooltip sticky if the user long-presses
|
|
543
|
-
const timeout = setTimeout(() => {
|
|
544
|
-
longPressTriggered = true;
|
|
545
|
-
this.#tooltip.sticky = true;
|
|
546
|
-
}, 400);
|
|
547
|
-
|
|
548
|
-
const clear = () => clearTimeout(timeout);
|
|
549
|
-
document.addEventListener("mouseup", clear, { once: true });
|
|
550
|
-
document.addEventListener("mousemove", clear, { once: true });
|
|
551
|
-
}
|
|
552
|
-
});
|
|
553
|
-
|
|
554
590
|
// Prevent text selections etc while dragging
|
|
555
591
|
canvas.addEventListener("dragstart", (event) =>
|
|
556
592
|
event.stopPropagation()
|
|
@@ -742,6 +778,10 @@ export default class InteractionController {
|
|
|
742
778
|
* @template T
|
|
743
779
|
*/
|
|
744
780
|
updateTooltip(datum, converter) {
|
|
781
|
+
if (this.#suppressTooltipUntilMouseMove) {
|
|
782
|
+
return;
|
|
783
|
+
}
|
|
784
|
+
|
|
745
785
|
if (!this.#tooltipUpdateRequested || !datum) {
|
|
746
786
|
this.#tooltip.updateWithDatum(datum, converter);
|
|
747
787
|
this.#tooltipUpdateRequested = true;
|
|
@@ -25,6 +25,13 @@ export class GeometryBuilder {
|
|
|
25
25
|
variableEncoders: Record<import("../spec/channel.js").Channel, import("../types/encoder.js").Encoder>;
|
|
26
26
|
allocatedVertices: number;
|
|
27
27
|
variableBuilder: ArrayBuilder;
|
|
28
|
+
/** @type {Partial<Record<import("../spec/channel.js").Channel, string>>} */
|
|
29
|
+
attributeNames: Partial<Record<import("../spec/channel.js").Channel, string>>;
|
|
30
|
+
xIndexConfig: {
|
|
31
|
+
domain: [number, number];
|
|
32
|
+
xAttributeName: string;
|
|
33
|
+
x2AttributeName: string;
|
|
34
|
+
};
|
|
28
35
|
lastOffset: number;
|
|
29
36
|
/** @type {Map<any, RangeEntry>} keep track of facet locations within the vertex array */
|
|
30
37
|
rangeMap: Map<any, RangeEntry>;
|
|
@@ -44,22 +51,13 @@ export class GeometryBuilder {
|
|
|
44
51
|
*/
|
|
45
52
|
addBatch(key: any, data: object[], lo?: number, hi?: number): void;
|
|
46
53
|
/**
|
|
47
|
-
*
|
|
48
|
-
* @param {number} [lo]
|
|
49
|
-
* @param {number} [hi]
|
|
50
|
-
*/
|
|
51
|
-
prepareXIndexer(data: import("../data/flowNode.js").Data, lo?: number, hi?: number): void;
|
|
52
|
-
/**
|
|
53
|
-
* Add the datum to an index, which allows for efficient rendering of ranges
|
|
54
|
-
* on the x axis. Must be called after a datum has been pushed to the ArrayBuilder.
|
|
54
|
+
* Builds the x-domain lookup for the current batch if x indexing is enabled.
|
|
55
55
|
*
|
|
56
|
-
* @param {
|
|
56
|
+
* @param {number} startVertexIndex
|
|
57
|
+
* @param {number} endVertexIndex
|
|
58
|
+
* @returns {import("../utils/binnedIndex.js").Lookup | undefined}
|
|
57
59
|
*/
|
|
58
|
-
|
|
59
|
-
xIndexer: {
|
|
60
|
-
(datum: import("../data/flowNode.js").Datum, startVertexIndex: number, endVertexIndex: number): void;
|
|
61
|
-
getIndex: () => import("../utils/binnedIndex.js").Lookup;
|
|
62
|
-
};
|
|
60
|
+
createXIndex(startVertexIndex: number, endVertexIndex: number): import("../utils/binnedIndex.js").Lookup | undefined;
|
|
63
61
|
toArrays(): {
|
|
64
62
|
/** @type {Record<string, {data: Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array, numComponents: number, divisor?: number}>} */
|
|
65
63
|
arrays: Record<string, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataToVertices.d.ts","sourceRoot":"","sources":["../../../src/gl/dataToVertices.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dataToVertices.d.ts","sourceRoot":"","sources":["../../../src/gl/dataToVertices.js"],"names":[],"mappings":"AAiBA;;;;;GAKG;AACH;IACI;;;OAGG;IAEH;;;;;;OAMG;IACH,mDALG;QAAsE,QAAQ,EAAtE,MAAM,CAAC,OAAO,oBAAoB,EAAE,OAAO,wCAAU;QACnC,UAAU,GAA5B,MAAM,EAAE;QACQ,WAAW,GAA3B,MAAM;KAEhB,EA0IA;IAxIG,8FAAwB;IAIxB,sGAQK;IAQL,0BAAoC;IAEpC,8BAAoD;IACpD,4EAA4E;IAC5E,gBADW,OAAO,CAAC,MAAM,CAAC,OAAO,oBAAoB,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAChD;IAgGpB;gBACuB,CAAC,MAAM,EAAE,MAAM,CAAC;;;MAMtC;IAKL,mBAAmB;IAEnB,yFAAyF;IACzF,UADW,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CACkB;IAGrD;;;;OAIG;IACH,mBAFW,GAAG,QAcb;IAED;;OAEG;IACH,oBAFW,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,QAM5B;IAED;;;OAGG;IACH,cAHW,GAAG,QACH,MAAM,EAAE,kCASlB;IAED;;;;;;OAMG;IACH,+BAJW,MAAM,kBACN,MAAM,GACJ,OAAO,yBAAyB,EAAE,MAAM,GAAG,SAAS,CA2ChE;IAED;QAEQ,kJAAkJ;gBAAvI,MAAM,CAAC,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,gDAJG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EA8BA;IAnBG,qBAkBW;CA0BlB;AAED;IACI;;;;;;;;;OASG;IACH,sFAPG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,qBAAqB,GAArC,MAAM;QAEY,YAAY,GAA9B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EAuBA;IARG,uBAAgC;IAEhC,8BAA8D;IAE9D,6CAA+D;IAC/D,4CAA6D;CAyCpE;AAED;IACI;;;;;;OAMG;IACH,gDAJG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EAQA;CAeJ;AAED;IACI;;;;;OAKG;IACH,gDAJG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EAQA;CA0BJ;AAED;IACI;;;;;;;;;OASG;IACH,+EAPG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACkD,WAAW,EAArE,OAAO,2BAA2B,EAAE,aAAa;QACrB,UAAU,EAAtC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;QACH,aAAa,GAA7B,MAAM;QACW,WAAW,GAA5B,OAAO;KAAsB,EA6CvC;IA9BG,4DAA2B;IAC3B,2DAA0B;IAE1B,gCAA4B;IAO5B,qCAAqC;IACrC,cADW,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAMf;IAElB,oDAGC;IACD,qDAGC;IAED,8CAAiE;CA4IxE;;;;;;;;YAtpBS,MAAM;;;;WACN,MAAM;YACN,OAAO,yBAAyB,EAAE,MAAM;;yBAlBzB,mBAAmB"}
|
|
@@ -3,9 +3,9 @@ import { format } from "d3-format";
|
|
|
3
3
|
import { isString } from "vega-util";
|
|
4
4
|
import ArrayBuilder from "./arrayBuilder.js";
|
|
5
5
|
import { SDF_PADDING } from "../fonts/bmFontMetrics.js";
|
|
6
|
-
import { createBinningRangeIndexer } from "../utils/binnedIndex.js";
|
|
7
6
|
import { getEncoderDataAccessor, isValueDef } from "../encoder/encoder.js";
|
|
8
7
|
import {
|
|
8
|
+
HIGH_PRECISION_SPLIT_BASE,
|
|
9
9
|
dedupeEncodingFields,
|
|
10
10
|
getAttributeAndArrayTypes,
|
|
11
11
|
makeAttributeName,
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
} from "./glslScaleGenerator.js";
|
|
14
14
|
import { isContinuous } from "vega-scale";
|
|
15
15
|
import createIndexer from "../utils/indexer.js";
|
|
16
|
+
import { createVertexRangeIndexer } from "./vertexRangeIndex.js";
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* @typedef {object} RangeEntry Represents a location of a vertex subset
|
|
@@ -57,6 +58,8 @@ export class GeometryBuilder {
|
|
|
57
58
|
this.allocatedVertices = numVertices;
|
|
58
59
|
|
|
59
60
|
this.variableBuilder = new ArrayBuilder(numVertices);
|
|
61
|
+
/** @type {Partial<Record<import("../spec/channel.js").Channel, string>>} */
|
|
62
|
+
this.attributeNames = {};
|
|
60
63
|
|
|
61
64
|
// Create converters and updaters for all variable channels.
|
|
62
65
|
for (const [channel, ce] of Object.entries(this.variableEncoders)) {
|
|
@@ -71,9 +74,6 @@ export class GeometryBuilder {
|
|
|
71
74
|
const sharedChannels = dedupedEncodingFields.find((channels) =>
|
|
72
75
|
channels.find((c) => c == channel)
|
|
73
76
|
);
|
|
74
|
-
if (sharedChannels && channel != sharedChannels[0]) {
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
77
|
|
|
78
78
|
const numberAccessor = accessor.asNumberAccessor();
|
|
79
79
|
const scale = ce.scale;
|
|
@@ -116,6 +116,13 @@ export class GeometryBuilder {
|
|
|
116
116
|
: numberAccessor;
|
|
117
117
|
|
|
118
118
|
const attributeName = makeAttributeName(sharedChannels ?? channel);
|
|
119
|
+
for (const sharedChannel of sharedChannels ?? [channel]) {
|
|
120
|
+
this.attributeNames[sharedChannel] = attributeName;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (sharedChannels && channel != sharedChannels[0]) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
119
126
|
|
|
120
127
|
this.variableBuilder.addConverter(attributeName, {
|
|
121
128
|
f,
|
|
@@ -125,6 +132,41 @@ export class GeometryBuilder {
|
|
|
125
132
|
});
|
|
126
133
|
}
|
|
127
134
|
|
|
135
|
+
const xEncoder = this.variableEncoders.x;
|
|
136
|
+
const x2Encoder = this.variableEncoders.x2;
|
|
137
|
+
const xChannelDef =
|
|
138
|
+
/** @type {import("../spec/channel.js").Encoding["x"] | undefined} */ (
|
|
139
|
+
this.encoders.x?.channelDef
|
|
140
|
+
);
|
|
141
|
+
const xScale = xEncoder?.scale;
|
|
142
|
+
if (
|
|
143
|
+
xChannelDef?.buildIndex &&
|
|
144
|
+
xEncoder &&
|
|
145
|
+
xScale &&
|
|
146
|
+
isContinuous(xScale.type)
|
|
147
|
+
) {
|
|
148
|
+
const xAttributeName = this.attributeNames.x;
|
|
149
|
+
if (!xAttributeName) {
|
|
150
|
+
throw new Error("Missing x attribute for x indexing.");
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const x2AttributeName =
|
|
154
|
+
x2Encoder?.scale && isContinuous(x2Encoder.scale.type)
|
|
155
|
+
? (this.attributeNames.x2 ?? xAttributeName)
|
|
156
|
+
: xAttributeName;
|
|
157
|
+
|
|
158
|
+
this.xIndexConfig = {
|
|
159
|
+
domain: /** @type {[number, number]} */ ([
|
|
160
|
+
xScale.domain()[0],
|
|
161
|
+
xScale.domain()[1],
|
|
162
|
+
]),
|
|
163
|
+
xAttributeName,
|
|
164
|
+
x2AttributeName,
|
|
165
|
+
};
|
|
166
|
+
} else {
|
|
167
|
+
this.xIndexConfig = undefined;
|
|
168
|
+
}
|
|
169
|
+
|
|
128
170
|
this.lastOffset = 0;
|
|
129
171
|
|
|
130
172
|
/** @type {Map<any, RangeEntry>} keep track of facet locations within the vertex array */
|
|
@@ -144,7 +186,7 @@ export class GeometryBuilder {
|
|
|
144
186
|
this.rangeMap.set(key, {
|
|
145
187
|
offset,
|
|
146
188
|
count: size,
|
|
147
|
-
xIndex: this.
|
|
189
|
+
xIndex: this.createXIndex(offset, index),
|
|
148
190
|
});
|
|
149
191
|
}
|
|
150
192
|
this.lastOffset = index;
|
|
@@ -164,100 +206,62 @@ export class GeometryBuilder {
|
|
|
164
206
|
* @param {object[]} data
|
|
165
207
|
*/
|
|
166
208
|
addBatch(key, data, lo = 0, hi = data.length) {
|
|
167
|
-
this.prepareXIndexer(data, lo, hi);
|
|
168
|
-
|
|
169
209
|
for (let i = lo; i < hi; i++) {
|
|
170
210
|
const d = data[i];
|
|
171
211
|
this.variableBuilder.pushFromDatum(d);
|
|
172
|
-
this.addToXIndex(d);
|
|
173
212
|
}
|
|
174
213
|
|
|
175
214
|
this.registerBatch(key);
|
|
176
215
|
}
|
|
177
216
|
|
|
178
217
|
/**
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
* @param {number}
|
|
218
|
+
* Builds the x-domain lookup for the current batch if x indexing is enabled.
|
|
219
|
+
*
|
|
220
|
+
* @param {number} startVertexIndex
|
|
221
|
+
* @param {number} endVertexIndex
|
|
222
|
+
* @returns {import("../utils/binnedIndex.js").Lookup | undefined}
|
|
182
223
|
*/
|
|
183
|
-
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
*/
|
|
188
|
-
this.addToXIndex = (datum) => {
|
|
189
|
-
// nop
|
|
190
|
-
};
|
|
191
|
-
this.xIndexer = undefined;
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
const channelDef = this.encoders.x?.channelDef;
|
|
195
|
-
if (
|
|
196
|
-
!("buildIndex" in channelDef) ||
|
|
197
|
-
!channelDef.buildIndex ||
|
|
198
|
-
!data.length ||
|
|
199
|
-
hi - lo < 0
|
|
200
|
-
) {
|
|
201
|
-
disable();
|
|
202
|
-
return;
|
|
224
|
+
createXIndex(startVertexIndex, endVertexIndex) {
|
|
225
|
+
const config = this.xIndexConfig;
|
|
226
|
+
if (!config) {
|
|
227
|
+
return undefined;
|
|
203
228
|
}
|
|
204
229
|
|
|
205
|
-
/**
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
disable();
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/** @type {[number, number]} */
|
|
224
|
-
const dataDomain = [xa(data[lo]), x2a(data[hi - 1])];
|
|
225
|
-
|
|
226
|
-
// No indexer for point domains that have zero extent
|
|
227
|
-
if (dataDomain[1] > dataDomain[0]) {
|
|
228
|
-
this.xIndexer = createBinningRangeIndexer(
|
|
229
|
-
50,
|
|
230
|
-
dataDomain,
|
|
231
|
-
xa,
|
|
232
|
-
x2a
|
|
233
|
-
);
|
|
234
|
-
|
|
235
|
-
let lastVertexCount = this.variableBuilder.vertexCount;
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* @param {any} datum
|
|
239
|
-
*/
|
|
240
|
-
this.addToXIndex = (datum) => {
|
|
241
|
-
let currentVertexCount = this.variableBuilder.vertexCount;
|
|
242
|
-
this.xIndexer(datum, lastVertexCount, currentVertexCount);
|
|
243
|
-
lastVertexCount = currentVertexCount;
|
|
230
|
+
/**
|
|
231
|
+
* @param {string} attributeName
|
|
232
|
+
*/
|
|
233
|
+
const createReader = (attributeName) => {
|
|
234
|
+
const attribute = this.variableBuilder.arrays[attributeName];
|
|
235
|
+
const { data, numComponents } = attribute;
|
|
236
|
+
|
|
237
|
+
if (numComponents == 2) {
|
|
238
|
+
/** @type {(vertexIndex: number) => number} */
|
|
239
|
+
return (vertexIndex) => {
|
|
240
|
+
const base = vertexIndex * numComponents;
|
|
241
|
+
return (
|
|
242
|
+
data[base] * HIGH_PRECISION_SPLIT_BASE + data[base + 1]
|
|
243
|
+
);
|
|
244
244
|
};
|
|
245
|
-
} else {
|
|
246
|
-
disable();
|
|
247
245
|
}
|
|
248
|
-
} else {
|
|
249
|
-
disable();
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
246
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
247
|
+
/** @type {(vertexIndex: number) => number} */
|
|
248
|
+
return (vertexIndex) => data[vertexIndex * numComponents];
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
const xReader = createReader(config.xAttributeName);
|
|
252
|
+
const x2Reader =
|
|
253
|
+
config.x2AttributeName == config.xAttributeName
|
|
254
|
+
? xReader
|
|
255
|
+
: createReader(config.x2AttributeName);
|
|
256
|
+
|
|
257
|
+
return createVertexRangeIndexer(
|
|
258
|
+
50,
|
|
259
|
+
config.domain,
|
|
260
|
+
xReader,
|
|
261
|
+
x2Reader,
|
|
262
|
+
startVertexIndex,
|
|
263
|
+
endVertexIndex
|
|
264
|
+
);
|
|
261
265
|
}
|
|
262
266
|
|
|
263
267
|
toArrays() {
|
|
@@ -322,8 +326,6 @@ export class RectVertexBuilder extends GeometryBuilder {
|
|
|
322
326
|
return;
|
|
323
327
|
}
|
|
324
328
|
|
|
325
|
-
this.prepareXIndexer(data, lo, hi);
|
|
326
|
-
|
|
327
329
|
for (let i = lo; i < hi; i++) {
|
|
328
330
|
const d = data[i];
|
|
329
331
|
|
|
@@ -333,8 +335,6 @@ export class RectVertexBuilder extends GeometryBuilder {
|
|
|
333
335
|
// Six vertices per rect. The vertex shader is using gl_VertexID to
|
|
334
336
|
// determine the vertex position within the rect.
|
|
335
337
|
this.pushAllSixTimes();
|
|
336
|
-
|
|
337
|
-
this.addToXIndex(d);
|
|
338
338
|
}
|
|
339
339
|
|
|
340
340
|
this.registerBatch(key);
|
|
@@ -384,8 +384,6 @@ export class RuleVertexBuilder extends GeometryBuilder {
|
|
|
384
384
|
addBatch(key, data, lo = 0, hi = data.length) {
|
|
385
385
|
//const [lower, upper] = this.visibleRange; // TODO
|
|
386
386
|
|
|
387
|
-
this.prepareXIndexer(data, lo, hi);
|
|
388
|
-
|
|
389
387
|
for (let i = lo; i < hi; i++) {
|
|
390
388
|
const d = data[i];
|
|
391
389
|
|
|
@@ -410,7 +408,6 @@ export class RuleVertexBuilder extends GeometryBuilder {
|
|
|
410
408
|
|
|
411
409
|
// Duplicate the last vertex to produce a degenerate triangle between the rules
|
|
412
410
|
this.variableBuilder.pushAll();
|
|
413
|
-
this.addToXIndex(d);
|
|
414
411
|
}
|
|
415
412
|
|
|
416
413
|
this.registerBatch(key);
|
|
@@ -433,6 +430,20 @@ export class PointVertexBuilder extends GeometryBuilder {
|
|
|
433
430
|
});
|
|
434
431
|
this.variableBuilder.configure();
|
|
435
432
|
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
*
|
|
436
|
+
* @param {any} key
|
|
437
|
+
* @param {object[]} data
|
|
438
|
+
*/
|
|
439
|
+
addBatch(key, data, lo = 0, hi = data.length) {
|
|
440
|
+
for (let i = lo; i < hi; i++) {
|
|
441
|
+
const d = data[i];
|
|
442
|
+
this.variableBuilder.pushFromDatum(d);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
this.registerBatch(key);
|
|
446
|
+
}
|
|
436
447
|
}
|
|
437
448
|
|
|
438
449
|
export class LinkVertexBuilder extends GeometryBuilder {
|
|
@@ -451,6 +462,20 @@ export class LinkVertexBuilder extends GeometryBuilder {
|
|
|
451
462
|
this.variableBuilder.configure();
|
|
452
463
|
}
|
|
453
464
|
|
|
465
|
+
/**
|
|
466
|
+
*
|
|
467
|
+
* @param {any} key
|
|
468
|
+
* @param {object[]} data
|
|
469
|
+
*/
|
|
470
|
+
addBatch(key, data, lo = 0, hi = data.length) {
|
|
471
|
+
for (let i = lo; i < hi; i++) {
|
|
472
|
+
const d = data[i];
|
|
473
|
+
this.variableBuilder.pushFromDatum(d);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
this.registerBatch(key);
|
|
477
|
+
}
|
|
478
|
+
|
|
454
479
|
toArrays() {
|
|
455
480
|
const arrays = this.variableBuilder.arrays;
|
|
456
481
|
|
|
@@ -553,8 +578,6 @@ export class TextVertexBuilder extends GeometryBuilder {
|
|
|
553
578
|
const textureCoord = [0, 0];
|
|
554
579
|
this.updateTextureCoord(textureCoord);
|
|
555
580
|
|
|
556
|
-
this.prepareXIndexer(data, lo, hi);
|
|
557
|
-
|
|
558
581
|
for (let i = lo; i < hi; i++) {
|
|
559
582
|
const d = data[i];
|
|
560
583
|
|
|
@@ -652,8 +675,6 @@ export class TextVertexBuilder extends GeometryBuilder {
|
|
|
652
675
|
|
|
653
676
|
x += advance;
|
|
654
677
|
}
|
|
655
|
-
|
|
656
|
-
this.addToXIndex(d);
|
|
657
678
|
}
|
|
658
679
|
|
|
659
680
|
this.registerBatch(key);
|
|
@@ -141,6 +141,9 @@ export const SCALED_FUNCTION_PREFIX: "getScaled_";
|
|
|
141
141
|
export const RANGE_TEXTURE_PREFIX: "uRangeTexture_";
|
|
142
142
|
export const PARAM_PREFIX: "uParam_";
|
|
143
143
|
export const SELECTION_CHECKER_PREFIX: "checkSelection_";
|
|
144
|
+
export const HIGH_PRECISION_SPLIT_BITS: 12;
|
|
145
|
+
export const HIGH_PRECISION_SPLIT_BASE: number;
|
|
146
|
+
export const HIGH_PRECISION_SPLIT_MASK: number;
|
|
144
147
|
export function getRangeForGlsl(scale: any, channel: Channel): number[];
|
|
145
148
|
export type Channel = import("../spec/channel.js").Channel;
|
|
146
149
|
export type AccessorParts = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"glslScaleGenerator.d.ts","sourceRoot":"","sources":["../../../src/gl/glslScaleGenerator.js"],"names":[],"mappings":"AAsDA;;;;;GAKG;AACH,kDAJW,OAAO,mBACP,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;;;;;GAUG;AAEH;;;;;;;GAOG;AACH,mDALW,OAAO,mBACP,MAAM,SACN,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,OAAO,GAClC,aAAa,CA4CzB;AAED;;;;;;;GAOG;AACH,4DAJW,OAAO,mBACP,MAAM,GACJ,aAAa,CAkCzB;AAED;;;;;;GAMG;AACH,0CANW,OAAO,SACP,GAAG,mBACH,MAAM,+BACN,OAAO,EAAE,GACP,aAAa,CA8BzB;AACD;;;;;GAKG;AACH,qDALW,OAAO,SACP,GAAG,mBACH,MAAM,GACJ,aAAa,CAyBzB;AAED;;;;;GAKG;AACH,2CAJW,OAAO,SACP,GAAG,cACH,OAAO,oBAAoB,EAAE,UAAU;;;;;;EAsQjD;AAED;;;;GAIG;AACH,wDAHW,OAAO,YACP,OAAO,qBAAqB,EAAE,cAAc,EAAE,UA+BxD;AAmED;;GAEG;AACH,qDAFW,OAAO,6BAQjB;AAuCD;;;;GAIG;AACH,iDAHW,OAAO,qBAAqB,EAAE,SAAS,WACvC,OAAO,oBAAoB,EAAE,OAAO;mBAQjB,MAAM;sBAAoB,sBAAsB,GAAG,sBAAsB,GAAG,uBAAuB;;;;;;
|
|
1
|
+
{"version":3,"file":"glslScaleGenerator.d.ts","sourceRoot":"","sources":["../../../src/gl/glslScaleGenerator.js"],"names":[],"mappings":"AAsDA;;;;;GAKG;AACH,kDAJW,OAAO,mBACP,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;;;;;GAUG;AAEH;;;;;;;GAOG;AACH,mDALW,OAAO,mBACP,MAAM,SACN,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,OAAO,GAClC,aAAa,CA4CzB;AAED;;;;;;;GAOG;AACH,4DAJW,OAAO,mBACP,MAAM,GACJ,aAAa,CAkCzB;AAED;;;;;;GAMG;AACH,0CANW,OAAO,SACP,GAAG,mBACH,MAAM,+BACN,OAAO,EAAE,GACP,aAAa,CA8BzB;AACD;;;;;GAKG;AACH,qDALW,OAAO,SACP,GAAG,mBACH,MAAM,GACJ,aAAa,CAyBzB;AAED;;;;;GAKG;AACH,2CAJW,OAAO,SACP,GAAG,cACH,OAAO,oBAAoB,EAAE,UAAU;;;;;;EAsQjD;AAED;;;;GAIG;AACH,wDAHW,OAAO,YACP,OAAO,qBAAqB,EAAE,cAAc,EAAE,UA+BxD;AAmED;;GAEG;AACH,qDAFW,OAAO,6BAQjB;AAuCD;;;;GAIG;AACH,iDAHW,OAAO,qBAAqB,EAAE,SAAS,WACvC,OAAO,oBAAoB,EAAE,OAAO;mBAQjB,MAAM;sBAAoB,sBAAsB,GAAG,sBAAsB,GAAG,uBAAuB;;;;;;EAoBhI;AAED;;;;GAIG;AACH,2CAFW,MAAM,6BAIhB;AAED;;;;GAIG;AACH,sCAFW,MAAM,EAAE,WAIlB;AAMD;;;GAGG;AACH,sCAHW,MAAM,QACN,MAAM,EAAE,YAYlB;AAED;;;GAGG;AACH,2CAHW,MAAM,QACN,MAAM,EAAE,YAUlB;AAYD;;GAEG;AACH,qDAFW,MAAM,EAAE,YAIlB;AAED;;GAEG;AAEH;;;;;GAKG;AACH,+CAFW,OAAO,CAAC,MAAM,CAAC,OAAO,oBAAoB,EAAE,OAAO,EAAE,OAAO,qBAAqB,EAAE,OAAO,CAAC,CAAC,+DA4BtG;AAED;;GAEG;AACH,2CAFW,OAAO,oBAAoB,EAAE,OAAO,GAAG,OAAO,oBAAoB,EAAE,OAAO,EAAE,UAIvF;AAwBD;;;;GAIG;AACH,uCAJW,MAAM,EAAE,cACR,MAAM,EAAE,GACN,MAAM,CAgClB;AAr0BD,+BAAgC,OAAO,CAAC;AACxC,4BAA6B,UAAU,CAAC;AACxC,2BAA4B,QAAQ,CAAC;AACrC,uCAAwC,WAAW,CAAC;AACpD,oCAAqC,QAAQ,CAAC;AAC9C,qCAAsC,YAAY,CAAC;AACnD,mCAAoC,gBAAgB,CAAC;AACrD,2BAA4B,SAAS,CAAC;AACtC,uCAAwC,iBAAiB,CAAC;AAoqB1D,wCAAyC,EAAE,CAAC;AAC5C,+CAAwE;AACxE,+CAAuE;AA4GhE,uCAJI,GAAG,WACH,OAAO,GACL,MAAM,EAAE,CAQA;sBAlxBR,OAAO,oBAAoB,EAAE,OAAO;;aA+BvC,OAAO;kBACP,MAAM;0BACN,MAAM;oBACN,MAAM;oBACN,MAAM;kBACN,MAAM;kBACN,MAAM;eACN,CAAC,CAAC,EAAE,GAAG,KAAK,GAAG;;;;;8BAkfZ,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE;;;;uBA0LhD,CAAC,MAAM,EAAE,OAAO,CAAC;0BAruBJ,WAAW"}
|
|
@@ -676,7 +676,9 @@ export function getAttributeAndArrayTypes(scale, channel) {
|
|
|
676
676
|
: { attributeType: "float", arrayConstructor: Float32Array };
|
|
677
677
|
|
|
678
678
|
return Object.assign(props, {
|
|
679
|
-
numComponents: +(
|
|
679
|
+
numComponents: +(
|
|
680
|
+
props.attributeType.match(/^(?:u)?vec([234])$/)?.[1] ?? 1
|
|
681
|
+
),
|
|
680
682
|
discrete,
|
|
681
683
|
hp,
|
|
682
684
|
largeHp,
|
|
@@ -701,9 +703,9 @@ export function isLargeGenome(domain) {
|
|
|
701
703
|
return domain[1] > 2 ** 32;
|
|
702
704
|
}
|
|
703
705
|
|
|
704
|
-
const
|
|
705
|
-
const
|
|
706
|
-
const
|
|
706
|
+
export const HIGH_PRECISION_SPLIT_BITS = 12;
|
|
707
|
+
export const HIGH_PRECISION_SPLIT_BASE = 2 ** HIGH_PRECISION_SPLIT_BITS;
|
|
708
|
+
export const HIGH_PRECISION_SPLIT_MASK = HIGH_PRECISION_SPLIT_BASE - 1;
|
|
707
709
|
|
|
708
710
|
/**
|
|
709
711
|
* @param {number} x Must be an integer
|
|
@@ -712,7 +714,7 @@ const BM = BS - 1;
|
|
|
712
714
|
export function splitHighPrecision(x, arr = []) {
|
|
713
715
|
// Using a bitmask is MUCH faster than using modulo (at least on Chrome 112)
|
|
714
716
|
// https://www.wikiwand.com/en/Modulo#Performance_issues
|
|
715
|
-
const lo = x &
|
|
717
|
+
const lo = x & HIGH_PRECISION_SPLIT_MASK;
|
|
716
718
|
const hi = x - lo;
|
|
717
719
|
|
|
718
720
|
arr[0] = hi;
|
|
@@ -726,8 +728,8 @@ export function splitHighPrecision(x, arr = []) {
|
|
|
726
728
|
* @param {number[]} [arr]
|
|
727
729
|
*/
|
|
728
730
|
export function splitLargeHighPrecision(x, arr = []) {
|
|
729
|
-
const lo = x %
|
|
730
|
-
const hi = (x - lo) /
|
|
731
|
+
const lo = x % HIGH_PRECISION_SPLIT_BASE;
|
|
732
|
+
const hi = (x - lo) / HIGH_PRECISION_SPLIT_BASE;
|
|
731
733
|
|
|
732
734
|
arr[0] = hi;
|
|
733
735
|
arr[1] = lo;
|
|
@@ -739,7 +741,7 @@ export function splitLargeHighPrecision(x, arr = []) {
|
|
|
739
741
|
* @param {number} x
|
|
740
742
|
*/
|
|
741
743
|
function exactSplitHighPrecision(x) {
|
|
742
|
-
const lo = x %
|
|
744
|
+
const lo = x % HIGH_PRECISION_SPLIT_BASE;
|
|
743
745
|
const hi = x - lo;
|
|
744
746
|
|
|
745
747
|
return [hi, lo];
|