@tanstack/virtual-core 3.0.0-beta.2 → 3.0.0-beta.20
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/build/cjs/{packages/virtual-core/src/index.js → index.js} +236 -111
- package/build/cjs/index.js.map +1 -0
- package/build/cjs/{packages/virtual-core/src/utils.js → utils.js} +0 -0
- package/build/cjs/utils.js.map +1 -0
- package/build/esm/index.js +236 -180
- package/build/esm/index.js.map +1 -1
- package/build/{stats-html.html → stats.html} +1 -1
- package/build/{stats-react.json → stats.json} +14 -39
- package/build/types/index.d.ts +61 -19
- package/build/umd/index.development.js +234 -178
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +4 -6
- package/src/index.ts +237 -132
- package/build/cjs/packages/virtual-core/src/index.js.map +0 -1
- package/build/cjs/packages/virtual-core/src/utils.js.map +0 -1
- package/build/types/utils.d.ts +0 -7
package/src/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import observeRect from '@reach/observe-rect'
|
|
2
1
|
import { memo } from './utils'
|
|
3
2
|
|
|
4
3
|
export * from './utils'
|
|
@@ -7,8 +6,9 @@ export * from './utils'
|
|
|
7
6
|
|
|
8
7
|
type ScrollAlignment = 'start' | 'center' | 'end' | 'auto'
|
|
9
8
|
|
|
10
|
-
interface ScrollToOptions {
|
|
11
|
-
align
|
|
9
|
+
export interface ScrollToOptions {
|
|
10
|
+
align?: ScrollAlignment
|
|
11
|
+
smoothScroll?: boolean
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
type ScrollToOffsetOptions = ScrollToOptions
|
|
@@ -58,12 +58,34 @@ export const defaultRangeExtractor = (range: Range) => {
|
|
|
58
58
|
return arr
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
const memoRectCallback = (
|
|
62
|
+
instance: Virtualizer<any, any>,
|
|
63
|
+
cb: (rect: Rect) => void,
|
|
64
|
+
) => {
|
|
65
|
+
let prev: Rect = { height: -1, width: -1 }
|
|
66
|
+
|
|
67
|
+
return (rect: Rect) => {
|
|
68
|
+
if (
|
|
69
|
+
instance.options.horizontal
|
|
70
|
+
? rect.width !== prev.width
|
|
71
|
+
: rect.height !== prev.height
|
|
72
|
+
) {
|
|
73
|
+
cb(rect)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
prev = rect
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
61
80
|
export const observeElementRect = (
|
|
62
81
|
instance: Virtualizer<any, any>,
|
|
63
82
|
cb: (rect: Rect) => void,
|
|
64
83
|
) => {
|
|
65
|
-
const observer =
|
|
66
|
-
cb(
|
|
84
|
+
const observer = new ResizeObserver((entries) => {
|
|
85
|
+
cb({
|
|
86
|
+
width: entries[0]?.contentRect.width as number,
|
|
87
|
+
height: entries[0]?.contentRect.height as number,
|
|
88
|
+
})
|
|
67
89
|
})
|
|
68
90
|
|
|
69
91
|
if (!instance.scrollElement) {
|
|
@@ -72,10 +94,10 @@ export const observeElementRect = (
|
|
|
72
94
|
|
|
73
95
|
cb(instance.scrollElement.getBoundingClientRect())
|
|
74
96
|
|
|
75
|
-
observer.observe()
|
|
97
|
+
observer.observe(instance.scrollElement)
|
|
76
98
|
|
|
77
99
|
return () => {
|
|
78
|
-
observer.unobserve()
|
|
100
|
+
observer.unobserve(instance.scrollElement)
|
|
79
101
|
}
|
|
80
102
|
}
|
|
81
103
|
|
|
@@ -83,12 +105,12 @@ export const observeWindowRect = (
|
|
|
83
105
|
instance: Virtualizer<any, any>,
|
|
84
106
|
cb: (rect: Rect) => void,
|
|
85
107
|
) => {
|
|
86
|
-
const
|
|
87
|
-
|
|
108
|
+
const memoizedCallback = memoRectCallback(instance, cb)
|
|
109
|
+
const onResize = () =>
|
|
110
|
+
memoizedCallback({
|
|
88
111
|
width: instance.scrollElement.innerWidth,
|
|
89
112
|
height: instance.scrollElement.innerHeight,
|
|
90
113
|
})
|
|
91
|
-
}
|
|
92
114
|
|
|
93
115
|
if (!instance.scrollElement) {
|
|
94
116
|
return
|
|
@@ -106,60 +128,61 @@ export const observeWindowRect = (
|
|
|
106
128
|
}
|
|
107
129
|
}
|
|
108
130
|
|
|
109
|
-
|
|
110
|
-
instance: Virtualizer<any, any>,
|
|
111
|
-
cb: (offset: number) => void,
|
|
112
|
-
) => {
|
|
113
|
-
const onScroll = () =>
|
|
114
|
-
cb(
|
|
115
|
-
instance.scrollElement[
|
|
116
|
-
instance.options.horizontal ? 'scrollLeft' : 'scrollTop'
|
|
117
|
-
],
|
|
118
|
-
)
|
|
131
|
+
type ObserverMode = 'element' | 'window'
|
|
119
132
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
133
|
+
const scrollProps = {
|
|
134
|
+
element: ['scrollLeft', 'scrollTop'],
|
|
135
|
+
window: ['scrollX', 'scrollY'],
|
|
136
|
+
} as const
|
|
123
137
|
|
|
124
|
-
|
|
138
|
+
const createOffsetObserver = (mode: ObserverMode) => {
|
|
139
|
+
return (instance: Virtualizer<any, any>, cb: (offset: number) => void) => {
|
|
140
|
+
if (!instance.scrollElement) {
|
|
141
|
+
return
|
|
142
|
+
}
|
|
125
143
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
passive: true,
|
|
129
|
-
})
|
|
144
|
+
const propX = scrollProps[mode][0]
|
|
145
|
+
const propY = scrollProps[mode][1]
|
|
130
146
|
|
|
131
|
-
|
|
132
|
-
instance.scrollElement
|
|
133
|
-
}
|
|
134
|
-
}
|
|
147
|
+
let prevX: number = instance.scrollElement[propX]
|
|
148
|
+
let prevY: number = instance.scrollElement[propY]
|
|
135
149
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
) => {
|
|
140
|
-
const onScroll = () =>
|
|
141
|
-
cb(
|
|
142
|
-
instance.scrollElement[
|
|
143
|
-
instance.options.horizontal ? 'scrollX' : 'scrollY'
|
|
144
|
-
],
|
|
145
|
-
)
|
|
150
|
+
const scroll = () => {
|
|
151
|
+
const offset =
|
|
152
|
+
instance.scrollElement[instance.options.horizontal ? propX : propY]
|
|
146
153
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
154
|
+
cb(Math.max(0, offset - instance.options.scrollMargin))
|
|
155
|
+
}
|
|
150
156
|
|
|
151
|
-
|
|
157
|
+
scroll()
|
|
152
158
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
159
|
+
const onScroll = (e: Event) => {
|
|
160
|
+
const target = e.currentTarget as HTMLElement & Window
|
|
161
|
+
const scrollX = target[propX]
|
|
162
|
+
const scrollY = target[propY]
|
|
157
163
|
|
|
158
|
-
|
|
159
|
-
|
|
164
|
+
if (instance.options.horizontal ? prevX - scrollX : prevY - scrollY) {
|
|
165
|
+
scroll()
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
prevX = scrollX
|
|
169
|
+
prevY = scrollY
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
instance.scrollElement.addEventListener('scroll', onScroll, {
|
|
173
|
+
capture: false,
|
|
174
|
+
passive: true,
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
return () => {
|
|
178
|
+
instance.scrollElement.removeEventListener('scroll', onScroll)
|
|
179
|
+
}
|
|
160
180
|
}
|
|
161
181
|
}
|
|
162
182
|
|
|
183
|
+
export const observeElementOffset = createOffsetObserver('element')
|
|
184
|
+
export const observeWindowOffset = createOffsetObserver('window')
|
|
185
|
+
|
|
163
186
|
export const measureElement = (
|
|
164
187
|
element: unknown,
|
|
165
188
|
instance: Virtualizer<any, any>,
|
|
@@ -171,22 +194,26 @@ export const measureElement = (
|
|
|
171
194
|
|
|
172
195
|
export const windowScroll = (
|
|
173
196
|
offset: number,
|
|
174
|
-
canSmooth: boolean,
|
|
197
|
+
{ canSmooth, sync }: { canSmooth: boolean; sync: boolean },
|
|
175
198
|
instance: Virtualizer<any, any>,
|
|
176
199
|
) => {
|
|
177
|
-
|
|
178
|
-
|
|
200
|
+
const toOffset = sync ? offset : offset + instance.options.scrollMargin
|
|
201
|
+
|
|
202
|
+
;(instance.scrollElement as Window)?.scrollTo?.({
|
|
203
|
+
[instance.options.horizontal ? 'left' : 'top']: toOffset,
|
|
179
204
|
behavior: canSmooth ? 'smooth' : undefined,
|
|
180
205
|
})
|
|
181
206
|
}
|
|
182
207
|
|
|
183
208
|
export const elementScroll = (
|
|
184
209
|
offset: number,
|
|
185
|
-
canSmooth: boolean,
|
|
210
|
+
{ canSmooth, sync }: { canSmooth: boolean; sync: boolean },
|
|
186
211
|
instance: Virtualizer<any, any>,
|
|
187
212
|
) => {
|
|
188
|
-
|
|
189
|
-
|
|
213
|
+
const toOffset = sync ? offset : offset + instance.options.scrollMargin
|
|
214
|
+
|
|
215
|
+
;(instance.scrollElement as Element)?.scrollTo?.({
|
|
216
|
+
[instance.options.horizontal ? 'left' : 'top']: toOffset,
|
|
190
217
|
behavior: canSmooth ? 'smooth' : undefined,
|
|
191
218
|
})
|
|
192
219
|
}
|
|
@@ -203,7 +230,7 @@ export interface VirtualizerOptions<
|
|
|
203
230
|
// Required from the framework adapter (but can be overridden)
|
|
204
231
|
scrollToFn: (
|
|
205
232
|
offset: number,
|
|
206
|
-
canSmooth: boolean,
|
|
233
|
+
options: { canSmooth: boolean; sync: boolean },
|
|
207
234
|
instance: Virtualizer<TScrollElement, TItemElement>,
|
|
208
235
|
) => void
|
|
209
236
|
observeElementRect: (
|
|
@@ -233,24 +260,39 @@ export interface VirtualizerOptions<
|
|
|
233
260
|
getItemKey?: (index: number) => Key
|
|
234
261
|
rangeExtractor?: (range: Range) => number[]
|
|
235
262
|
enableSmoothScroll?: boolean
|
|
263
|
+
scrollMargin?: number
|
|
264
|
+
scrollingDelay?: number
|
|
236
265
|
}
|
|
237
266
|
|
|
238
267
|
export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
|
|
239
268
|
private unsubs: (void | (() => void))[] = []
|
|
240
269
|
options!: Required<VirtualizerOptions<TScrollElement, TItemElement>>
|
|
241
270
|
scrollElement: TScrollElement | null = null
|
|
271
|
+
isScrolling: boolean = false
|
|
272
|
+
private isScrollingTimeoutId: ReturnType<typeof setTimeout> | null = null
|
|
242
273
|
private measurementsCache: Item[] = []
|
|
243
274
|
private itemMeasurementsCache: Record<Key, number> = {}
|
|
244
275
|
private pendingMeasuredCacheIndexes: number[] = []
|
|
245
276
|
private scrollRect: Rect
|
|
246
277
|
private scrollOffset: number
|
|
278
|
+
private scrollDelta: number = 0
|
|
247
279
|
private destinationOffset: undefined | number
|
|
248
280
|
private scrollCheckFrame!: ReturnType<typeof setTimeout>
|
|
281
|
+
private measureElementCache: Record<
|
|
282
|
+
number,
|
|
283
|
+
(measurableItem: TItemElement | null) => void
|
|
284
|
+
> = {}
|
|
285
|
+
range: { startIndex: number; endIndex: number } = {
|
|
286
|
+
startIndex: 0,
|
|
287
|
+
endIndex: 0,
|
|
288
|
+
}
|
|
249
289
|
|
|
250
290
|
constructor(opts: VirtualizerOptions<TScrollElement, TItemElement>) {
|
|
251
291
|
this.setOptions(opts)
|
|
252
292
|
this.scrollRect = this.options.initialRect
|
|
253
293
|
this.scrollOffset = this.options.initialOffset
|
|
294
|
+
|
|
295
|
+
this.calculateRange()
|
|
254
296
|
}
|
|
255
297
|
|
|
256
298
|
setOptions = (opts: VirtualizerOptions<TScrollElement, TItemElement>) => {
|
|
@@ -273,6 +315,8 @@ export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
|
|
|
273
315
|
onChange: () => {},
|
|
274
316
|
measureElement,
|
|
275
317
|
initialRect: { width: 0, height: 0 },
|
|
318
|
+
scrollMargin: 0,
|
|
319
|
+
scrollingDelay: 150,
|
|
276
320
|
...opts,
|
|
277
321
|
}
|
|
278
322
|
}
|
|
@@ -284,6 +328,7 @@ export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
|
|
|
284
328
|
private cleanup = () => {
|
|
285
329
|
this.unsubs.filter(Boolean).forEach((d) => d!())
|
|
286
330
|
this.unsubs = []
|
|
331
|
+
this.scrollElement = null
|
|
287
332
|
}
|
|
288
333
|
|
|
289
334
|
_didMount = () => {
|
|
@@ -299,20 +344,47 @@ export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
|
|
|
299
344
|
this.cleanup()
|
|
300
345
|
|
|
301
346
|
this.scrollElement = scrollElement
|
|
347
|
+
this._scrollToOffset(this.scrollOffset, {
|
|
348
|
+
canSmooth: false,
|
|
349
|
+
sync: true,
|
|
350
|
+
requested: false,
|
|
351
|
+
})
|
|
302
352
|
|
|
303
353
|
this.unsubs.push(
|
|
304
354
|
this.options.observeElementRect(this, (rect) => {
|
|
305
355
|
this.scrollRect = rect
|
|
306
|
-
this.
|
|
356
|
+
this.calculateRange()
|
|
307
357
|
}),
|
|
308
358
|
)
|
|
309
359
|
|
|
310
360
|
this.unsubs.push(
|
|
311
361
|
this.options.observeElementOffset(this, (offset) => {
|
|
312
|
-
this.
|
|
313
|
-
|
|
362
|
+
if (this.isScrollingTimeoutId !== null) {
|
|
363
|
+
clearTimeout(this.isScrollingTimeoutId)
|
|
364
|
+
this.isScrollingTimeoutId = null
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (this.scrollOffset !== offset) {
|
|
368
|
+
this.scrollOffset = offset
|
|
369
|
+
this.isScrolling = true
|
|
370
|
+
this.scrollDelta = 0
|
|
371
|
+
|
|
372
|
+
this.isScrollingTimeoutId = setTimeout(() => {
|
|
373
|
+
this.isScrollingTimeoutId = null
|
|
374
|
+
this.isScrolling = false
|
|
375
|
+
|
|
376
|
+
this.notify()
|
|
377
|
+
}, this.options.scrollingDelay)
|
|
378
|
+
} else {
|
|
379
|
+
this.isScrolling = false
|
|
380
|
+
this.scrollDelta = 0
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
this.calculateRange()
|
|
314
384
|
}),
|
|
315
385
|
)
|
|
386
|
+
} else if (!this.isScrolling) {
|
|
387
|
+
this.calculateRange()
|
|
316
388
|
}
|
|
317
389
|
}
|
|
318
390
|
|
|
@@ -354,22 +426,30 @@ export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
|
|
|
354
426
|
return measurements
|
|
355
427
|
},
|
|
356
428
|
{
|
|
357
|
-
key: process.env.NODE_ENV
|
|
429
|
+
key: process.env.NODE_ENV !== 'production' && 'getMeasurements',
|
|
358
430
|
debug: () => this.options.debug,
|
|
359
431
|
},
|
|
360
432
|
)
|
|
361
433
|
|
|
362
|
-
|
|
434
|
+
calculateRange = memo(
|
|
363
435
|
() => [this.getMeasurements(), this.getSize(), this.scrollOffset],
|
|
364
436
|
(measurements, outerSize, scrollOffset) => {
|
|
365
|
-
|
|
437
|
+
const range = calculateRange({
|
|
366
438
|
measurements,
|
|
367
439
|
outerSize,
|
|
368
440
|
scrollOffset,
|
|
369
441
|
})
|
|
442
|
+
if (
|
|
443
|
+
range.startIndex !== this.range.startIndex ||
|
|
444
|
+
range.endIndex !== this.range.endIndex
|
|
445
|
+
) {
|
|
446
|
+
this.range = range
|
|
447
|
+
this.notify()
|
|
448
|
+
}
|
|
449
|
+
return this.range
|
|
370
450
|
},
|
|
371
451
|
{
|
|
372
|
-
key: process.env.NODE_ENV
|
|
452
|
+
key: process.env.NODE_ENV !== 'production' && 'calculateRange',
|
|
373
453
|
debug: () => this.options.debug,
|
|
374
454
|
},
|
|
375
455
|
)
|
|
@@ -377,7 +457,7 @@ export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
|
|
|
377
457
|
private getIndexes = memo(
|
|
378
458
|
() => [
|
|
379
459
|
this.options.rangeExtractor,
|
|
380
|
-
this.
|
|
460
|
+
this.range,
|
|
381
461
|
this.options.overscan,
|
|
382
462
|
this.options.count,
|
|
383
463
|
],
|
|
@@ -389,7 +469,8 @@ export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
|
|
|
389
469
|
})
|
|
390
470
|
},
|
|
391
471
|
{
|
|
392
|
-
key: process.env.NODE_ENV
|
|
472
|
+
key: process.env.NODE_ENV !== 'production' && 'getIndexes',
|
|
473
|
+
debug: () => this.options.debug,
|
|
393
474
|
},
|
|
394
475
|
)
|
|
395
476
|
|
|
@@ -400,91 +481,110 @@ export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
|
|
|
400
481
|
this.options.measureElement,
|
|
401
482
|
],
|
|
402
483
|
(indexes, measurements, measureElement) => {
|
|
484
|
+
const makeMeasureElement =
|
|
485
|
+
(index: number) => (measurableItem: TItemElement | null) => {
|
|
486
|
+
const item = this.measurementsCache[index]!
|
|
487
|
+
|
|
488
|
+
if (!measurableItem) {
|
|
489
|
+
return
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
const measuredItemSize = measureElement(measurableItem, this)
|
|
493
|
+
const itemSize = this.itemMeasurementsCache[item.key] ?? item.size
|
|
494
|
+
|
|
495
|
+
if (measuredItemSize !== itemSize) {
|
|
496
|
+
if (item.start < this.scrollOffset) {
|
|
497
|
+
if (process.env.NODE_ENV !== 'production' && this.options.debug) {
|
|
498
|
+
console.info('correction', measuredItemSize - itemSize)
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
if (this.destinationOffset === undefined) {
|
|
502
|
+
this.scrollDelta += measuredItemSize - itemSize
|
|
503
|
+
|
|
504
|
+
this._scrollToOffset(this.scrollOffset + this.scrollDelta, {
|
|
505
|
+
canSmooth: false,
|
|
506
|
+
sync: false,
|
|
507
|
+
requested: false,
|
|
508
|
+
})
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
this.pendingMeasuredCacheIndexes.push(index)
|
|
513
|
+
this.itemMeasurementsCache = {
|
|
514
|
+
...this.itemMeasurementsCache,
|
|
515
|
+
[item.key]: measuredItemSize,
|
|
516
|
+
}
|
|
517
|
+
this.notify()
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
403
521
|
const virtualItems: VirtualItem<TItemElement>[] = []
|
|
404
522
|
|
|
523
|
+
const currentMeasureElements: typeof this.measureElementCache = {}
|
|
524
|
+
|
|
405
525
|
for (let k = 0, len = indexes.length; k < len; k++) {
|
|
406
526
|
const i = indexes[k]!
|
|
407
527
|
const measurement = measurements[i]!
|
|
408
528
|
|
|
409
529
|
const item = {
|
|
410
530
|
...measurement,
|
|
411
|
-
measureElement: (
|
|
412
|
-
|
|
413
|
-
const measuredItemSize = measureElement(measurableItem, this)
|
|
414
|
-
|
|
415
|
-
if (measuredItemSize !== item.size) {
|
|
416
|
-
if (item.start < this.scrollOffset) {
|
|
417
|
-
if (
|
|
418
|
-
process.env.NODE_ENV === 'development' &&
|
|
419
|
-
this.options.debug
|
|
420
|
-
)
|
|
421
|
-
console.info('correction', measuredItemSize - item.size)
|
|
422
|
-
|
|
423
|
-
if (!this.destinationOffset) {
|
|
424
|
-
this._scrollToOffset(
|
|
425
|
-
this.scrollOffset + (measuredItemSize - item.size),
|
|
426
|
-
false,
|
|
427
|
-
)
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
this.pendingMeasuredCacheIndexes.push(i)
|
|
432
|
-
this.itemMeasurementsCache = {
|
|
433
|
-
...this.itemMeasurementsCache,
|
|
434
|
-
[item.key]: measuredItemSize,
|
|
435
|
-
}
|
|
436
|
-
this.notify()
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
},
|
|
531
|
+
measureElement: (currentMeasureElements[i] =
|
|
532
|
+
this.measureElementCache[i] ?? makeMeasureElement(i)),
|
|
440
533
|
}
|
|
441
|
-
|
|
442
534
|
virtualItems.push(item)
|
|
443
535
|
}
|
|
444
536
|
|
|
537
|
+
this.measureElementCache = currentMeasureElements
|
|
538
|
+
|
|
445
539
|
return virtualItems
|
|
446
540
|
},
|
|
447
541
|
{
|
|
448
|
-
key: process.env.NODE_ENV
|
|
542
|
+
key: process.env.NODE_ENV !== 'production' && 'getIndexes',
|
|
543
|
+
debug: () => this.options.debug,
|
|
449
544
|
},
|
|
450
545
|
)
|
|
451
546
|
|
|
452
547
|
scrollToOffset = (
|
|
453
548
|
toOffset: number,
|
|
454
|
-
{
|
|
549
|
+
{
|
|
550
|
+
align = 'start',
|
|
551
|
+
smoothScroll = this.options.enableSmoothScroll,
|
|
552
|
+
}: ScrollToOffsetOptions = {},
|
|
455
553
|
) => {
|
|
456
|
-
const
|
|
457
|
-
|
|
458
|
-
const size = this.getSize()
|
|
459
|
-
|
|
460
|
-
if (align === 'auto') {
|
|
461
|
-
if (toOffset <= offset) {
|
|
462
|
-
align = 'start'
|
|
463
|
-
} else if (toOffset >= offset + size) {
|
|
464
|
-
align = 'end'
|
|
465
|
-
} else {
|
|
466
|
-
align = 'start'
|
|
467
|
-
}
|
|
468
|
-
}
|
|
554
|
+
const offset = this.scrollOffset
|
|
555
|
+
const size = this.getSize()
|
|
469
556
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
557
|
+
if (align === 'auto') {
|
|
558
|
+
if (toOffset <= offset) {
|
|
559
|
+
align = 'start'
|
|
560
|
+
} else if (toOffset >= offset + size) {
|
|
561
|
+
align = 'end'
|
|
562
|
+
} else {
|
|
563
|
+
align = 'start'
|
|
476
564
|
}
|
|
477
565
|
}
|
|
478
566
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
567
|
+
const options = {
|
|
568
|
+
canSmooth: smoothScroll,
|
|
569
|
+
sync: false,
|
|
570
|
+
requested: true,
|
|
571
|
+
}
|
|
572
|
+
if (align === 'start') {
|
|
573
|
+
this._scrollToOffset(toOffset, options)
|
|
574
|
+
} else if (align === 'end') {
|
|
575
|
+
this._scrollToOffset(toOffset - size, options)
|
|
576
|
+
} else if (align === 'center') {
|
|
577
|
+
this._scrollToOffset(toOffset - size / 2, options)
|
|
578
|
+
}
|
|
483
579
|
}
|
|
484
580
|
|
|
485
581
|
scrollToIndex = (
|
|
486
582
|
index: number,
|
|
487
|
-
{
|
|
583
|
+
{
|
|
584
|
+
align = 'auto',
|
|
585
|
+
smoothScroll = this.options.enableSmoothScroll,
|
|
586
|
+
...rest
|
|
587
|
+
}: ScrollToIndexOptions = {},
|
|
488
588
|
) => {
|
|
489
589
|
const measurements = this.getMeasurements()
|
|
490
590
|
const offset = this.scrollOffset
|
|
@@ -515,22 +615,27 @@ export class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {
|
|
|
515
615
|
? measurement.end + this.options.scrollPaddingEnd
|
|
516
616
|
: measurement.start - this.options.scrollPaddingStart
|
|
517
617
|
|
|
518
|
-
this.scrollToOffset(toOffset, { align, ...rest })
|
|
618
|
+
this.scrollToOffset(toOffset, { align, smoothScroll, ...rest })
|
|
519
619
|
}
|
|
520
620
|
|
|
521
621
|
getTotalSize = () =>
|
|
522
622
|
(this.getMeasurements()[this.options.count - 1]?.end ||
|
|
523
623
|
this.options.paddingStart) + this.options.paddingEnd
|
|
524
624
|
|
|
525
|
-
private _scrollToOffset = (
|
|
625
|
+
private _scrollToOffset = (
|
|
626
|
+
offset: number,
|
|
627
|
+
{
|
|
628
|
+
requested,
|
|
629
|
+
canSmooth,
|
|
630
|
+
sync,
|
|
631
|
+
}: { canSmooth: boolean; sync: boolean; requested: boolean },
|
|
632
|
+
) => {
|
|
526
633
|
clearTimeout(this.scrollCheckFrame)
|
|
527
634
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
this,
|
|
533
|
-
)
|
|
635
|
+
if (requested) {
|
|
636
|
+
this.destinationOffset = offset
|
|
637
|
+
}
|
|
638
|
+
this.options.scrollToFn(offset, { canSmooth, sync }, this)
|
|
534
639
|
|
|
535
640
|
let scrollCheckFrame: ReturnType<typeof setTimeout>
|
|
536
641
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../../src/index.ts"],"sourcesContent":["import observeRect from '@reach/observe-rect'\nimport { memo } from './utils'\n\nexport * from './utils'\n\n//\n\ntype ScrollAlignment = 'start' | 'center' | 'end' | 'auto'\n\ninterface ScrollToOptions {\n align: ScrollAlignment\n}\n\ntype ScrollToOffsetOptions = ScrollToOptions\n\ntype ScrollToIndexOptions = ScrollToOptions\n\nexport interface Range {\n startIndex: number\n endIndex: number\n overscan: number\n count: number\n}\n\ntype Key = number | string\n\ninterface Item {\n key: Key\n index: number\n start: number\n end: number\n size: number\n}\n\ninterface Rect {\n width: number\n height: number\n}\n\nexport interface VirtualItem<TItemElement> extends Item {\n measureElement: (el: TItemElement | null) => void\n}\n\n//\n\nexport const defaultKeyExtractor = (index: number) => index\n\nexport const defaultRangeExtractor = (range: Range) => {\n const start = Math.max(range.startIndex - range.overscan, 0)\n const end = Math.min(range.endIndex + range.overscan, range.count - 1)\n\n const arr = []\n\n for (let i = start; i <= end; i++) {\n arr.push(i)\n }\n\n return arr\n}\n\nexport const observeElementRect = (\n instance: Virtualizer<any, any>,\n cb: (rect: Rect) => void,\n) => {\n const observer = observeRect(instance.scrollElement as Element, (rect) => {\n cb(rect)\n })\n\n if (!instance.scrollElement) {\n return\n }\n\n cb(instance.scrollElement.getBoundingClientRect())\n\n observer.observe()\n\n return () => {\n observer.unobserve()\n }\n}\n\nexport const observeWindowRect = (\n instance: Virtualizer<any, any>,\n cb: (rect: Rect) => void,\n) => {\n const onResize = () => {\n cb({\n width: instance.scrollElement.innerWidth,\n height: instance.scrollElement.innerHeight,\n })\n }\n\n if (!instance.scrollElement) {\n return\n }\n\n onResize()\n\n instance.scrollElement.addEventListener('resize', onResize, {\n capture: false,\n passive: true,\n })\n\n return () => {\n instance.scrollElement.removeEventListener('resize', onResize)\n }\n}\n\nexport const observeElementOffset = (\n instance: Virtualizer<any, any>,\n cb: (offset: number) => void,\n) => {\n const onScroll = () =>\n cb(\n instance.scrollElement[\n instance.options.horizontal ? 'scrollLeft' : 'scrollTop'\n ],\n )\n\n if (!instance.scrollElement) {\n return\n }\n\n onScroll()\n\n instance.scrollElement.addEventListener('scroll', onScroll, {\n capture: false,\n passive: true,\n })\n\n return () => {\n instance.scrollElement.removeEventListener('scroll', onScroll)\n }\n}\n\nexport const observeWindowOffset = (\n instance: Virtualizer<any, any>,\n cb: (offset: number) => void,\n) => {\n const onScroll = () =>\n cb(\n instance.scrollElement[\n instance.options.horizontal ? 'scrollX' : 'scrollY'\n ],\n )\n\n if (!instance.scrollElement) {\n return\n }\n\n onScroll()\n\n instance.scrollElement.addEventListener('scroll', onScroll, {\n capture: false,\n passive: true,\n })\n\n return () => {\n instance.scrollElement.removeEventListener('scroll', onScroll)\n }\n}\n\nexport const measureElement = (\n element: unknown,\n instance: Virtualizer<any, any>,\n) => {\n return (element as Element).getBoundingClientRect()[\n instance.options.horizontal ? 'width' : 'height'\n ]\n}\n\nexport const windowScroll = (\n offset: number,\n canSmooth: boolean,\n instance: Virtualizer<any, any>,\n) => {\n ;(instance.scrollElement as Window)?.scrollTo({\n [instance.options.horizontal ? 'left' : 'top']: offset,\n behavior: canSmooth ? 'smooth' : undefined,\n })\n}\n\nexport const elementScroll = (\n offset: number,\n canSmooth: boolean,\n instance: Virtualizer<any, any>,\n) => {\n ;(instance.scrollElement as Element)?.scrollTo({\n [instance.options.horizontal ? 'left' : 'top']: offset,\n behavior: canSmooth ? 'smooth' : undefined,\n })\n}\n\nexport interface VirtualizerOptions<\n TScrollElement = unknown,\n TItemElement = unknown,\n> {\n // Required from the user\n count: number\n getScrollElement: () => TScrollElement\n estimateSize: (index: number) => number\n\n // Required from the framework adapter (but can be overridden)\n scrollToFn: (\n offset: number,\n canSmooth: boolean,\n instance: Virtualizer<TScrollElement, TItemElement>,\n ) => void\n observeElementRect: (\n instance: Virtualizer<TScrollElement, TItemElement>,\n cb: (rect: Rect) => void,\n ) => void | (() => void)\n observeElementOffset: (\n instance: Virtualizer<TScrollElement, TItemElement>,\n cb: (offset: number) => void,\n ) => void | (() => void)\n\n // Optional\n debug?: any\n initialRect?: Rect\n onChange?: (instance: Virtualizer<TScrollElement, TItemElement>) => void\n measureElement?: (\n el: TItemElement,\n instance: Virtualizer<TScrollElement, TItemElement>,\n ) => number\n overscan?: number\n horizontal?: boolean\n paddingStart?: number\n paddingEnd?: number\n scrollPaddingStart?: number\n scrollPaddingEnd?: number\n initialOffset?: number\n getItemKey?: (index: number) => Key\n rangeExtractor?: (range: Range) => number[]\n enableSmoothScroll?: boolean\n}\n\nexport class Virtualizer<TScrollElement = unknown, TItemElement = unknown> {\n private unsubs: (void | (() => void))[] = []\n options!: Required<VirtualizerOptions<TScrollElement, TItemElement>>\n scrollElement: TScrollElement | null = null\n private measurementsCache: Item[] = []\n private itemMeasurementsCache: Record<Key, number> = {}\n private pendingMeasuredCacheIndexes: number[] = []\n private scrollRect: Rect\n private scrollOffset: number\n private destinationOffset: undefined | number\n private scrollCheckFrame!: ReturnType<typeof setTimeout>\n\n constructor(opts: VirtualizerOptions<TScrollElement, TItemElement>) {\n this.setOptions(opts)\n this.scrollRect = this.options.initialRect\n this.scrollOffset = this.options.initialOffset\n }\n\n setOptions = (opts: VirtualizerOptions<TScrollElement, TItemElement>) => {\n Object.entries(opts).forEach(([key, value]) => {\n if (typeof value === 'undefined') delete (opts as any)[key]\n })\n\n this.options = {\n debug: false,\n initialOffset: 0,\n overscan: 1,\n paddingStart: 0,\n paddingEnd: 0,\n scrollPaddingStart: 0,\n scrollPaddingEnd: 0,\n horizontal: false,\n getItemKey: defaultKeyExtractor,\n rangeExtractor: defaultRangeExtractor,\n enableSmoothScroll: true,\n onChange: () => {},\n measureElement,\n initialRect: { width: 0, height: 0 },\n ...opts,\n }\n }\n\n private notify = () => {\n this.options.onChange?.(this)\n }\n\n private cleanup = () => {\n this.unsubs.filter(Boolean).forEach((d) => d!())\n this.unsubs = []\n }\n\n _didMount = () => {\n return () => {\n this.cleanup()\n }\n }\n\n _willUpdate = () => {\n const scrollElement = this.options.getScrollElement()\n\n if (this.scrollElement !== scrollElement) {\n this.cleanup()\n\n this.scrollElement = scrollElement\n\n this.unsubs.push(\n this.options.observeElementRect(this, (rect) => {\n this.scrollRect = rect\n this.notify()\n }),\n )\n\n this.unsubs.push(\n this.options.observeElementOffset(this, (offset) => {\n this.scrollOffset = offset\n this.notify()\n }),\n )\n }\n }\n\n private getSize = () => {\n return this.scrollRect[this.options.horizontal ? 'width' : 'height']\n }\n\n private getMeasurements = memo(\n () => [\n this.options.count,\n this.options.paddingStart,\n this.options.getItemKey,\n this.itemMeasurementsCache,\n ],\n (count, paddingStart, getItemKey, measurementsCache) => {\n const min =\n this.pendingMeasuredCacheIndexes.length > 0\n ? Math.min(...this.pendingMeasuredCacheIndexes)\n : 0\n this.pendingMeasuredCacheIndexes = []\n\n const measurements = this.measurementsCache.slice(0, min)\n\n for (let i = min; i < count; i++) {\n const key = getItemKey(i)\n const measuredSize = measurementsCache[key]\n const start = measurements[i - 1]\n ? measurements[i - 1]!.end\n : paddingStart\n const size =\n typeof measuredSize === 'number'\n ? measuredSize\n : this.options.estimateSize(i)\n const end = start + size\n measurements[i] = { index: i, start, size, end, key }\n }\n\n this.measurementsCache = measurements\n return measurements\n },\n {\n key: process.env.NODE_ENV === 'development' && 'getMeasurements',\n debug: () => this.options.debug,\n },\n )\n\n private calculateRange = memo(\n () => [this.getMeasurements(), this.getSize(), this.scrollOffset],\n (measurements, outerSize, scrollOffset) => {\n return calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n })\n },\n {\n key: process.env.NODE_ENV === 'development' && 'calculateRange',\n debug: () => this.options.debug,\n },\n )\n\n private getIndexes = memo(\n () => [\n this.options.rangeExtractor,\n this.calculateRange(),\n this.options.overscan,\n this.options.count,\n ],\n (rangeExtractor, range, overscan, count) => {\n return rangeExtractor({\n ...range,\n overscan,\n count: count,\n })\n },\n {\n key: process.env.NODE_ENV === 'development' && 'getIndexes',\n },\n )\n\n getVirtualItems = memo(\n () => [\n this.getIndexes(),\n this.getMeasurements(),\n this.options.measureElement,\n ],\n (indexes, measurements, measureElement) => {\n const virtualItems: VirtualItem<TItemElement>[] = []\n\n for (let k = 0, len = indexes.length; k < len; k++) {\n const i = indexes[k]!\n const measurement = measurements[i]!\n\n const item = {\n ...measurement,\n measureElement: (measurableItem: TItemElement | null) => {\n if (measurableItem) {\n const measuredItemSize = measureElement(measurableItem, this)\n\n if (measuredItemSize !== item.size) {\n if (item.start < this.scrollOffset) {\n if (\n process.env.NODE_ENV === 'development' &&\n this.options.debug\n )\n console.info('correction', measuredItemSize - item.size)\n\n if (!this.destinationOffset) {\n this._scrollToOffset(\n this.scrollOffset + (measuredItemSize - item.size),\n false,\n )\n }\n }\n\n this.pendingMeasuredCacheIndexes.push(i)\n this.itemMeasurementsCache = {\n ...this.itemMeasurementsCache,\n [item.key]: measuredItemSize,\n }\n this.notify()\n }\n }\n },\n }\n\n virtualItems.push(item)\n }\n\n return virtualItems\n },\n {\n key: process.env.NODE_ENV === 'development' && 'getIndexes',\n },\n )\n\n scrollToOffset = (\n toOffset: number,\n { align }: ScrollToOffsetOptions = { align: 'start' },\n ) => {\n const attempt = () => {\n const offset = this.scrollOffset\n const size = this.getSize()\n\n if (align === 'auto') {\n if (toOffset <= offset) {\n align = 'start'\n } else if (toOffset >= offset + size) {\n align = 'end'\n } else {\n align = 'start'\n }\n }\n\n if (align === 'start') {\n this._scrollToOffset(toOffset, true)\n } else if (align === 'end') {\n this._scrollToOffset(toOffset - size, true)\n } else if (align === 'center') {\n this._scrollToOffset(toOffset - size / 2, true)\n }\n }\n\n attempt()\n requestAnimationFrame(() => {\n attempt()\n })\n }\n\n scrollToIndex = (\n index: number,\n { align, ...rest }: ScrollToIndexOptions = { align: 'auto' },\n ) => {\n const measurements = this.getMeasurements()\n const offset = this.scrollOffset\n const size = this.getSize()\n const { count } = this.options\n\n const measurement = measurements[Math.max(0, Math.min(index, count - 1))]\n\n if (!measurement) {\n return\n }\n\n if (align === 'auto') {\n if (measurement.end >= offset + size - this.options.scrollPaddingEnd) {\n align = 'end'\n } else if (\n measurement.start <=\n offset + this.options.scrollPaddingStart\n ) {\n align = 'start'\n } else {\n return\n }\n }\n\n const toOffset =\n align === 'end'\n ? measurement.end + this.options.scrollPaddingEnd\n : measurement.start - this.options.scrollPaddingStart\n\n this.scrollToOffset(toOffset, { align, ...rest })\n }\n\n getTotalSize = () =>\n (this.getMeasurements()[this.options.count - 1]?.end ||\n this.options.paddingStart) + this.options.paddingEnd\n\n private _scrollToOffset = (offset: number, canSmooth: boolean) => {\n clearTimeout(this.scrollCheckFrame)\n\n this.destinationOffset = offset\n this.options.scrollToFn(\n offset,\n this.options.enableSmoothScroll && canSmooth,\n this,\n )\n\n let scrollCheckFrame: ReturnType<typeof setTimeout>\n\n const check = () => {\n let lastOffset = this.scrollOffset\n this.scrollCheckFrame = scrollCheckFrame = setTimeout(() => {\n if (this.scrollCheckFrame !== scrollCheckFrame) {\n return\n }\n\n if (this.scrollOffset === lastOffset) {\n this.destinationOffset = undefined\n return\n }\n lastOffset = this.scrollOffset\n check()\n }, 100)\n }\n\n check()\n }\n\n measure = () => {\n this.itemMeasurementsCache = {}\n this.notify()\n }\n}\n\nconst findNearestBinarySearch = (\n low: number,\n high: number,\n getCurrentValue: (i: number) => number,\n value: number,\n) => {\n while (low <= high) {\n const middle = ((low + high) / 2) | 0\n const currentValue = getCurrentValue(middle)\n\n if (currentValue < value) {\n low = middle + 1\n } else if (currentValue > value) {\n high = middle - 1\n } else {\n return middle\n }\n }\n\n if (low > 0) {\n return low - 1\n } else {\n return 0\n }\n}\n\nfunction calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n}: {\n measurements: Item[]\n outerSize: number\n scrollOffset: number\n}) {\n const count = measurements.length - 1\n const getOffset = (index: number) => measurements[index]!.start\n\n const startIndex = findNearestBinarySearch(0, count, getOffset, scrollOffset)\n let endIndex = startIndex\n\n while (\n endIndex < count &&\n measurements[endIndex]!.end < scrollOffset + outerSize\n ) {\n endIndex++\n }\n\n return { startIndex, endIndex }\n}\n"],"names":["defaultKeyExtractor","index","defaultRangeExtractor","range","start","Math","max","startIndex","overscan","end","min","endIndex","count","arr","i","push","observeElementRect","instance","cb","observer","observeRect","scrollElement","rect","getBoundingClientRect","observe","unobserve","observeWindowRect","onResize","width","innerWidth","height","innerHeight","addEventListener","capture","passive","removeEventListener","observeElementOffset","onScroll","options","horizontal","observeWindowOffset","measureElement","element","windowScroll","offset","canSmooth","scrollTo","behavior","undefined","elementScroll","Virtualizer","constructor","opts","unsubs","measurementsCache","itemMeasurementsCache","pendingMeasuredCacheIndexes","setOptions","Object","entries","forEach","key","value","debug","initialOffset","paddingStart","paddingEnd","scrollPaddingStart","scrollPaddingEnd","getItemKey","rangeExtractor","enableSmoothScroll","onChange","initialRect","notify","cleanup","filter","Boolean","d","_didMount","_willUpdate","getScrollElement","scrollRect","scrollOffset","getSize","getMeasurements","memo","length","measurements","slice","measuredSize","size","estimateSize","process","env","NODE_ENV","calculateRange","outerSize","getIndexes","getVirtualItems","indexes","virtualItems","k","len","measurement","item","measurableItem","measuredItemSize","console","info","destinationOffset","_scrollToOffset","scrollToOffset","toOffset","align","attempt","requestAnimationFrame","scrollToIndex","rest","getTotalSize","clearTimeout","scrollCheckFrame","scrollToFn","check","lastOffset","setTimeout","measure","findNearestBinarySearch","low","high","getCurrentValue","middle","currentValue","getOffset"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../../../../src/utils.ts"],"sourcesContent":["export type NoInfer<A extends any> = [A][A extends any ? 0 : never]\n\nexport type PartialKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\n\nexport function memo<TDeps extends readonly any[], TResult>(\n getDeps: () => [...TDeps],\n fn: (...args: NoInfer<[...TDeps]>) => TResult,\n opts: {\n key: any\n debug?: () => any\n onChange?: (result: TResult) => void\n },\n): () => TResult {\n let deps: any[] = []\n let result: TResult | undefined\n\n return () => {\n let depTime: number\n if (opts.key && opts.debug?.()) depTime = Date.now()\n\n const newDeps = getDeps()\n\n const depsChanged =\n newDeps.length !== deps.length ||\n newDeps.some((dep: any, index: number) => deps[index] !== dep)\n\n if (!depsChanged) {\n return result!\n }\n\n deps = newDeps\n\n let resultTime: number\n if (opts.key && opts.debug?.()) resultTime = Date.now()\n\n result = fn(...newDeps)\n opts?.onChange?.(result)\n\n if (opts.key && opts.debug?.()) {\n const depEndTime = Math.round((Date.now() - depTime!) * 100) / 100\n const resultEndTime = Math.round((Date.now() - resultTime!) * 100) / 100\n const resultFpsPercentage = resultEndTime / 16\n\n const pad = (str: number | string, num: number) => {\n str = String(str)\n while (str.length < num) {\n str = ' ' + str\n }\n return str\n }\n\n console.info(\n `%c⏱ ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`,\n `\n font-size: .6rem;\n font-weight: bold;\n color: hsl(${Math.max(\n 0,\n Math.min(120 - 120 * resultFpsPercentage, 120),\n )}deg 100% 31%);`,\n opts?.key,\n )\n }\n\n return result!\n }\n}\n"],"names":["memo","getDeps","fn","opts","deps","result","depTime","key","debug","Date","now","newDeps","depsChanged","length","some","dep","index","resultTime","onChange","depEndTime","Math","round","resultEndTime","resultFpsPercentage","pad","str","num","String","console","info","max","min"],"mappings":";;;;;;;;;;;;;;AAIO,SAASA,IAAT,CACLC,OADK,EAELC,EAFK,EAGLC,IAHK,EAQU;EACf,IAAIC,IAAW,GAAG,EAAlB,CAAA;AACA,EAAA,IAAIC,MAAJ,CAAA;AAEA,EAAA,OAAO,MAAM;AACX,IAAA,IAAIC,OAAJ,CAAA;AACA,IAAA,IAAIH,IAAI,CAACI,GAAL,IAAYJ,IAAI,CAACK,KAAjB,IAAYL,IAAAA,IAAAA,IAAI,CAACK,KAAL,EAAhB,EAAgCF,OAAO,GAAGG,IAAI,CAACC,GAAL,EAAV,CAAA;IAEhC,MAAMC,OAAO,GAAGV,OAAO,EAAvB,CAAA;IAEA,MAAMW,WAAW,GACfD,OAAO,CAACE,MAAR,KAAmBT,IAAI,CAACS,MAAxB,IACAF,OAAO,CAACG,IAAR,CAAa,CAACC,GAAD,EAAWC,KAAX,KAA6BZ,IAAI,CAACY,KAAD,CAAJ,KAAgBD,GAA1D,CAFF,CAAA;;IAIA,IAAI,CAACH,WAAL,EAAkB;AAChB,MAAA,OAAOP,MAAP,CAAA;AACD,KAAA;;AAEDD,IAAAA,IAAI,GAAGO,OAAP,CAAA;AAEA,IAAA,IAAIM,UAAJ,CAAA;AACA,IAAA,IAAId,IAAI,CAACI,GAAL,IAAYJ,IAAI,CAACK,KAAjB,IAAYL,IAAAA,IAAAA,IAAI,CAACK,KAAL,EAAhB,EAAgCS,UAAU,GAAGR,IAAI,CAACC,GAAL,EAAb,CAAA;AAEhCL,IAAAA,MAAM,GAAGH,EAAE,CAAC,GAAGS,OAAJ,CAAX,CAAA;IACAR,IAAI,IAAA,IAAJ,GAAAA,KAAAA,CAAAA,GAAAA,IAAI,CAAEe,QAAN,oBAAAf,IAAI,CAAEe,QAAN,CAAiBb,MAAjB,CAAA,CAAA;;AAEA,IAAA,IAAIF,IAAI,CAACI,GAAL,IAAYJ,IAAI,CAACK,KAAjB,IAAA,IAAA,IAAYL,IAAI,CAACK,KAAL,EAAhB,EAAgC;AAC9B,MAAA,MAAMW,UAAU,GAAGC,IAAI,CAACC,KAAL,CAAW,CAACZ,IAAI,CAACC,GAAL,EAAaJ,GAAAA,OAAd,IAA0B,GAArC,IAA4C,GAA/D,CAAA;AACA,MAAA,MAAMgB,aAAa,GAAGF,IAAI,CAACC,KAAL,CAAW,CAACZ,IAAI,CAACC,GAAL,EAAaO,GAAAA,UAAd,IAA6B,GAAxC,IAA+C,GAArE,CAAA;AACA,MAAA,MAAMM,mBAAmB,GAAGD,aAAa,GAAG,EAA5C,CAAA;;AAEA,MAAA,MAAME,GAAG,GAAG,CAACC,GAAD,EAAuBC,GAAvB,KAAuC;AACjDD,QAAAA,GAAG,GAAGE,MAAM,CAACF,GAAD,CAAZ,CAAA;;AACA,QAAA,OAAOA,GAAG,CAACZ,MAAJ,GAAaa,GAApB,EAAyB;UACvBD,GAAG,GAAG,MAAMA,GAAZ,CAAA;AACD,SAAA;;AACD,QAAA,OAAOA,GAAP,CAAA;OALF,CAAA;;AAQAG,MAAAA,OAAO,CAACC,IAAR,CAAA,WAAA,GACSL,GAAG,CAACF,aAAD,EAAgB,CAAhB,CADZ,GAAA,IAAA,GACmCE,GAAG,CAACL,UAAD,EAAa,CAAb,CADtC,uGAKmBC,IAAI,CAACU,GAAL,CACX,CADW,EAEXV,IAAI,CAACW,GAAL,CAAS,MAAM,GAAMR,GAAAA,mBAArB,EAA0C,GAA1C,CAFW,CALnB,GAAA,gBAAA,EASEpB,IATF,IASEA,IAAAA,GAAAA,KAAAA,CAAAA,GAAAA,IAAI,CAAEI,GATR,CAAA,CAAA;AAWD,KAAA;;AAED,IAAA,OAAOF,MAAP,CAAA;GAhDF,CAAA;AAkDD;;;;"}
|