@genome-spy/core 0.76.0 → 0.77.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.
Files changed (56) hide show
  1. package/LICENSE +21 -0
  2. package/dist/bundle/browser-KWU9rWZT.js +123 -0
  3. package/dist/bundle/{esm-BimDEpBb.js → esm-0dYHNV_D.js} +1 -1
  4. package/dist/bundle/{esm-CngqBe45.js → esm-CRMf_I9V.js} +1 -1
  5. package/dist/bundle/esm-CT3ygiMq.js +1084 -0
  6. package/dist/bundle/{esm-D_euN86T.js → esm-CscjKVDc.js} +1 -1
  7. package/dist/bundle/index.es.js +2708 -2601
  8. package/dist/bundle/index.js +91 -83
  9. package/dist/src/data/sources/lazy/bigWigSource.d.ts.map +1 -1
  10. package/dist/src/data/sources/lazy/bigWigSource.js +31 -11
  11. package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts +19 -3
  12. package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts.map +1 -1
  13. package/dist/src/data/sources/lazy/singleAxisWindowedSource.js +34 -13
  14. package/dist/src/data/transforms/filterScoredLabels.d.ts.map +1 -1
  15. package/dist/src/data/transforms/filterScoredLabels.js +3 -2
  16. package/dist/src/embedFactory.d.ts.map +1 -1
  17. package/dist/src/embedFactory.js +2 -0
  18. package/dist/src/genomeSpy/viewContextFactory.d.ts.map +1 -1
  19. package/dist/src/genomeSpy/viewContextFactory.js +1 -0
  20. package/dist/src/genomeSpyBase.d.ts +6 -0
  21. package/dist/src/genomeSpyBase.d.ts.map +1 -1
  22. package/dist/src/genomeSpyBase.js +11 -0
  23. package/dist/src/index.d.ts +1 -0
  24. package/dist/src/index.d.ts.map +1 -1
  25. package/dist/src/index.js +1 -0
  26. package/dist/src/marks/__snapshots__/shaderSnapshot.test.js.snap +2 -2
  27. package/dist/src/marks/mark.d.ts.map +1 -1
  28. package/dist/src/marks/mark.js +0 -6
  29. package/dist/src/marks/rect.vertex.glsl.js +1 -1
  30. package/dist/src/minimal.d.ts +1 -0
  31. package/dist/src/minimal.d.ts.map +1 -1
  32. package/dist/src/minimal.js +1 -0
  33. package/dist/src/paramRuntime/embedParamApi.d.ts +26 -0
  34. package/dist/src/paramRuntime/embedParamApi.d.ts.map +1 -0
  35. package/dist/src/paramRuntime/embedParamApi.js +133 -0
  36. package/dist/src/scales/scaleInteractionController.d.ts +8 -4
  37. package/dist/src/scales/scaleInteractionController.d.ts.map +1 -1
  38. package/dist/src/scales/scaleInteractionController.js +55 -7
  39. package/dist/src/scales/scaleResolution.d.ts +3 -3
  40. package/dist/src/scales/scaleResolution.d.ts.map +1 -1
  41. package/dist/src/scales/scaleResolution.js +5 -4
  42. package/dist/src/selection/index.d.ts +8 -0
  43. package/dist/src/selection/index.d.ts.map +1 -0
  44. package/dist/src/selection/index.js +12 -0
  45. package/dist/src/styles/genome-spy.css +8 -0
  46. package/dist/src/styles/genome-spy.css.d.ts +1 -1
  47. package/dist/src/styles/genome-spy.css.d.ts.map +1 -1
  48. package/dist/src/styles/genome-spy.css.js +8 -0
  49. package/dist/src/types/embedApi.d.ts +54 -0
  50. package/dist/src/types/scaleResolutionApi.d.ts +28 -1
  51. package/dist/src/types/viewContext.d.ts +11 -0
  52. package/dist/src/utils/ui/tooltip.d.ts.map +1 -1
  53. package/dist/src/utils/ui/tooltip.js +22 -0
  54. package/package.json +3 -3
  55. package/dist/bundle/browser-BTgw5ieH.js +0 -126
  56. package/dist/bundle/esm-Bvlm1uVk.js +0 -1015
@@ -27,6 +27,7 @@ import {
27
27
  * @typedef {import("../spec/scale.js").ComplexDomain} ComplexDomain
28
28
  * @typedef {import("../spec/scale.js").ZoomParams} ZoomParams
29
29
  * @typedef {import("../types/encoder.js").VegaScale} VegaScale
30
+ * @typedef {import("../types/scaleResolutionApi.js").ZoomToOptions} ZoomToOptions
30
31
  * @typedef {VegaScale & { props: import("../spec/scale.js").Scale }} ScaleWithProps
31
32
  */
32
33
 
@@ -37,6 +38,9 @@ export default class ScaleInteractionController {
37
38
  /** @type {() => import("../utils/animator.js").default} */
38
39
  #getAnimator;
39
40
 
41
+ /** @type {() => void} */
42
+ #renderImmediately;
43
+
40
44
  /** @type {() => number[]} */
41
45
  #getInitialDomainSnapshot;
42
46
 
@@ -56,6 +60,7 @@ export default class ScaleInteractionController {
56
60
  * @param {object} options
57
61
  * @param {() => ScaleWithProps} options.getScale
58
62
  * @param {() => import("../utils/animator.js").default} options.getAnimator
63
+ * @param {() => void} options.renderImmediately
59
64
  * @param {() => number[]} options.getInitialDomainSnapshot
60
65
  * @param {() => number[]} options.getResetDomain
61
66
  * @param {(domain: ScalarDomain | ComplexDomain) => number[]} options.fromComplexInterval
@@ -64,6 +69,7 @@ export default class ScaleInteractionController {
64
69
  constructor({
65
70
  getScale,
66
71
  getAnimator,
72
+ renderImmediately,
67
73
  getInitialDomainSnapshot,
68
74
  getResetDomain,
69
75
  fromComplexInterval,
@@ -71,6 +77,7 @@ export default class ScaleInteractionController {
71
77
  }) {
72
78
  this.#getScale = getScale;
73
79
  this.#getAnimator = getAnimator;
80
+ this.#renderImmediately = renderImmediately;
74
81
  this.#getInitialDomainSnapshot = getInitialDomainSnapshot;
75
82
  this.#getResetDomain = getResetDomain;
76
83
  this.#fromComplexInterval = fromComplexInterval;
@@ -170,13 +177,11 @@ export default class ScaleInteractionController {
170
177
  * Immediately zooms to the given interval.
171
178
  *
172
179
  * @param {NumericDomain | ComplexDomain} domain
173
- * @param {boolean | number} [duration] an approximate duration for transition.
174
- * Zero duration zooms immediately. Boolean `true` indicates a default duration.
180
+ * @param {ZoomToOptions | boolean | number} [options] Zoom options.
181
+ * Passing the duration directly as a boolean or number is deprecated.
175
182
  */
176
- async zoomTo(domain, duration = false) {
177
- if (isBoolean(duration)) {
178
- duration = duration ? 700 : 0;
179
- }
183
+ async zoomTo(domain, options = false) {
184
+ const { duration, renderImmediately } = normalizeZoomToOptions(options);
180
185
 
181
186
  if (!this.isZoomingSupported()) {
182
187
  throw new Error("Not a zoomable scale!");
@@ -195,6 +200,12 @@ export default class ScaleInteractionController {
195
200
  const from = /** @type {number[]} */ (scale.domain());
196
201
 
197
202
  if (duration > 0 && from.length == 2) {
203
+ if (renderImmediately) {
204
+ throw new Error(
205
+ "renderImmediately is not supported for animated zooms."
206
+ );
207
+ }
208
+
198
209
  // Spans
199
210
  const fw = from[1] - from[0];
200
211
  const tw = to[1] - to[0];
@@ -234,7 +245,11 @@ export default class ScaleInteractionController {
234
245
  } else {
235
246
  this.#cancelZoomTransition();
236
247
  scale.domain(to);
237
- animator?.requestRender();
248
+ if (renderImmediately) {
249
+ this.#renderImmediately();
250
+ } else {
251
+ animator?.requestRender();
252
+ }
238
253
  }
239
254
  }
240
255
 
@@ -279,6 +294,39 @@ export default class ScaleInteractionController {
279
294
  }
280
295
  }
281
296
 
297
+ /**
298
+ * @param {ZoomToOptions | boolean | number | undefined} options
299
+ * @returns {{ duration: number, renderImmediately: boolean }}
300
+ */
301
+ function normalizeZoomToOptions(options) {
302
+ if (options === undefined) {
303
+ return {
304
+ duration: 0,
305
+ renderImmediately: false,
306
+ };
307
+ }
308
+
309
+ if (isBoolean(options)) {
310
+ return {
311
+ duration: options ? 700 : 0,
312
+ renderImmediately: false,
313
+ };
314
+ }
315
+
316
+ if (typeof options === "number") {
317
+ return {
318
+ duration: options,
319
+ renderImmediately: false,
320
+ };
321
+ }
322
+
323
+ const duration = options.duration ?? 0;
324
+ return {
325
+ duration: isBoolean(duration) ? (duration ? 700 : 0) : duration,
326
+ renderImmediately: options.renderImmediately === true,
327
+ };
328
+ }
329
+
282
330
  /**
283
331
  * @param {ScaleWithProps} scale
284
332
  * @param {ZoomParams | boolean | undefined} zoom
@@ -185,10 +185,10 @@ export default class ScaleResolution implements ScaleResolutionApi {
185
185
  * Immediately zooms to the given interval.
186
186
  *
187
187
  * @param {NumericDomain | ComplexDomain} domain
188
- * @param {boolean | number} [duration] an approximate duration for transition.
189
- * Zero duration zooms immediately. Boolean `true` indicates a default duration.
188
+ * @param {import("../types/scaleResolutionApi.js").ZoomToOptions | boolean | number} [options]
189
+ * Zoom options. Passing the duration directly as a boolean or number is deprecated.
190
190
  */
191
- zoomTo(domain: import("../spec/scale.js").NumericDomain | import("../spec/scale.js").ComplexDomain, duration?: boolean | number): Promise<void>;
191
+ zoomTo(domain: import("../spec/scale.js").NumericDomain | import("../spec/scale.js").ComplexDomain, options?: import("../types/scaleResolutionApi.js").ZoomToOptions | boolean | number): Promise<void>;
192
192
  /**
193
193
  * Resets the current domain to the initial one
194
194
  *
@@ -1 +1 @@
1
- {"version":3,"file":"scaleResolution.d.ts","sourceRoot":"","sources":["../../../src/scales/scaleResolution.js"],"names":[],"mappings":"AAoDA;;;;;;;;GAQG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH;IA6cI;;;;;;;;OAQG;IACH,uBALa,CAAC,eACH,QAAQ,CAAC,eAAe,CAAC,YACzB,MAAM,CAAC,GACL,CAAC,CAqBb;IAlaD;;;OAGG;IACH,sEAFW,OAAO,iBAAiB,EAAE,OAAO,EAsC3C;IAnCG,8CAAsB;IACtB,0FAA0F;IAC1F,MADW,OAAO,oBAAoB,EAAE,IAAI,CAC5B;IAEhB,iEAAiE;IACjE,MADW,MAAM,CACI;IA0EzB,2BASC;IAwBD;;;;;;;OAOG;IACH,4KAEC;IAED;;;OAGG;IACH,+KAEC;IAiCD,sCA6CC;IA+MD;;;OAGG;IACH,uBAHW,qBAAqB,GACnB,MAAM,OAAO,CAazB;IAED,gBAMC;IAoFD;;;;OAIG;IACH,0CAJW,OAAO,sBAAsB,EAAE,OAAO,aACtC,QAAQ,CAAC,OAAO,qBAAqB,EAAE,aAAa,CAAC,GACnD,MAAM,IAAI,CAkCtB;IAED;;OAEG;IACH,qCAEC;IAED,+BAiBC;IAuED;;;;;;;;;;;OAWG;IACH,0BALa;QACR,QAAQ,EAAE,OAAO,kBAAkB,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;QACnE,oBAAoB,EAAE,OAAO,CAAA;KAC9B,CAeH;IAED;;;;;;;OAOG;IACH,wBAFa,OAAO,kBAAkB,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,CAShE;IAgGD;;;;;OAKG;IACH,oBAYC;IAED;;;;;OAKG;IACH,0BA0BC;IAoID;;OAEG;IACH;eAlhCkC,OAAO,kBAAkB,EAAE,KAAK;MAyhCjE;IAED;;;;;;OAMG;IACH;eAliCkC,OAAO,kBAAkB,EAAE,KAAK;MAyiCjE;IAED;;;;OAIG;IACH;eAhjCkC,OAAO,kBAAkB,EAAE,KAAK;MAyjCjE;IAED,mBASC;IAED;;;;OAIG;IACH,+DAEC;IAED;;OAEG;IACH,oBAFa,mFAA6B,CASzC;IAED;;OAEG;IACH;;;;MAqBC;IAED;;;;OAIG;IACH,oBAEC;IAED;;OAEG;IACH,sBASC;IAED;;;;;;;OAOG;IACH,kBALW,MAAM,eACN,MAAM,OACN,MAAM,GACJ,OAAO,CAInB;IAED;;;;;;OAMG;IACH,eAJW,mFAA6B,aAC7B,OAAO,GAAG,MAAM,iBAK1B;IAED;;;;OAIG;IACH,qBAEC;IAED;;;;;OAKG;IACH,uBAEC;IAED;;;;;;;OAOG;IACH,wBAoBC;IAED;;;;;OAKG;IACH,uBAFW,MAAM,yDAUhB;IAED;;OAEG;IACH,iBAFW,MAAM,yDAIhB;IAED;;;OAGG;IACH,qBAHW,MAAM,+CAAmB,GACvB,MAAM,CAIlB;IAED;;;OAGG;IACH,8BAHW,kFAA4B,GAC1B,MAAM,EAAE,CAOpB;;CACJ;kCAvyC+B,CAAC,SAApB,6CAAkB;;;;UAGrB,OAAO,qBAAqB,EAAE,OAAO;aACrC,CAAC;gBACD,OAAO,oBAAoB,EAAE,mBAAmB;yBAChD,OAAO;;sBApCV,+BAA+B;sBAA/B,+BAA+B;wBAA/B,+BAA+B;wBAA/B,+BAA+B;6BAA/B,+BAA+B"}
1
+ {"version":3,"file":"scaleResolution.d.ts","sourceRoot":"","sources":["../../../src/scales/scaleResolution.js"],"names":[],"mappings":"AAoDA;;;;;;;;GAQG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH;IA8cI;;;;;;;;OAQG;IACH,uBALa,CAAC,eACH,QAAQ,CAAC,eAAe,CAAC,YACzB,MAAM,CAAC,GACL,CAAC,CAqBb;IAnaD;;;OAGG;IACH,sEAFW,OAAO,iBAAiB,EAAE,OAAO,EAuC3C;IApCG,8CAAsB;IACtB,0FAA0F;IAC1F,MADW,OAAO,oBAAoB,EAAE,IAAI,CAC5B;IAEhB,iEAAiE;IACjE,MADW,MAAM,CACI;IA2EzB,2BASC;IAwBD;;;;;;;OAOG;IACH,4KAEC;IAED;;;OAGG;IACH,+KAEC;IAiCD,sCA6CC;IA+MD;;;OAGG;IACH,uBAHW,qBAAqB,GACnB,MAAM,OAAO,CAazB;IAED,gBAMC;IAoFD;;;;OAIG;IACH,0CAJW,OAAO,sBAAsB,EAAE,OAAO,aACtC,QAAQ,CAAC,OAAO,qBAAqB,EAAE,aAAa,CAAC,GACnD,MAAM,IAAI,CAkCtB;IAED;;OAEG;IACH,qCAEC;IAED,+BAiBC;IAuED;;;;;;;;;;;OAWG;IACH,0BALa;QACR,QAAQ,EAAE,OAAO,kBAAkB,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;QACnE,oBAAoB,EAAE,OAAO,CAAA;KAC9B,CAeH;IAED;;;;;;;OAOG;IACH,wBAFa,OAAO,kBAAkB,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,CAShE;IAgGD;;;;;OAKG;IACH,oBAYC;IAED;;;;;OAKG;IACH,0BA0BC;IAoID;;OAEG;IACH;eAnhCkC,OAAO,kBAAkB,EAAE,KAAK;MA0hCjE;IAED;;;;;;OAMG;IACH;eAniCkC,OAAO,kBAAkB,EAAE,KAAK;MA0iCjE;IAED;;;;OAIG;IACH;eAjjCkC,OAAO,kBAAkB,EAAE,KAAK;MA0jCjE;IAED,mBASC;IAED;;;;OAIG;IACH,+DAEC;IAED;;OAEG;IACH,oBAFa,mFAA6B,CASzC;IAED;;OAEG;IACH;;;;MAqBC;IAED;;;;OAIG;IACH,oBAEC;IAED;;OAEG;IACH,sBASC;IAED;;;;;;;OAOG;IACH,kBALW,MAAM,eACN,MAAM,OACN,MAAM,GACJ,OAAO,CAInB;IAED;;;;;;OAMG;IACH,eAJW,mFAA6B,YAC7B,OAAO,gCAAgC,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,iBAKnF;IAED;;;;OAIG;IACH,qBAEC;IAED;;;;;OAKG;IACH,uBAEC;IAED;;;;;;;OAOG;IACH,wBAoBC;IAED;;;;;OAKG;IACH,uBAFW,MAAM,yDAUhB;IAED;;OAEG;IACH,iBAFW,MAAM,yDAIhB;IAED;;;OAGG;IACH,qBAHW,MAAM,+CAAmB,GACvB,MAAM,CAIlB;IAED;;;OAGG;IACH,8BAHW,kFAA4B,GAC1B,MAAM,EAAE,CAOpB;;CACJ;kCAxyC+B,CAAC,SAApB,6CAAkB;;;;UAGrB,OAAO,qBAAqB,EAAE,OAAO;aACrC,CAAC;gBACD,OAAO,oBAAoB,EAAE,mBAAmB;yBAChD,OAAO;;sBApCV,+BAA+B;sBAA/B,+BAA+B;wBAA/B,+BAA+B;wBAA/B,+BAA+B;6BAA/B,+BAA+B"}
@@ -183,6 +183,7 @@ export default class ScaleResolution {
183
183
  this.#interactionController = new ScaleInteractionController({
184
184
  getScale: () => this.getScale(),
185
185
  getAnimator: () => this.#viewContext.animator,
186
+ renderImmediately: () => this.#viewContext.renderImmediately(),
186
187
  getInitialDomainSnapshot: () =>
187
188
  this.#domainAggregator.initialDomainSnapshot,
188
189
  getResetDomain: () => this.#getConfiguredOrDefaultDomain(),
@@ -1273,11 +1274,11 @@ export default class ScaleResolution {
1273
1274
  * Immediately zooms to the given interval.
1274
1275
  *
1275
1276
  * @param {NumericDomain | ComplexDomain} domain
1276
- * @param {boolean | number} [duration] an approximate duration for transition.
1277
- * Zero duration zooms immediately. Boolean `true` indicates a default duration.
1277
+ * @param {import("../types/scaleResolutionApi.js").ZoomToOptions | boolean | number} [options]
1278
+ * Zoom options. Passing the duration directly as a boolean or number is deprecated.
1278
1279
  */
1279
- async zoomTo(domain, duration = false) {
1280
- return this.#interactionController.zoomTo(domain, duration);
1280
+ async zoomTo(domain, options = false) {
1281
+ return this.#interactionController.zoomTo(domain, options);
1281
1282
  }
1282
1283
 
1283
1284
  /**
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Creates a runtime interval selection value for use with parameter APIs.
3
+ *
4
+ * @param {Partial<Record<import("../spec/channel.js").PositionalChannel, [number, number] | null>>} intervals
5
+ * @returns {import("../types/selectionTypes.js").IntervalSelection}
6
+ */
7
+ export function intervalSelection(intervals: Partial<Record<import("../spec/channel.js").PositionalChannel, [number, number] | null>>): import("../types/selectionTypes.js").IntervalSelection;
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/selection/index.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,6CAHW,OAAO,CAAC,MAAM,CAAC,OAAO,oBAAoB,EAAE,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,GACtF,OAAO,4BAA4B,EAAE,iBAAiB,CAOlE"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Creates a runtime interval selection value for use with parameter APIs.
3
+ *
4
+ * @param {Partial<Record<import("../spec/channel.js").PositionalChannel, [number, number] | null>>} intervals
5
+ * @returns {import("../types/selectionTypes.js").IntervalSelection}
6
+ */
7
+ export function intervalSelection(intervals) {
8
+ return {
9
+ type: "interval",
10
+ intervals: { ...intervals },
11
+ };
12
+ }
@@ -177,6 +177,14 @@
177
177
  }
178
178
  }
179
179
 
180
+ .autoscroll-container {
181
+ max-height: min(40em, 50vh);
182
+ overflow-x: hidden;
183
+ overflow-y: auto;
184
+ padding-right: var(--genome-spy-basic-spacing);
185
+ margin-right: calc(-1 * var(--genome-spy-basic-spacing));
186
+ }
187
+
180
188
  .na {
181
189
  color: #aaa;
182
190
  font-style: italic;
@@ -1,3 +1,3 @@
1
1
  export default css;
2
- declare const css: "\n@scope {\n:scope {\n--genome-spy-basic-spacing: 10px;\n--genome-spy-font-family:\nsystem-ui, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif,\n\"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n\nfont-family: var(--genome-spy-font-family);\n\nposition: relative;\n\ndisplay: flex;\nflex-direction: column;\n}\n\n.canvas-wrapper {\nposition: relative;\nflex-grow: 1;\noverflow: hidden;\n}\n\ncanvas {\ndisplay: block;\ntouch-action: none;\ntransform: scale(1, 1);\nopacity: 1;\ntransition:\ntransform 0.6s,\nopacity 0.6s;\n\n&:focus,\n&:focus-visible {\noutline: none;\n}\n}\n\n.loading {\n> canvas {\ntransform: scale(0.95, 0.95);\nopacity: 0;\n}\n}\n\n.loading-indicators {\nposition: absolute;\ninset: 0;\n\nuser-select: none;\npointer-events: none;\n\ndiv {\nposition: absolute;\ndisplay: flex;\nalign-items: center;\njustify-content: center;\n\n> div {\nfont-size: 11px;\ntransition: opacity 0.2s;\nbackground: white;\npadding: 2px 5px;\ndisplay: flex;\nborder-radius: 3px;\ngap: 0.5em;\nopacity: 0;\n\n&.loading {\nopacity: 0.5;\n}\n\n&.error {\nopacity: 0.8;\ncolor: firebrick;\n}\n\n> * {\ndisplay: block;\n}\n\nimg {\nwidth: 1.5em;\nheight: 1.5em;\n}\n}\n}\n}\n\n.tooltip {\nposition: absolute;\n\nmax-width: 450px;\noverflow: hidden;\n\n--background-color: #f6f6f6;\nbackground: var(--background-color);\npadding: var(--genome-spy-basic-spacing);\n\n--font-size: 12px;\nfont-size: var(--font-size);\n\nbox-shadow: 0px 3px 15px 0px rgba(0, 0, 0, 0.21);\n\n&:not(.sticky) {\npointer-events: none;\n}\n\ntransition:\noutline-color 0.3s ease-in-out,\nbox-shadow 0.3s ease-in-out;\n\noutline: 0px solid transparent;\n&.sticky {\noutline: 2px solid black;\nbox-shadow: 0px 3px 18px 0px rgba(0, 0, 0, 0.3);\n}\n\nz-index: 100;\n\n> :last-child {\nmargin-bottom: 0;\n}\n\n> .title {\npadding-bottom: calc(var(--genome-spy-basic-spacing) / 2);\nmargin-bottom: calc(var(--genome-spy-basic-spacing) / 2);\nborder-bottom: 1px dashed var(--background-color);\nborder-bottom: 1px dashed\ncolor-mix(in srgb, black 25%, var(--background-color));\n}\n\n.summary {\nfont-size: 12px;\n}\n\ntable {\n&:first-child {\nmargin-top: 0;\n}\n\nborder-collapse: collapse;\n\nth,\ntd {\npadding: 2px 0.4em;\nvertical-align: top;\nfont-size: var(--font-size);\n\n&:first-child {\npadding-left: 0;\n}\n}\n\nth {\ntext-align: left;\nfont-weight: bold;\n}\n}\n\n.color-legend {\ndisplay: inline-block;\nwidth: 0.8em;\nheight: 0.8em;\nmargin-left: 0.4em;\nbox-shadow: 0px 0px 3px 1px white;\n}\n\n.color-legend-unmapped {\nbackground-color: transparent;\nborder: 1px solid black;\nbox-sizing: border-box;\nbox-shadow: none;\n}\n\n.attributes {\n.hovered {\nbackground-color: #e0e0e0;\n}\n}\n\n.na {\ncolor: #aaa;\nfont-style: italic;\nfont-size: 80%;\n}\n}\n\n.gene-track-tooltip {\n.summary {\nfont-size: 90%;\n}\n}\n\n.gs-input-binding {\ndisplay: grid;\ngrid-template-columns: max-content max-content;\ncolumn-gap: 1em;\nrow-gap: 0.3em;\njustify-items: start;\n\n> select,\n> input:not([type=\"checkbox\"]) {\nwidth: 100%;\n}\n\ninput[type=\"range\"] + span {\ndisplay: inline-block;\nmargin-left: 0.3em;\nmin-width: 2.2em;\nfont-variant-numeric: tabular-nums;\n}\n\ninput[type=\"range\"],\ninput[type=\"radio\"] {\nvertical-align: text-bottom;\n}\n\n.radio-group {\ndisplay: flex;\nalign-items: center;\n}\n\n.description {\nmax-width: 26em;\ngrid-column: 1 / -1;\ncolor: #777;\nfont-size: 90%;\nmargin-top: -0.5em;\n}\n}\n\n.gs-input-bindings {\nflex-basis: content;\nfont-size: 14px;\npadding: var(--genome-spy-basic-spacing);\n}\n\n.message-box {\ndisplay: flex;\nalign-items: center;\njustify-content: center;\nposition: absolute;\ntop: 0;\nheight: 100%;\nwidth: 100%;\n\n> div {\nborder: 1px solid red;\npadding: 10px;\nbackground: #fff0f0;\n}\n}\n}\n";
2
+ declare const css: "\n@scope {\n:scope {\n--genome-spy-basic-spacing: 10px;\n--genome-spy-font-family:\nsystem-ui, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif,\n\"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n\nfont-family: var(--genome-spy-font-family);\n\nposition: relative;\n\ndisplay: flex;\nflex-direction: column;\n}\n\n.canvas-wrapper {\nposition: relative;\nflex-grow: 1;\noverflow: hidden;\n}\n\ncanvas {\ndisplay: block;\ntouch-action: none;\ntransform: scale(1, 1);\nopacity: 1;\ntransition:\ntransform 0.6s,\nopacity 0.6s;\n\n&:focus,\n&:focus-visible {\noutline: none;\n}\n}\n\n.loading {\n> canvas {\ntransform: scale(0.95, 0.95);\nopacity: 0;\n}\n}\n\n.loading-indicators {\nposition: absolute;\ninset: 0;\n\nuser-select: none;\npointer-events: none;\n\ndiv {\nposition: absolute;\ndisplay: flex;\nalign-items: center;\njustify-content: center;\n\n> div {\nfont-size: 11px;\ntransition: opacity 0.2s;\nbackground: white;\npadding: 2px 5px;\ndisplay: flex;\nborder-radius: 3px;\ngap: 0.5em;\nopacity: 0;\n\n&.loading {\nopacity: 0.5;\n}\n\n&.error {\nopacity: 0.8;\ncolor: firebrick;\n}\n\n> * {\ndisplay: block;\n}\n\nimg {\nwidth: 1.5em;\nheight: 1.5em;\n}\n}\n}\n}\n\n.tooltip {\nposition: absolute;\n\nmax-width: 450px;\noverflow: hidden;\n\n--background-color: #f6f6f6;\nbackground: var(--background-color);\npadding: var(--genome-spy-basic-spacing);\n\n--font-size: 12px;\nfont-size: var(--font-size);\n\nbox-shadow: 0px 3px 15px 0px rgba(0, 0, 0, 0.21);\n\n&:not(.sticky) {\npointer-events: none;\n}\n\ntransition:\noutline-color 0.3s ease-in-out,\nbox-shadow 0.3s ease-in-out;\n\noutline: 0px solid transparent;\n&.sticky {\noutline: 2px solid black;\nbox-shadow: 0px 3px 18px 0px rgba(0, 0, 0, 0.3);\n}\n\nz-index: 100;\n\n> :last-child {\nmargin-bottom: 0;\n}\n\n> .title {\npadding-bottom: calc(var(--genome-spy-basic-spacing) / 2);\nmargin-bottom: calc(var(--genome-spy-basic-spacing) / 2);\nborder-bottom: 1px dashed var(--background-color);\nborder-bottom: 1px dashed\ncolor-mix(in srgb, black 25%, var(--background-color));\n}\n\n.summary {\nfont-size: 12px;\n}\n\ntable {\n&:first-child {\nmargin-top: 0;\n}\n\nborder-collapse: collapse;\n\nth,\ntd {\npadding: 2px 0.4em;\nvertical-align: top;\nfont-size: var(--font-size);\n\n&:first-child {\npadding-left: 0;\n}\n}\n\nth {\ntext-align: left;\nfont-weight: bold;\n}\n}\n\n.color-legend {\ndisplay: inline-block;\nwidth: 0.8em;\nheight: 0.8em;\nmargin-left: 0.4em;\nbox-shadow: 0px 0px 3px 1px white;\n}\n\n.color-legend-unmapped {\nbackground-color: transparent;\nborder: 1px solid black;\nbox-sizing: border-box;\nbox-shadow: none;\n}\n\n.attributes {\n.hovered {\nbackground-color: #e0e0e0;\n}\n}\n\n.autoscroll-container {\nmax-height: min(40em, 50vh);\noverflow-x: hidden;\noverflow-y: auto;\npadding-right: var(--genome-spy-basic-spacing);\nmargin-right: calc(-1 * var(--genome-spy-basic-spacing));\n}\n\n.na {\ncolor: #aaa;\nfont-style: italic;\nfont-size: 80%;\n}\n}\n\n.gene-track-tooltip {\n.summary {\nfont-size: 90%;\n}\n}\n\n.gs-input-binding {\ndisplay: grid;\ngrid-template-columns: max-content max-content;\ncolumn-gap: 1em;\nrow-gap: 0.3em;\njustify-items: start;\n\n> select,\n> input:not([type=\"checkbox\"]) {\nwidth: 100%;\n}\n\ninput[type=\"range\"] + span {\ndisplay: inline-block;\nmargin-left: 0.3em;\nmin-width: 2.2em;\nfont-variant-numeric: tabular-nums;\n}\n\ninput[type=\"range\"],\ninput[type=\"radio\"] {\nvertical-align: text-bottom;\n}\n\n.radio-group {\ndisplay: flex;\nalign-items: center;\n}\n\n.description {\nmax-width: 26em;\ngrid-column: 1 / -1;\ncolor: #777;\nfont-size: 90%;\nmargin-top: -0.5em;\n}\n}\n\n.gs-input-bindings {\nflex-basis: content;\nfont-size: 14px;\npadding: var(--genome-spy-basic-spacing);\n}\n\n.message-box {\ndisplay: flex;\nalign-items: center;\njustify-content: center;\nposition: absolute;\ntop: 0;\nheight: 100%;\nwidth: 100%;\n\n> div {\nborder: 1px solid red;\npadding: 10px;\nbackground: #fff0f0;\n}\n}\n}\n";
3
3
  //# sourceMappingURL=genome-spy.css.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"genome-spy.css.d.ts","sourceRoot":"","sources":["../../../src/styles/genome-spy.css.js"],"names":[],"mappings":";AAAA,isHA6PE"}
1
+ {"version":3,"file":"genome-spy.css.d.ts","sourceRoot":"","sources":["../../../src/styles/genome-spy.css.js"],"names":[],"mappings":";AAAA,i5HAqQE"}
@@ -178,6 +178,14 @@ background-color: #e0e0e0;
178
178
  }
179
179
  }
180
180
 
181
+ .autoscroll-container {
182
+ max-height: min(40em, 50vh);
183
+ overflow-x: hidden;
184
+ overflow-y: auto;
185
+ padding-right: var(--genome-spy-basic-spacing);
186
+ margin-right: calc(-1 * var(--genome-spy-basic-spacing));
187
+ }
188
+
181
189
  .na {
182
190
  color: #aaa;
183
191
  font-style: italic;
@@ -2,6 +2,8 @@ import { ScaleResolutionApi } from "./scaleResolutionApi.js";
2
2
  import { TooltipHandler } from "../tooltip/tooltipHandler.js";
3
3
  import { RootSpec } from "../spec/root.js";
4
4
  import { GenomeSpyConfig } from "../spec/config.js";
5
+ import { Scalar } from "../spec/channel.js";
6
+ import { IntervalSelection } from "./selectionTypes.js";
5
7
 
6
8
  /**
7
9
  * Embeds GenomeSpy into the DOM
@@ -54,6 +56,47 @@ export interface EmbedOptions {
54
56
  onError?: (error: unknown, container: HTMLElement) => boolean | void;
55
57
  }
56
58
 
59
+ /**
60
+ * Runtime value type covered by the default embed parameter API.
61
+ *
62
+ * The default type covers scalar variable parameters and interval selections.
63
+ * Object and array variable parameters are supported at runtime, but callers
64
+ * should provide their own generic type when accessing them:
65
+ *
66
+ * `const param = api.getParam<MyValue>("myParam")`
67
+ *
68
+ * Current limitations:
69
+ *
70
+ * - Parameters are addressed by name only. Independent same-name parameters
71
+ * throw an ambiguity error.
72
+ * - Computed `expr` parameters are readable but cannot be written.
73
+ * - Point selections are readable as runtime values but are not supported for
74
+ * writes through the initial API because valid values require
75
+ * GenomeSpy-generated datum ids.
76
+ * - Projected selections are not supported.
77
+ */
78
+ export type ParamValue = Scalar | null | undefined | IntervalSelection;
79
+
80
+ /**
81
+ * A handle for reading, writing, and subscribing to an explicit parameter.
82
+ */
83
+ export interface ParamApi<T = ParamValue> {
84
+ /**
85
+ * Returns the current parameter value.
86
+ */
87
+ getValue: () => T;
88
+
89
+ /**
90
+ * Sets the parameter value. Computed `expr` parameters throw when set.
91
+ */
92
+ setValue: (value: T) => void;
93
+
94
+ /**
95
+ * Subscribes to parameter changes. Returns an unsubscribe function.
96
+ */
97
+ subscribe: (listener: (value: T) => void) => () => void;
98
+ }
99
+
57
100
  /**
58
101
  * An API for controlling the embedded GenomeSpy instance.
59
102
  */
@@ -82,6 +125,17 @@ export interface EmbedResult {
82
125
  */
83
126
  getScaleResolutionByName: (name: string) => ScaleResolutionApi;
84
127
 
128
+ /**
129
+ * Returns a handle for reading, writing, and subscribing to a named
130
+ * parameter.
131
+ *
132
+ * Parameters are addressed by name only. If the name resolves to multiple
133
+ * independent parameters, this method throws an ambiguity error. Parameters
134
+ * declared with `push: "outer"` are treated as aliases of the outer
135
+ * parameter they write to.
136
+ */
137
+ getParam: <T = ParamValue>(name: string) => ParamApi<T>;
138
+
85
139
  /**
86
140
  * Waits until lazy data sources have loaded data for the current visible
87
141
  * positional domain.
@@ -10,6 +10,25 @@ export interface ScaleResolutionEvent {
10
10
 
11
11
  export type ScaleResolutionListener = (event: ScaleResolutionEvent) => void;
12
12
 
13
+ export interface ZoomToOptions {
14
+ /**
15
+ * Approximate transition duration. Zero or omitted zooms immediately.
16
+ * Boolean `true` indicates a default duration.
17
+ */
18
+ duration?: boolean | number;
19
+
20
+ /**
21
+ * Render immediately without scheduling an animation frame.
22
+ *
23
+ * This is intended for synchronizing multiple GenomeSpy instances, where
24
+ * the target view should be redrawn during the same animation frame as the
25
+ * source view. Use it only for zero-duration zooms. It is not supported for
26
+ * animated transitions and may do redundant work if several domains are
27
+ * applied before the browser has a chance to paint.
28
+ */
29
+ renderImmediately?: boolean;
30
+ }
31
+
13
32
  /**
14
33
  * A public API for ScaleResolution
15
34
  */
@@ -59,6 +78,14 @@ export interface ScaleResolutionApi {
59
78
 
60
79
  zoomTo(
61
80
  domain: number[] | ComplexDomain,
62
- duration?: boolean | number
81
+ options?: ZoomToOptions
82
+ ): Promise<void>;
83
+
84
+ /**
85
+ * @deprecated Use the options object form: `zoomTo(domain, { duration })`.
86
+ */
87
+ zoomTo(
88
+ domain: number[] | ComplexDomain,
89
+ duration: boolean | number
63
90
  ): Promise<void>;
64
91
  }
@@ -34,6 +34,17 @@ export default interface ViewContext {
34
34
 
35
35
  requestLayoutReflow: () => void;
36
36
 
37
+ /**
38
+ * Renders the current scene immediately without scheduling an animation frame.
39
+ *
40
+ * This is intended for synchronization paths where another GenomeSpy
41
+ * instance is already rendering the current animation frame and this view
42
+ * must repaint after a synchronous state update, such as linked scale
43
+ * domains. Callers should use the animator for ordinary rendering. Calling
44
+ * this repeatedly before the browser paints may do redundant work.
45
+ */
46
+ renderImmediately: () => void;
47
+
37
48
  updateTooltip: <T>(
38
49
  datum: T,
39
50
  converter?: (datum: T) => Promise<TemplateResult>
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../../../src/utils/ui/tooltip.js"],"names":[],"mappings":"AAIA,0CAA2C,qBAAqB,CAAC;AACjE,4CAA6C,uBAAuB,CAAC;AAErE;IAsBI;;OAEG;IACH,uBAFW,WAAW,EAUrB;IAED;;OAEG;IACH,mBAFW,OAAO,EAQjB;IAED,cAVW,OAAO,CAYjB;IAED;;OAEG;IACH,qBAFW,OAAO,EAOjB;IAED,eATW,OAAO,CAWjB;IAED,uBAEC;IAED;;OAEG;IACH,0BAFW,OAAO,QAOjB;IAED,wBAEC;IAED;;OAEG;IACH,4BAFW,UAAU,QAsCpB;IA/BG,8BAA2D;IAiC/D,wBAiBC;IAED;;OAEG;IACH,oBAFW,MAAM,GAAG,OAAO,KAAK,EAAE,cAAc,GAAG,WAAW,QAqB7D;IAED,cAGC;IAED;;;;;;;OAOG;IACH,gBAFa,CAAC,SAFH,CAAC,cACD,CAAS,IAAC,EAAD,CAAC,KAAE,OAAO,CAAC,MAAM,GAAG,WAAW,GAAG,OAAO,KAAK,EAAE,cAAc,CAAC,QAyBlF;IAED,sBAEC;;CACJ"}
1
+ {"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../../../src/utils/ui/tooltip.js"],"names":[],"mappings":"AAIA,0CAA2C,qBAAqB,CAAC;AACjE,4CAA6C,uBAAuB,CAAC;AAErE;IAsBI;;OAEG;IACH,uBAFW,WAAW,EAUrB;IAED;;OAEG;IACH,mBAFW,OAAO,EAQjB;IAED,cAVW,OAAO,CAYjB;IAED;;OAEG;IACH,qBAFW,OAAO,EAOjB;IAED,eATW,OAAO,CAWjB;IAED,uBAEC;IAED;;OAEG;IACH,0BAFW,OAAO,QAOjB;IAED,wBAEC;IAED;;OAEG;IACH,4BAFW,UAAU,QAsCpB;IA/BG,8BAA2D;IAiC/D,wBAiBC;IAED;;OAEG;IACH,oBAFW,MAAM,GAAG,OAAO,KAAK,EAAE,cAAc,GAAG,WAAW,QAwB7D;IAED,cAGC;IAED;;;;;;;OAOG;IACH,gBAFa,CAAC,SAFH,CAAC,cACD,CAAS,IAAC,EAAD,CAAC,KAAE,OAAO,CAAC,MAAM,GAAG,WAAW,GAAG,OAAO,KAAK,EAAE,cAAc,CAAC,QAyBlF;IAED,sBAEC;;CACJ"}
@@ -165,6 +165,9 @@ export default class Tooltip {
165
165
  }
166
166
 
167
167
  render(content, this.#element);
168
+ this.#element
169
+ .querySelectorAll(".autoscroll-container")
170
+ .forEach(scrollHoveredTooltipRow);
168
171
 
169
172
  this.visible = true;
170
173
 
@@ -213,6 +216,25 @@ export default class Tooltip {
213
216
  }
214
217
  }
215
218
 
219
+ /**
220
+ * Scrolls the highlighted tooltip row into view after Lit has committed the
221
+ * current render.
222
+ *
223
+ * @param {Element | undefined} element
224
+ */
225
+ function scrollHoveredTooltipRow(element) {
226
+ if (!element) {
227
+ return;
228
+ }
229
+
230
+ queueMicrotask(() => {
231
+ element.querySelector("tr.hovered")?.scrollIntoView({
232
+ block: "nearest",
233
+ inline: "nearest",
234
+ });
235
+ });
236
+ }
237
+
216
238
  /**
217
239
  * Calculate euclidean distance
218
240
  *
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "contributors": [],
9
9
  "license": "MIT",
10
- "version": "0.76.0",
10
+ "version": "0.77.0",
11
11
  "jsdelivr": "dist/bundle/index.js",
12
12
  "unpkg": "dist/bundle/index.js",
13
13
  "browser": "dist/bundle/index.js",
@@ -46,7 +46,7 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "@gmod/bam": "^7.1.19",
49
- "@gmod/bbi": "^9.0.0",
49
+ "@gmod/bbi": "^9.2.0",
50
50
  "@gmod/bed": "^2.1.10",
51
51
  "@gmod/indexedfasta": "^5.0.2",
52
52
  "@gmod/tabix": "^3.2.2",
@@ -78,5 +78,5 @@
78
78
  "devDependencies": {
79
79
  "@types/long": "^4.0.1"
80
80
  },
81
- "gitHead": "34d821cf5e864972afaa65a3290719e2fdb209c2"
81
+ "gitHead": "2851e22e2069a70d7d02e3ab707b7556573aa17e"
82
82
  }
@@ -1,126 +0,0 @@
1
- import { t as e } from "./chunk-DmhlhrBa.js";
2
- //#region ../../node_modules/generic-filehandle2/esm/blobFile.js
3
- var t = class {
4
- constructor(e) {
5
- this.blob = e;
6
- }
7
- async read(e, t = 0) {
8
- if (!e) return new Uint8Array();
9
- let n = t, r = n + e, i = this.blob.slice(n, r);
10
- return i.bytes ? i.bytes() : new Uint8Array(await i.arrayBuffer());
11
- }
12
- async readFile(e) {
13
- let t = typeof e == "string" ? e : e?.encoding;
14
- if (t === "utf8") return this.blob.text();
15
- if (t) throw Error(`unsupported encoding: ${t}`);
16
- return this.blob.bytes ? this.blob.bytes() : new Uint8Array(await this.blob.arrayBuffer());
17
- }
18
- async stat() {
19
- return { size: this.blob.size };
20
- }
21
- async close() {}
22
- };
23
- //#endregion
24
- //#region ../../node_modules/generic-filehandle2/esm/remoteFile.js
25
- function n(e) {
26
- return (typeof e == "object" && e && "message" in e ? e.message : `${e}`).replace(/\.$/, "");
27
- }
28
- var r = class {
29
- constructor(e, t = {}) {
30
- this.baseOverrides = {}, this.url = e;
31
- let n = t.fetch || globalThis.fetch.bind(globalThis);
32
- t.overrides && (this.baseOverrides = t.overrides), this.fetchImplementation = n;
33
- }
34
- async fetch(e, t) {
35
- let r = (t) => Error(`${n(t)} fetching ${e}`, { cause: t }), i;
36
- try {
37
- i = await this.fetchImplementation(e, t);
38
- } catch (n) {
39
- if (`${n}`.includes("Failed to fetch")) {
40
- console.warn(`generic-filehandle: refetching ${e} to attempt to work around chrome CORS header caching bug`);
41
- try {
42
- i = await this.fetchImplementation(e, {
43
- ...t,
44
- cache: "reload"
45
- });
46
- } catch (e) {
47
- throw r(e);
48
- }
49
- } else throw r(n);
50
- }
51
- return i;
52
- }
53
- async read(e, t, n = {}) {
54
- if (e === 0) return new Uint8Array();
55
- let { headers: r = {}, signal: i, overrides: a = {} } = n;
56
- e < Infinity ? r.range = `bytes=${t}-${t + e - 1}` : e === Infinity && t !== 0 && (r.range = `bytes=${t}-`);
57
- let o = await this.fetch(this.url, {
58
- ...this.baseOverrides,
59
- ...a,
60
- headers: {
61
- ...this.baseOverrides.headers,
62
- ...a.headers,
63
- ...r
64
- },
65
- method: "GET",
66
- redirect: "follow",
67
- mode: "cors",
68
- signal: i
69
- });
70
- if (!o.ok) throw Error(`HTTP ${o.status} fetching ${this.url}`);
71
- if (o.status === 200 && t === 0 || o.status === 206) {
72
- let t = o.headers.get("content-range"), n = /\/(\d+)$/.exec(t || "");
73
- n?.[1] && (this._stat = { size: parseInt(n[1], 10) });
74
- let r = o.bytes ? await o.bytes() : new Uint8Array(await o.arrayBuffer());
75
- return r.byteLength <= e ? r : r.subarray(0, e);
76
- }
77
- throw Error(o.status === 200 ? `${this.url} fetch returned status 200, expected 206` : `HTTP ${o.status} fetching ${this.url}`);
78
- }
79
- async readFile(e = {}) {
80
- let t, n;
81
- if (typeof e == "string") t = e, n = {};
82
- else {
83
- t = e.encoding;
84
- let { encoding: r, ...i } = e;
85
- n = i;
86
- }
87
- let { headers: r = {}, signal: i, overrides: a = {} } = n, o = await this.fetch(this.url, {
88
- ...this.baseOverrides,
89
- ...a,
90
- headers: {
91
- ...this.baseOverrides.headers,
92
- ...a.headers,
93
- ...r
94
- },
95
- method: "GET",
96
- redirect: "follow",
97
- mode: "cors",
98
- signal: i
99
- });
100
- if (!o.ok) throw Error(`HTTP ${o.status} fetching ${this.url}`);
101
- if (t === "utf8") return o.text();
102
- if (t) throw Error(`unsupported encoding: ${t}`);
103
- return o.bytes ? o.bytes() : new Uint8Array(await o.arrayBuffer());
104
- }
105
- async stat() {
106
- if (!this._stat && (await this.read(10, 0), !this._stat)) throw Error(`unable to determine size of file at ${this.url}`);
107
- return this._stat;
108
- }
109
- async close() {}
110
- }, i = /* @__PURE__ */ e({
111
- BlobFile: () => t,
112
- LocalFile: () => a,
113
- RemoteFile: () => r
114
- }), a = class {
115
- readFile() {
116
- throw Error("unimplemented");
117
- }
118
- read() {
119
- throw Error("unimplemented");
120
- }
121
- close() {
122
- throw Error("unimplemented");
123
- }
124
- };
125
- //#endregion
126
- export { i as n, r, a as t };