@brytdesigns/web-component-parallax 1.2.17 → 1.2.18

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.
@@ -1,52 +1,35 @@
1
- import { createWithElementContext, getContextFromProvider } from '@brytdesigns/web-component-core/utils';
2
- import { createContext, provide, consume } from 'component-register';
3
- import { motionValue, frame, animate } from 'motion';
4
1
  import { splitProps, createEffect, onCleanup, mergeProps } from 'solid-js';
5
- import { normalizeTuple, isInRange } from '../utils';
2
+ import { createContext, provide, consume } from 'component-register';
3
+ import { motionValue, transformValue, transform, frame, animate } from 'motion';
4
+ import { awaitAllAnimations } from '@brytdesigns/web-component-core/animation';
5
+ import { abortablePromise } from '@brytdesigns/web-component-core/promise';
6
+ import { createWithElementContext, getContextFromProvider } from '@brytdesigns/web-component-core/utils';
6
7
  import { useParallax } from './useParallax';
8
+ import { normalizeTuple, isInRange } from '../utils';
7
9
 
8
- const HANDOFF_EASE = "easeOut";
9
- const ENTER_HYSTERESIS = 1e-3;
10
- const EXIT_HYSTERESIS = 5e-3;
11
- const HANDOFF_MIN_DELTA_PX = 0.75;
12
- const EXIT_WAIT_TIMEOUT_MS = 500;
13
- const PREDICT_LOOKAHEAD_MS = 28;
14
- const PREDICT_ENTER_BAND = 6e-3;
15
- const PREDICT_EXIT_BAND = 0.01;
16
- const PREDICT_MIN_VELOCITY = 4e-4;
17
- const LOW_VELOCITY_NO_TWEEN = 1e-3;
18
- const HIGH_VELOCITY_SKIP_HANDOFF = 0.01;
19
- const MAX_PREDICT_LOOKAHEAD_MS = 60;
20
- const MAX_HANDOFF_DELTA_PX = 56;
21
- function supportsStickyPosition() {
22
- if (typeof CSS === "undefined" || typeof CSS.supports !== "function") {
23
- return false;
24
- }
25
- return CSS.supports("position", "sticky") || CSS.supports("position", "-webkit-sticky");
26
- }
27
10
  function initializeParallaxStickyLayerContext(props) {
28
11
  const [_internal, _state] = splitProps(props, ["root", "start", "end"]);
29
12
  const parallax = useParallax(_internal.root);
30
- const stickySupported = supportsStickyPosition();
31
13
  const progress = motionValue(-1);
32
- const rawScrollProgress = motionValue(-1);
33
14
  const inRange = motionValue(false);
34
15
  const belowRange = motionValue(false);
35
16
  const aboveRange = motionValue(false);
36
- const normStartValue = motionValue(0);
37
- const normEndValue = motionValue(1);
38
- const mode = motionValue("absolute-below");
39
- const handoffOffsetY = motionValue(0);
40
- const activeContentAnimations = /* @__PURE__ */ new Set();
41
- let handoffAnimation = null;
42
- let exitWaitRaf = null;
43
- let exitWaitTimeout = null;
44
- let pendingExitVersion = 0;
45
- let pendingExitMode = null;
46
- let lastScrollSampleValue = 0;
47
- let lastScrollSampleTime = 0;
48
- let hasScrollSample = false;
49
- let latestScrollVelocity = 0;
17
+ const position = transformValue(
18
+ () => inRange.get() ? "sticky" : "absolute"
19
+ );
20
+ const transform$1 = transformValue(() => {
21
+ const isInRange2 = inRange.get();
22
+ const isBelowRange = belowRange.get();
23
+ const isAboveRange = aboveRange.get();
24
+ if (isInRange2) return "none";
25
+ if (isBelowRange) return `translate(0px, ${(_internal.start - 1) * 100}vh)`;
26
+ if (isAboveRange) return `translate(0px, ${(_internal.end - 1) * 100}vh)`;
27
+ });
28
+ const animations = motionValue([]);
29
+ const styles = transformValue(() => ({
30
+ position: position.get(),
31
+ transform: transform$1.get()
32
+ }));
50
33
  _internal.root.style.top = "0px";
51
34
  _internal.root.style.right = "0px";
52
35
  _internal.root.style.bottom = "0px";
@@ -57,315 +40,51 @@ function initializeParallaxStickyLayerContext(props) {
57
40
  if (window.getComputedStyle(_internal.root).display === "inline") {
58
41
  _internal.root.style.display = "block";
59
42
  }
60
- function updateStyles() {
61
- if (!stickySupported) {
62
- const normStart = normStartValue.get();
63
- const normEnd = normEndValue.get();
64
- const raw = rawScrollProgress.get();
65
- const span = Math.max(normEnd - normStart, Number.EPSILON);
66
- const t = Math.min(Math.max((raw - normStart) / span, 0), 1);
67
- const pageY = _internal.start - 1 + t * (_internal.end - _internal.start);
68
- _internal.root.style.position = "absolute";
69
- _internal.root.style.transform = `translate(0px, ${pageY * 100}vh)`;
70
- return;
71
- }
72
- const currentMode = mode.get();
73
- const offset = handoffOffsetY.get();
74
- const hasOffset = Math.abs(offset) >= 0.1;
75
- if (currentMode === "sticky") {
76
- _internal.root.style.position = "sticky";
77
- _internal.root.style.transform = hasOffset ? `translate(0px, ${offset}px)` : "none";
78
- return;
79
- }
80
- const baseTransform = currentMode === "absolute-below" ? `translate(0px, ${(_internal.start - 1) * 100}vh)` : `translate(0px, ${(_internal.end - 1) * 100}vh)`;
81
- _internal.root.style.position = "absolute";
82
- _internal.root.style.transform = hasOffset ? `${baseTransform} translate(0px, ${offset}px)` : baseTransform;
83
- }
84
- function renderStyles() {
85
- frame.render(updateStyles);
86
- }
87
- function stopHandoffAnimation() {
88
- handoffAnimation?.stop();
89
- handoffAnimation = null;
90
- handoffOffsetY.set(0);
91
- }
92
- function clearExitWaitHandles() {
93
- if (exitWaitRaf !== null) {
94
- window.cancelAnimationFrame(exitWaitRaf);
95
- exitWaitRaf = null;
96
- }
97
- if (exitWaitTimeout !== null) {
98
- window.clearTimeout(exitWaitTimeout);
99
- exitWaitTimeout = null;
100
- }
101
- }
102
- function pruneFinishedAnimations() {
103
- for (const animation of activeContentAnimations) {
104
- if (animation.state !== "running") {
105
- activeContentAnimations.delete(animation);
106
- }
107
- }
108
- }
109
- function hasActiveContentAnimations() {
110
- pruneFinishedAnimations();
111
- return activeContentAnimations.size > 0;
112
- }
113
- function registerContentAnimation(animation) {
114
- activeContentAnimations.add(animation);
115
- animation.then(
116
- () => {
117
- activeContentAnimations.delete(animation);
118
- },
119
- () => {
120
- activeContentAnimations.delete(animation);
121
- }
122
- );
123
- }
124
- function getHandoffDuration(deltaY, velocity) {
125
- const speed = Math.abs(velocity);
126
- if (speed <= LOW_VELOCITY_NO_TWEEN) return 0;
127
- const byDistance = Math.min(0.12, Math.max(0.05, Math.abs(deltaY) / 1400));
128
- const speedScale = Math.min(speed / 0.01, 1);
129
- return Math.max(0.04, byDistance - speedScale * 0.02);
130
- }
131
- function settleHandoffOverFrames(deltaY, frameCount) {
132
- handoffOffsetY.set(deltaY);
133
- updateStyles();
134
- let remainingFrames = Math.max(frameCount, 1);
135
- const settle = () => {
136
- remainingFrames -= 1;
137
- if (remainingFrames <= 0) {
138
- handoffOffsetY.set(0);
139
- updateStyles();
140
- return;
141
- }
142
- frame.render(settle);
143
- };
144
- frame.render(settle);
145
- }
146
- function cancelPendingExit() {
147
- pendingExitVersion += 1;
148
- pendingExitMode = null;
149
- clearExitWaitHandles();
150
- }
151
- function commitModeImmediately(nextMode) {
152
- stopHandoffAnimation();
153
- mode.set(nextMode);
154
- updateStyles();
155
- }
156
- function waitForAnimations(nextMode) {
157
- if (pendingExitMode === nextMode && (exitWaitRaf !== null || exitWaitTimeout !== null)) {
158
- return;
159
- }
160
- cancelPendingExit();
161
- pendingExitMode = nextMode;
162
- const version = pendingExitVersion;
163
- const completeExit = () => {
164
- if (version !== pendingExitVersion) return;
165
- clearExitWaitHandles();
166
- pendingExitMode = null;
167
- const latest = Math.min(Math.max(rawScrollProgress.get(), 0), 1);
168
- const stableMode = getTargetMode(
169
- latest,
170
- normStartValue.get(),
171
- normEndValue.get()
172
- );
173
- if (stableMode !== nextMode) return;
174
- commitModeImmediately(nextMode);
175
- };
176
- if (!hasActiveContentAnimations()) {
177
- completeExit();
178
- return;
179
- }
180
- const tick = () => {
181
- if (version !== pendingExitVersion) return;
182
- if (!hasActiveContentAnimations()) {
183
- completeExit();
184
- return;
185
- }
186
- exitWaitRaf = window.requestAnimationFrame(tick);
187
- };
188
- exitWaitTimeout = window.setTimeout(() => {
189
- completeExit();
190
- }, EXIT_WAIT_TIMEOUT_MS);
191
- exitWaitRaf = window.requestAnimationFrame(tick);
192
- }
193
- function getTargetMode(value, normStart, normEnd) {
194
- if (!stickySupported) {
195
- if (value <= normStart) return "absolute-below";
196
- if (value >= normEnd) return "absolute-above";
197
- return "absolute-below";
198
- }
199
- const current = mode.get();
200
- if (current === "sticky") {
201
- if (value < normStart - EXIT_HYSTERESIS) return "absolute-below";
202
- if (value > normEnd + EXIT_HYSTERESIS) return "absolute-above";
203
- return "sticky";
204
- }
205
- if (current === "absolute-below") {
206
- if (value >= normStart + ENTER_HYSTERESIS) return "sticky";
207
- return "absolute-below";
208
- }
209
- if (value <= normEnd - ENTER_HYSTERESIS) return "sticky";
210
- return "absolute-above";
211
- }
212
- function getModeDecisionValue(value, normStart, normEnd, allowPrediction) {
213
- const now = performance.now();
214
- let velocity = 0;
215
- if (hasScrollSample) {
216
- const elapsed = Math.max(now - lastScrollSampleTime, 1);
217
- velocity = (value - lastScrollSampleValue) / elapsed;
218
- }
219
- lastScrollSampleValue = value;
220
- lastScrollSampleTime = now;
221
- hasScrollSample = true;
222
- latestScrollVelocity = velocity;
223
- if (!allowPrediction || Math.abs(velocity) < PREDICT_MIN_VELOCITY) {
224
- return value;
225
- }
226
- const speed = Math.abs(velocity);
227
- const speedScale = Math.min(speed / HIGH_VELOCITY_SKIP_HANDOFF, 1);
228
- const lookaheadMs = PREDICT_LOOKAHEAD_MS + speedScale * (MAX_PREDICT_LOOKAHEAD_MS - PREDICT_LOOKAHEAD_MS);
229
- const predicted = Math.min(Math.max(value + velocity * lookaheadMs, 0), 1);
230
- const currentMode = mode.get();
231
- if (currentMode === "absolute-below") {
232
- const entryEdge = normStart + ENTER_HYSTERESIS;
233
- const nearStart = Math.abs(value - entryEdge) <= PREDICT_ENTER_BAND;
234
- if (velocity > 0 && nearStart && value < entryEdge && predicted >= entryEdge) {
235
- return entryEdge;
236
- }
237
- }
238
- if (currentMode === "absolute-above") {
239
- const entryEdge = normEnd - ENTER_HYSTERESIS;
240
- const nearEnd = Math.abs(value - entryEdge) <= PREDICT_ENTER_BAND;
241
- if (velocity < 0 && nearEnd && value > entryEdge && predicted <= entryEdge) {
242
- return entryEdge;
243
- }
244
- }
245
- if (currentMode === "sticky") {
246
- const exitTopEdge = normStart - EXIT_HYSTERESIS;
247
- const exitBottomEdge = normEnd + EXIT_HYSTERESIS;
248
- const nearTop = Math.abs(value - exitTopEdge) <= PREDICT_EXIT_BAND;
249
- if (velocity < 0 && nearTop && value > exitTopEdge && predicted <= exitTopEdge) {
250
- return exitTopEdge;
251
- }
252
- const nearBottom = Math.abs(value - exitBottomEdge) <= PREDICT_EXIT_BAND;
253
- if (velocity > 0 && nearBottom && value < exitBottomEdge && predicted >= exitBottomEdge) {
254
- return exitBottomEdge;
255
- }
256
- }
257
- return value;
258
- }
259
- function applyModeWithHandoff(nextMode) {
260
- if (!stickySupported) {
261
- stopHandoffAnimation();
262
- mode.set(nextMode);
263
- renderStyles();
264
- return;
265
- }
266
- stopHandoffAnimation();
267
- const prevRect = _internal.root.getBoundingClientRect();
268
- mode.set(nextMode);
269
- updateStyles();
270
- const nextRect = _internal.root.getBoundingClientRect();
271
- const deltaY = prevRect.top - nextRect.top;
272
- if (Math.abs(deltaY) <= HANDOFF_MIN_DELTA_PX) {
273
- handoffOffsetY.set(0);
274
- renderStyles();
275
- return;
276
- }
277
- if (Math.abs(latestScrollVelocity) >= HIGH_VELOCITY_SKIP_HANDOFF || Math.abs(deltaY) >= MAX_HANDOFF_DELTA_PX) {
278
- settleHandoffOverFrames(deltaY, 2);
279
- return;
280
- }
281
- handoffOffsetY.set(deltaY);
282
- updateStyles();
283
- const duration = getHandoffDuration(deltaY, latestScrollVelocity);
284
- if (duration <= 0) {
285
- settleHandoffOverFrames(deltaY, 1);
286
- return;
287
- }
288
- handoffAnimation = animate([
289
- [handoffOffsetY, 0, { duration, ease: HANDOFF_EASE }]
290
- ]);
291
- handoffAnimation.then(() => {
292
- if (!handoffAnimation) return;
293
- handoffAnimation = null;
294
- handoffOffsetY.set(0);
295
- renderStyles();
296
- });
297
- }
298
- function syncFromScroll(value, allowHandoff) {
299
- const clamped = Math.min(Math.max(value, 0), 1);
300
- rawScrollProgress.set(clamped);
301
- const normStart = normStartValue.get();
302
- const normEnd = normEndValue.get();
303
- const range = [normStart, normEnd];
304
- const span = Math.max(normEnd - normStart, Number.EPSILON);
305
- const normalizedProgress = Math.min(
306
- Math.max((clamped - normStart) / span, 0),
307
- 1
308
- );
309
- inRange.set(isInRange({ range, value: clamped }));
310
- belowRange.set(clamped <= normStart);
311
- aboveRange.set(clamped >= normEnd);
312
- progress.set(normalizedProgress);
313
- const decisionValue = getModeDecisionValue(
314
- clamped,
315
- normStart,
316
- normEnd,
317
- allowHandoff
318
- );
319
- const nextMode = getTargetMode(decisionValue, normStart, normEnd);
320
- const currentMode = mode.get();
321
- if (currentMode === "sticky" && nextMode !== "sticky" && allowHandoff) {
322
- waitForAnimations(nextMode);
323
- updateStyles();
324
- return;
325
- }
326
- cancelPendingExit();
327
- if (nextMode === currentMode) {
328
- if (!allowHandoff) {
329
- stopHandoffAnimation();
330
- updateStyles();
331
- }
332
- return;
333
- }
334
- if (allowHandoff) {
335
- applyModeWithHandoff(nextMode);
336
- return;
337
- }
338
- commitModeImmediately(nextMode);
339
- }
340
43
  createEffect(() => {
341
44
  const range = [_internal.start, _internal.end];
342
45
  const maxPages = parallax.maxPages;
343
46
  const normalizedRange = normalizeTuple(range, maxPages);
344
47
  const [normStart, normEnd] = normalizedRange;
345
- normStartValue.set(normStart);
346
- normEndValue.set(normEnd);
347
- const initialValue = parallax.scrollYProgress.get();
348
- syncFromScroll(initialValue, false);
349
- renderStyles();
48
+ const transformer = transform(normalizedRange, [0, 1]);
350
49
  const unsubscribe = parallax.scrollYProgress.on("change", (value) => {
351
- syncFromScroll(value, true);
50
+ inRange.set(isInRange({ range: normalizedRange, value }));
51
+ belowRange.set(value <= normStart);
52
+ aboveRange.set(value >= normEnd);
53
+ progress.set(transformer(value));
352
54
  });
353
55
  return onCleanup(() => {
354
56
  unsubscribe();
355
57
  });
356
58
  });
357
- const unsubHandoffOffset = handoffOffsetY.on("change", (_) => {
59
+ function updateStyles() {
60
+ const s = styles.get();
61
+ _internal.root.style.position = s.position;
62
+ _internal.root.style.transform = s.transform;
63
+ }
64
+ function renderStyles() {
65
+ frame.render(updateStyles);
66
+ }
67
+ function waitForAnimations() {
68
+ const a = animations.get();
69
+ const controller = new AbortController();
70
+ abortablePromise(awaitAllAnimations(a), controller.signal).then(() => {
71
+ animations.set([]);
72
+ renderStyles();
73
+ });
74
+ }
75
+ const unsubStyles = styles.on("change", (_) => {
76
+ if (progress.get() === 1 || progress.get() === 0)
77
+ return waitForAnimations();
78
+ animations.set([]);
358
79
  renderStyles();
359
80
  });
360
81
  function _animate(...args) {
361
82
  const animation = animate(...args);
362
- registerContentAnimation(animation);
83
+ animations.set([...animations.get(), animation]);
363
84
  return animation;
364
85
  }
365
86
  onCleanup(() => {
366
- cancelPendingExit();
367
- stopHandoffAnimation();
368
- unsubHandoffOffset();
87
+ unsubStyles();
369
88
  });
370
89
  return [progress, { animate: _animate }];
371
90
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/hooks/useParallaxStickyLayer.ts"],"names":[],"mappings":";;;;;;;AAkCA,MAAM,YAAe,GAAA,SAAA;AACrB,MAAM,gBAAmB,GAAA,IAAA;AACzB,MAAM,eAAkB,GAAA,IAAA;AACxB,MAAM,oBAAuB,GAAA,IAAA;AAC7B,MAAM,oBAAuB,GAAA,GAAA;AAC7B,MAAM,oBAAuB,GAAA,EAAA;AAC7B,MAAM,kBAAqB,GAAA,IAAA;AAC3B,MAAM,iBAAoB,GAAA,IAAA;AAC1B,MAAM,oBAAuB,GAAA,IAAA;AAC7B,MAAM,qBAAwB,GAAA,IAAA;AAC9B,MAAM,0BAA6B,GAAA,IAAA;AACnC,MAAM,wBAA2B,GAAA,EAAA;AACjC,MAAM,oBAAuB,GAAA,EAAA;AAE7B,SAAS,sBAAyB,GAAA;AACjC,EAAA,IAAI,OAAO,GAAQ,KAAA,WAAA,IAAe,OAAO,GAAA,CAAI,aAAa,UAAY,EAAA;AACrE,IAAO,OAAA,KAAA;AAAA;AAGR,EACC,OAAA,GAAA,CAAI,SAAS,UAAY,EAAA,QAAQ,KACjC,GAAI,CAAA,QAAA,CAAS,YAAY,gBAAgB,CAAA;AAE3C;AAEA,SAAS,qCAAqC,KAA6B,EAAA;AAC1E,EAAM,MAAA,CAAC,SAAW,EAAA,MAAM,CAAI,GAAA,UAAA,CAAW,OAAO,CAAC,MAAA,EAAQ,OAAS,EAAA,KAAK,CAAC,CAAA;AACtE,EAAM,MAAA,QAAA,GAAW,WAAY,CAAA,SAAA,CAAU,IAAI,CAAA;AAC3C,EAAA,MAAM,kBAAkB,sBAAuB,EAAA;AAE/C,EAAM,MAAA,QAAA,GAAW,YAAY,EAAE,CAAA;AAC/B,EAAM,MAAA,iBAAA,GAAoB,YAAY,EAAE,CAAA;AACxC,EAAM,MAAA,OAAA,GAAU,YAAY,KAAK,CAAA;AACjC,EAAM,MAAA,UAAA,GAAa,YAAY,KAAK,CAAA;AACpC,EAAM,MAAA,UAAA,GAAa,YAAY,KAAK,CAAA;AACpC,EAAM,MAAA,cAAA,GAAiB,YAAY,CAAC,CAAA;AACpC,EAAM,MAAA,YAAA,GAAe,YAAY,CAAC,CAAA;AAClC,EAAM,MAAA,IAAA,GAAO,YAAuB,gBAAgB,CAAA;AACpD,EAAM,MAAA,cAAA,GAAiB,YAAY,CAAC,CAAA;AAEpC,EAAM,MAAA,uBAAA,uBAA8B,GAAuC,EAAA;AAC3E,EAAA,IAAI,gBAA6D,GAAA,IAAA;AACjE,EAAA,IAAI,WAA6B,GAAA,IAAA;AACjC,EAAA,IAAI,eAAiC,GAAA,IAAA;AACrC,EAAA,IAAI,kBAAqB,GAAA,CAAA;AACzB,EAAA,IAAI,eAAoC,GAAA,IAAA;AACxC,EAAA,IAAI,qBAAwB,GAAA,CAAA;AAC5B,EAAA,IAAI,oBAAuB,GAAA,CAAA;AAC3B,EAAA,IAAI,eAAkB,GAAA,KAAA;AACtB,EAAA,IAAI,oBAAuB,GAAA,CAAA;AAE3B,EAAU,SAAA,CAAA,IAAA,CAAK,MAAM,GAAM,GAAA,KAAA;AAC3B,EAAU,SAAA,CAAA,IAAA,CAAK,MAAM,KAAQ,GAAA,KAAA;AAC7B,EAAU,SAAA,CAAA,IAAA,CAAK,MAAM,MAAS,GAAA,KAAA;AAC9B,EAAU,SAAA,CAAA,IAAA,CAAK,MAAM,IAAO,GAAA,KAAA;AAC5B,EAAU,SAAA,CAAA,IAAA,CAAK,MAAM,MAAS,GAAA,CAAA,MAAA,CAAA;AAC9B,EAAU,SAAA,CAAA,IAAA,CAAK,MAAM,SAAY,GAAA,QAAA;AACjC,EAAU,SAAA,CAAA,IAAA,CAAK,MAAM,QAAW,GAAA,MAAA;AAChC,EAAA,IAAI,OAAO,gBAAiB,CAAA,SAAA,CAAU,IAAI,CAAA,CAAE,YAAY,QAAU,EAAA;AACjE,IAAU,SAAA,CAAA,IAAA,CAAK,MAAM,OAAU,GAAA,OAAA;AAAA;AAGhC,EAAA,SAAS,YAAe,GAAA;AACvB,IAAA,IAAI,CAAC,eAAiB,EAAA;AACrB,MAAM,MAAA,SAAA,GAAY,eAAe,GAAI,EAAA;AACrC,MAAM,MAAA,OAAA,GAAU,aAAa,GAAI,EAAA;AACjC,MAAM,MAAA,GAAA,GAAM,kBAAkB,GAAI,EAAA;AAClC,MAAA,MAAM,OAAO,IAAK,CAAA,GAAA,CAAI,OAAU,GAAA,SAAA,EAAW,OAAO,OAAO,CAAA;AACzD,MAAM,MAAA,CAAA,GAAI,IAAK,CAAA,GAAA,CAAI,IAAK,CAAA,GAAA,CAAA,CAAK,MAAM,SAAa,IAAA,IAAA,EAAM,CAAC,CAAA,EAAG,CAAC,CAAA;AAC3D,MAAA,MAAM,QAAQ,SAAU,CAAA,KAAA,GAAQ,IAAI,CAAK,IAAA,SAAA,CAAU,MAAM,SAAU,CAAA,KAAA,CAAA;AAEnE,MAAU,SAAA,CAAA,IAAA,CAAK,MAAM,QAAW,GAAA,UAAA;AAChC,MAAA,SAAA,CAAU,IAAK,CAAA,KAAA,CAAM,SAAY,GAAA,CAAA,eAAA,EAAkB,QAAQ,GAAG,CAAA,GAAA,CAAA;AAC9D,MAAA;AAAA;AAGD,IAAM,MAAA,WAAA,GAAc,KAAK,GAAI,EAAA;AAC7B,IAAM,MAAA,MAAA,GAAS,eAAe,GAAI,EAAA;AAClC,IAAA,MAAM,SAAY,GAAA,IAAA,CAAK,GAAI,CAAA,MAAM,CAAK,IAAA,GAAA;AAEtC,IAAA,IAAI,gBAAgB,QAAU,EAAA;AAC7B,MAAU,SAAA,CAAA,IAAA,CAAK,MAAM,QAAW,GAAA,QAAA;AAChC,MAAA,SAAA,CAAU,KAAK,KAAM,CAAA,SAAA,GAAY,SAC9B,GAAA,CAAA,eAAA,EAAkB,MAAM,CACxB,GAAA,CAAA,GAAA,MAAA;AACH,MAAA;AAAA;AAGD,IAAA,MAAM,aACL,GAAA,WAAA,KAAgB,gBACb,GAAA,CAAA,eAAA,EAAA,CAAmB,SAAU,CAAA,KAAA,GAAQ,CAAK,IAAA,GAAG,CAC7C,GAAA,CAAA,GAAA,CAAA,eAAA,EAAA,CAAmB,SAAU,CAAA,GAAA,GAAM,KAAK,GAAG,CAAA,GAAA,CAAA;AAE/C,IAAU,SAAA,CAAA,IAAA,CAAK,MAAM,QAAW,GAAA,UAAA;AAChC,IAAU,SAAA,CAAA,IAAA,CAAK,MAAM,SAAY,GAAA,SAAA,GAC9B,GAAG,aAAa,CAAA,gBAAA,EAAmB,MAAM,CACzC,GAAA,CAAA,GAAA,aAAA;AAAA;AAGJ,EAAA,SAAS,YAAe,GAAA;AACvB,IAAA,KAAA,CAAM,OAAO,YAAY,CAAA;AAAA;AAG1B,EAAA,SAAS,oBAAuB,GAAA;AAC/B,IAAA,gBAAA,EAAkB,IAAK,EAAA;AACvB,IAAmB,gBAAA,GAAA,IAAA;AACnB,IAAA,cAAA,CAAe,IAAI,CAAC,CAAA;AAAA;AAGrB,EAAA,SAAS,oBAAuB,GAAA;AAC/B,IAAA,IAAI,gBAAgB,IAAM,EAAA;AACzB,MAAA,MAAA,CAAO,qBAAqB,WAAW,CAAA;AACvC,MAAc,WAAA,GAAA,IAAA;AAAA;AAEf,IAAA,IAAI,oBAAoB,IAAM,EAAA;AAC7B,MAAA,MAAA,CAAO,aAAa,eAAe,CAAA;AACnC,MAAkB,eAAA,GAAA,IAAA;AAAA;AACnB;AAGD,EAAA,SAAS,uBAA0B,GAAA;AAClC,IAAA,KAAA,MAAW,aAAa,uBAAyB,EAAA;AAChD,MAAI,IAAA,SAAA,CAAU,UAAU,SAAW,EAAA;AAClC,QAAA,uBAAA,CAAwB,OAAO,SAAS,CAAA;AAAA;AACzC;AACD;AAGD,EAAA,SAAS,0BAA6B,GAAA;AACrC,IAAwB,uBAAA,EAAA;AACxB,IAAA,OAAO,wBAAwB,IAAO,GAAA,CAAA;AAAA;AAGvC,EAAA,SAAS,yBACR,SACC,EAAA;AACD,IAAA,uBAAA,CAAwB,IAAI,SAAS,CAAA;AACrC,IAAU,SAAA,CAAA,IAAA;AAAA,MACT,MAAM;AACL,QAAA,uBAAA,CAAwB,OAAO,SAAS,CAAA;AAAA,OACzC;AAAA,MACA,MAAM;AACL,QAAA,uBAAA,CAAwB,OAAO,SAAS,CAAA;AAAA;AACzC,KACD;AAAA;AAGD,EAAS,SAAA,kBAAA,CAAmB,QAAgB,QAAkB,EAAA;AAC7D,IAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,GAAA,CAAI,QAAQ,CAAA;AAC/B,IAAI,IAAA,KAAA,IAAS,uBAA8B,OAAA,CAAA;AAE3C,IAAA,MAAM,UAAa,GAAA,IAAA,CAAK,GAAI,CAAA,IAAA,EAAM,IAAK,CAAA,GAAA,CAAI,IAAM,EAAA,IAAA,CAAK,GAAI,CAAA,MAAM,CAAI,GAAA,IAAI,CAAC,CAAA;AACzE,IAAA,MAAM,UAAa,GAAA,IAAA,CAAK,GAAI,CAAA,KAAA,GAAQ,MAAM,CAAC,CAAA;AAC3C,IAAA,OAAO,IAAK,CAAA,GAAA,CAAI,IAAM,EAAA,UAAA,GAAa,aAAa,IAAI,CAAA;AAAA;AAGrD,EAAS,SAAA,uBAAA,CAAwB,QAAgB,UAAoB,EAAA;AACpE,IAAA,cAAA,CAAe,IAAI,MAAM,CAAA;AACzB,IAAa,YAAA,EAAA;AAEb,IAAA,IAAI,eAAkB,GAAA,IAAA,CAAK,GAAI,CAAA,UAAA,EAAY,CAAC,CAAA;AAC5C,IAAA,MAAM,SAAS,MAAM;AACpB,MAAmB,eAAA,IAAA,CAAA;AACnB,MAAA,IAAI,mBAAmB,CAAG,EAAA;AACzB,QAAA,cAAA,CAAe,IAAI,CAAC,CAAA;AACpB,QAAa,YAAA,EAAA;AACb,QAAA;AAAA;AAED,MAAA,KAAA,CAAM,OAAO,MAAM,CAAA;AAAA,KACpB;AAEA,IAAA,KAAA,CAAM,OAAO,MAAM,CAAA;AAAA;AAGpB,EAAA,SAAS,iBAAoB,GAAA;AAC5B,IAAsB,kBAAA,IAAA,CAAA;AACtB,IAAkB,eAAA,GAAA,IAAA;AAClB,IAAqB,oBAAA,EAAA;AAAA;AAGtB,EAAA,SAAS,sBAAsB,QAAqB,EAAA;AACnD,IAAqB,oBAAA,EAAA;AACrB,IAAA,IAAA,CAAK,IAAI,QAAQ,CAAA;AACjB,IAAa,YAAA,EAAA;AAAA;AAGd,EAAA,SAAS,kBAAkB,QAAqB,EAAA;AAC/C,IAAA,IACC,eAAoB,KAAA,QAAA,KACnB,WAAgB,KAAA,IAAA,IAAQ,oBAAoB,IAC5C,CAAA,EAAA;AACD,MAAA;AAAA;AAGD,IAAkB,iBAAA,EAAA;AAClB,IAAkB,eAAA,GAAA,QAAA;AAClB,IAAA,MAAM,OAAU,GAAA,kBAAA;AAEhB,IAAA,MAAM,eAAe,MAAM;AAC1B,MAAA,IAAI,YAAY,kBAAoB,EAAA;AACpC,MAAqB,oBAAA,EAAA;AACrB,MAAkB,eAAA,GAAA,IAAA;AAElB,MAAM,MAAA,MAAA,GAAS,IAAK,CAAA,GAAA,CAAI,IAAK,CAAA,GAAA,CAAI,kBAAkB,GAAI,EAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA;AAC/D,MAAA,MAAM,UAAa,GAAA,aAAA;AAAA,QAClB,MAAA;AAAA,QACA,eAAe,GAAI,EAAA;AAAA,QACnB,aAAa,GAAI;AAAA,OAClB;AACA,MAAA,IAAI,eAAe,QAAU,EAAA;AAE7B,MAAA,qBAAA,CAAsB,QAAQ,CAAA;AAAA,KAC/B;AAEA,IAAI,IAAA,CAAC,4BAA8B,EAAA;AAClC,MAAa,YAAA,EAAA;AACb,MAAA;AAAA;AAGD,IAAA,MAAM,OAAO,MAAM;AAClB,MAAA,IAAI,YAAY,kBAAoB,EAAA;AACpC,MAAI,IAAA,CAAC,4BAA8B,EAAA;AAClC,QAAa,YAAA,EAAA;AACb,QAAA;AAAA;AAGD,MAAc,WAAA,GAAA,MAAA,CAAO,sBAAsB,IAAI,CAAA;AAAA,KAChD;AAEA,IAAkB,eAAA,GAAA,MAAA,CAAO,WAAW,MAAM;AACzC,MAAa,YAAA,EAAA;AAAA,OACX,oBAAoB,CAAA;AACvB,IAAc,WAAA,GAAA,MAAA,CAAO,sBAAsB,IAAI,CAAA;AAAA;AAGhD,EAAS,SAAA,aAAA,CAAc,KAAe,EAAA,SAAA,EAAmB,OAAiB,EAAA;AACzE,IAAA,IAAI,CAAC,eAAiB,EAAA;AACrB,MAAI,IAAA,KAAA,IAAS,WAAkB,OAAA,gBAAA;AAC/B,MAAI,IAAA,KAAA,IAAS,SAAgB,OAAA,gBAAA;AAC7B,MAAO,OAAA,gBAAA;AAAA;AAGR,IAAM,MAAA,OAAA,GAAU,KAAK,GAAI,EAAA;AACzB,IAAA,IAAI,YAAY,QAAU,EAAA;AACzB,MAAI,IAAA,KAAA,GAAQ,SAAY,GAAA,eAAA,EAAwB,OAAA,gBAAA;AAChD,MAAI,IAAA,KAAA,GAAQ,OAAU,GAAA,eAAA,EAAwB,OAAA,gBAAA;AAC9C,MAAO,OAAA,QAAA;AAAA;AAGR,IAAA,IAAI,YAAY,gBAAkB,EAAA;AACjC,MAAI,IAAA,KAAA,IAAS,SAAY,GAAA,gBAAA,EAAyB,OAAA,QAAA;AAClD,MAAO,OAAA,gBAAA;AAAA;AAGR,IAAI,IAAA,KAAA,IAAS,OAAU,GAAA,gBAAA,EAAyB,OAAA,QAAA;AAChD,IAAO,OAAA,gBAAA;AAAA;AAGR,EAAA,SAAS,oBACR,CAAA,KAAA,EACA,SACA,EAAA,OAAA,EACA,eACC,EAAA;AACD,IAAM,MAAA,GAAA,GAAM,YAAY,GAAI,EAAA;AAC5B,IAAA,IAAI,QAAW,GAAA,CAAA;AAEf,IAAA,IAAI,eAAiB,EAAA;AACpB,MAAA,MAAM,OAAU,GAAA,IAAA,CAAK,GAAI,CAAA,GAAA,GAAM,sBAAsB,CAAC,CAAA;AACtD,MAAA,QAAA,GAAA,CAAY,QAAQ,qBAAyB,IAAA,OAAA;AAAA;AAG9C,IAAwB,qBAAA,GAAA,KAAA;AACxB,IAAuB,oBAAA,GAAA,GAAA;AACvB,IAAkB,eAAA,GAAA,IAAA;AAClB,IAAuB,oBAAA,GAAA,QAAA;AAEvB,IAAA,IAAI,CAAC,eAAmB,IAAA,IAAA,CAAK,GAAI,CAAA,QAAQ,IAAI,oBAAsB,EAAA;AAClE,MAAO,OAAA,KAAA;AAAA;AAGR,IAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,GAAA,CAAI,QAAQ,CAAA;AAC/B,IAAA,MAAM,UAAa,GAAA,IAAA,CAAK,GAAI,CAAA,KAAA,GAAQ,4BAA4B,CAAC,CAAA;AACjE,IAAM,MAAA,WAAA,GACL,oBACA,GAAA,UAAA,IAAc,wBAA2B,GAAA,oBAAA,CAAA;AAE1C,IAAM,MAAA,SAAA,GAAY,IAAK,CAAA,GAAA,CAAI,IAAK,CAAA,GAAA,CAAI,QAAQ,QAAW,GAAA,WAAA,EAAa,CAAC,CAAA,EAAG,CAAC,CAAA;AAEzE,IAAM,MAAA,WAAA,GAAc,KAAK,GAAI,EAAA;AAC7B,IAAA,IAAI,gBAAgB,gBAAkB,EAAA;AACrC,MAAA,MAAM,YAAY,SAAY,GAAA,gBAAA;AAC9B,MAAA,MAAM,SAAY,GAAA,IAAA,CAAK,GAAI,CAAA,KAAA,GAAQ,SAAS,CAAK,IAAA,kBAAA;AACjD,MAAA,IACC,WAAW,CACX,IAAA,SAAA,IACA,KAAQ,GAAA,SAAA,IACR,aAAa,SACZ,EAAA;AACD,QAAO,OAAA,SAAA;AAAA;AACR;AAGD,IAAA,IAAI,gBAAgB,gBAAkB,EAAA;AACrC,MAAA,MAAM,YAAY,OAAU,GAAA,gBAAA;AAC5B,MAAA,MAAM,OAAU,GAAA,IAAA,CAAK,GAAI,CAAA,KAAA,GAAQ,SAAS,CAAK,IAAA,kBAAA;AAC/C,MAAA,IACC,WAAW,CACX,IAAA,OAAA,IACA,KAAQ,GAAA,SAAA,IACR,aAAa,SACZ,EAAA;AACD,QAAO,OAAA,SAAA;AAAA;AACR;AAGD,IAAA,IAAI,gBAAgB,QAAU,EAAA;AAC7B,MAAA,MAAM,cAAc,SAAY,GAAA,eAAA;AAChC,MAAA,MAAM,iBAAiB,OAAU,GAAA,eAAA;AAEjC,MAAA,MAAM,OAAU,GAAA,IAAA,CAAK,GAAI,CAAA,KAAA,GAAQ,WAAW,CAAK,IAAA,iBAAA;AACjD,MAAA,IACC,WAAW,CACX,IAAA,OAAA,IACA,KAAQ,GAAA,WAAA,IACR,aAAa,WACZ,EAAA;AACD,QAAO,OAAA,WAAA;AAAA;AAGR,MAAA,MAAM,UAAa,GAAA,IAAA,CAAK,GAAI,CAAA,KAAA,GAAQ,cAAc,CAAK,IAAA,iBAAA;AACvD,MAAA,IACC,WAAW,CACX,IAAA,UAAA,IACA,KAAQ,GAAA,cAAA,IACR,aAAa,cACZ,EAAA;AACD,QAAO,OAAA,cAAA;AAAA;AACR;AAGD,IAAO,OAAA,KAAA;AAAA;AAGR,EAAA,SAAS,qBAAqB,QAAqB,EAAA;AAClD,IAAA,IAAI,CAAC,eAAiB,EAAA;AACrB,MAAqB,oBAAA,EAAA;AACrB,MAAA,IAAA,CAAK,IAAI,QAAQ,CAAA;AACjB,MAAa,YAAA,EAAA;AACb,MAAA;AAAA;AAGD,IAAqB,oBAAA,EAAA;AAErB,IAAM,MAAA,QAAA,GAAW,SAAU,CAAA,IAAA,CAAK,qBAAsB,EAAA;AACtD,IAAA,IAAA,CAAK,IAAI,QAAQ,CAAA;AACjB,IAAa,YAAA,EAAA;AAEb,IAAM,MAAA,QAAA,GAAW,SAAU,CAAA,IAAA,CAAK,qBAAsB,EAAA;AACtD,IAAM,MAAA,MAAA,GAAS,QAAS,CAAA,GAAA,GAAM,QAAS,CAAA,GAAA;AACvC,IAAA,IAAI,IAAK,CAAA,GAAA,CAAI,MAAM,CAAA,IAAK,oBAAsB,EAAA;AAC7C,MAAA,cAAA,CAAe,IAAI,CAAC,CAAA;AACpB,MAAa,YAAA,EAAA;AACb,MAAA;AAAA;AAGD,IACC,IAAA,IAAA,CAAK,IAAI,oBAAoB,CAAA,IAAK,8BAClC,IAAK,CAAA,GAAA,CAAI,MAAM,CAAA,IAAK,oBACnB,EAAA;AACD,MAAA,uBAAA,CAAwB,QAAQ,CAAC,CAAA;AACjC,MAAA;AAAA;AAGD,IAAA,cAAA,CAAe,IAAI,MAAM,CAAA;AACzB,IAAa,YAAA,EAAA;AACb,IAAM,MAAA,QAAA,GAAW,kBAAmB,CAAA,MAAA,EAAQ,oBAAoB,CAAA;AAChE,IAAA,IAAI,YAAY,CAAG,EAAA;AAClB,MAAA,uBAAA,CAAwB,QAAQ,CAAC,CAAA;AACjC,MAAA;AAAA;AAGD,IAAA,gBAAA,GAAmB,OAAQ,CAAA;AAAA,MAC1B,CAAC,cAAgB,EAAA,CAAA,EAAG,EAAE,QAAU,EAAA,IAAA,EAAM,cAAc;AAAA,KACpD,CAAA;AACD,IAAA,gBAAA,CAAiB,KAAK,MAAM;AAC3B,MAAA,IAAI,CAAC,gBAAkB,EAAA;AACvB,MAAmB,gBAAA,GAAA,IAAA;AACnB,MAAA,cAAA,CAAe,IAAI,CAAC,CAAA;AACpB,MAAa,YAAA,EAAA;AAAA,KACb,CAAA;AAAA;AAGF,EAAS,SAAA,cAAA,CAAe,OAAe,YAAuB,EAAA;AAC7D,IAAM,MAAA,OAAA,GAAU,KAAK,GAAI,CAAA,IAAA,CAAK,IAAI,KAAO,EAAA,CAAC,GAAG,CAAC,CAAA;AAC9C,IAAA,iBAAA,CAAkB,IAAI,OAAO,CAAA;AAE7B,IAAM,MAAA,SAAA,GAAY,eAAe,GAAI,EAAA;AACrC,IAAM,MAAA,OAAA,GAAU,aAAa,GAAI,EAAA;AACjC,IAAM,MAAA,KAAA,GAAQ,CAAC,SAAA,EAAW,OAAO,CAAA;AACjC,IAAA,MAAM,OAAO,IAAK,CAAA,GAAA,CAAI,OAAU,GAAA,SAAA,EAAW,OAAO,OAAO,CAAA;AACzD,IAAA,MAAM,qBAAqB,IAAK,CAAA,GAAA;AAAA,MAC/B,IAAK,CAAA,GAAA,CAAA,CAAK,OAAU,GAAA,SAAA,IAAa,MAAM,CAAC,CAAA;AAAA,MACxC;AAAA,KACD;AAEA,IAAA,OAAA,CAAQ,IAAI,SAAU,CAAA,EAAE,OAAO,KAAO,EAAA,OAAA,EAAS,CAAC,CAAA;AAChD,IAAW,UAAA,CAAA,GAAA,CAAI,WAAW,SAAS,CAAA;AACnC,IAAW,UAAA,CAAA,GAAA,CAAI,WAAW,OAAO,CAAA;AACjC,IAAA,QAAA,CAAS,IAAI,kBAAkB,CAAA;AAE/B,IAAA,MAAM,aAAgB,GAAA,oBAAA;AAAA,MACrB,OAAA;AAAA,MACA,SAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA,KACD;AACA,IAAA,MAAM,QAAW,GAAA,aAAA,CAAc,aAAe,EAAA,SAAA,EAAW,OAAO,CAAA;AAChE,IAAM,MAAA,WAAA,GAAc,KAAK,GAAI,EAAA;AAE7B,IAAA,IAAI,WAAgB,KAAA,QAAA,IAAY,QAAa,KAAA,QAAA,IAAY,YAAc,EAAA;AACtE,MAAA,iBAAA,CAAkB,QAAQ,CAAA;AAC1B,MAAa,YAAA,EAAA;AACb,MAAA;AAAA;AAGD,IAAkB,iBAAA,EAAA;AAClB,IAAA,IAAI,aAAa,WAAa,EAAA;AAC7B,MAAA,IAAI,CAAC,YAAc,EAAA;AAClB,QAAqB,oBAAA,EAAA;AACrB,QAAa,YAAA,EAAA;AAAA;AAEd,MAAA;AAAA;AAGD,IAAA,IAAI,YAAc,EAAA;AACjB,MAAA,oBAAA,CAAqB,QAAQ,CAAA;AAC7B,MAAA;AAAA;AAGD,IAAA,qBAAA,CAAsB,QAAQ,CAAA;AAAA;AAG/B,EAAA,YAAA,CAAa,MAAM;AAClB,IAAA,MAAM,KAAQ,GAAA,CAAC,SAAU,CAAA,KAAA,EAAO,UAAU,GAAG,CAAA;AAC7C,IAAA,MAAM,WAAW,QAAS,CAAA,QAAA;AAC1B,IAAM,MAAA,eAAA,GAAkB,cAAe,CAAA,KAAA,EAAc,QAAQ,CAAA;AAC7D,IAAM,MAAA,CAAC,SAAW,EAAA,OAAO,CAAI,GAAA,eAAA;AAC7B,IAAA,cAAA,CAAe,IAAI,SAAS,CAAA;AAC5B,IAAA,YAAA,CAAa,IAAI,OAAO,CAAA;AAExB,IAAM,MAAA,YAAA,GAAe,QAAS,CAAA,eAAA,CAAgB,GAAI,EAAA;AAClD,IAAA,cAAA,CAAe,cAAc,KAAK,CAAA;AAClC,IAAa,YAAA,EAAA;AAEb,IAAA,MAAM,cAAc,QAAS,CAAA,eAAA,CAAgB,EAAG,CAAA,QAAA,EAAU,CAAC,KAAU,KAAA;AACpE,MAAA,cAAA,CAAe,OAAO,IAAI,CAAA;AAAA,KAC1B,CAAA;AAED,IAAA,OAAO,UAAU,MAAM;AACtB,MAAY,WAAA,EAAA;AAAA,KACZ,CAAA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,kBAAqB,GAAA,cAAA,CAAe,EAAG,CAAA,QAAA,EAAU,CAAC,CAAM,KAAA;AAC7D,IAAa,YAAA,EAAA;AAAA,GACb,CAAA;AAED,EAAA,SAAS,YAAY,IAAkC,EAAA;AACtD,IAAM,MAAA,SAAA,GAAY,OAAQ,CAAA,GAAG,IAAI,CAAA;AACjC,IAAA,wBAAA,CAAyB,SAAS,CAAA;AAClC,IAAO,OAAA,SAAA;AAAA;AAGR,EAAA,SAAA,CAAU,MAAM;AACf,IAAkB,iBAAA,EAAA;AAClB,IAAqB,oBAAA,EAAA;AACrB,IAAmB,kBAAA,EAAA;AAAA,GACnB,CAAA;AAED,EAAA,OAAO,CAAC,QAAA,EAAU,EAAE,OAAA,EAAS,UAAU,CAAA;AACxC;AAEA,MAAM,+BAAkC,GAAA,aAAA;AAAA,EACvC;AACD,CAAA;AAEa,MAAA,iCAAA,GAAoC,CAChD,YAAA,EACA,OACgC,KAAA;AAChC,EAAA,MAAM,QAAQ,UAAW,CAAA,YAAA,EAAc,EAAE,IAAA,EAAM,SAAS,CAAA;AACxD,EAAO,OAAA,OAAA,CAAQ,+BAAiC,EAAA,KAAA,EAAO,OAAO,CAAA;AAC/D;AAEa,MAAA,6BAAA,GAAgC,CAC5C,OACI,KAAA;AACJ,EAAO,OAAA,OAAA;AACR;AAEa,MAAA,sBAAA,GAAyB,CACrC,OACI,KAAA;AACJ,EAAA,MAAM,OAAsC,GAAA,OAAA;AAAA,IAC3C,+BAAA;AAAA,IACA;AAAA,GACD;AAEA,EAAA,IAAI,CAAC,OAAS,EAAA;AACb,IAAA,MAAM,OAAQ,CAAA,KAAA;AAAA,MACb;AAAA,KACD;AAAA;AAGD,EAAA,OAAO,8BAA8B,OAAO,CAAA;AAC7C;AAEa,MAAA,8BAAA,GAAiC,yBAG5C,+BAA+B;AAEpB,MAAA,6BAAA,GAAgC,CAAC,OAAqB,KAAA;AAClE,EAAA,MAAM,OAAU,GAAA,sBAAA;AAAA,IACf,+BAAA;AAAA,IACA;AAAA,GACD;AACA,EAAA,OAAO,8BAA8B,OAAO,CAAA;AAC7C","file":"useParallaxStickyLayer.js","sourcesContent":["import {\n\tcreateWithElementContext,\n\tgetContextFromProvider,\n} from \"@brytdesigns/web-component-core/utils\";\nimport {\n\tconsume,\n\tcreateContext,\n\ttype ICustomElement,\n\tprovide,\n} from \"component-register\";\nimport {\n\ttype AnimationPlaybackControlsWithThen,\n\tanimate,\n\tframe,\n\tmotionValue,\n} from \"motion\";\nimport { createEffect, mergeProps, onCleanup, splitProps } from \"solid-js\";\nimport { isInRange, normalizeTuple } from \"../utils\";\nimport { useParallax } from \"./useParallax\";\n\ntype CreateContextOptions = {\n\troot: HTMLElement & ICustomElement;\n\tstart: number;\n\tend: number;\n};\n\ntype WalkableNode = Parameters<typeof provide>[2];\n\ntype ParallaxStickyLayerContext = ReturnType<\n\ttypeof initializeParallaxStickyLayerContext\n>;\n\ntype LayerMode = \"absolute-below\" | \"sticky\" | \"absolute-above\";\n\nconst HANDOFF_EASE = \"easeOut\";\nconst ENTER_HYSTERESIS = 0.001;\nconst EXIT_HYSTERESIS = 0.005;\nconst HANDOFF_MIN_DELTA_PX = 0.75;\nconst EXIT_WAIT_TIMEOUT_MS = 500;\nconst PREDICT_LOOKAHEAD_MS = 28;\nconst PREDICT_ENTER_BAND = 0.006;\nconst PREDICT_EXIT_BAND = 0.01;\nconst PREDICT_MIN_VELOCITY = 0.0004;\nconst LOW_VELOCITY_NO_TWEEN = 0.001;\nconst HIGH_VELOCITY_SKIP_HANDOFF = 0.01;\nconst MAX_PREDICT_LOOKAHEAD_MS = 60;\nconst MAX_HANDOFF_DELTA_PX = 56;\n\nfunction supportsStickyPosition() {\n\tif (typeof CSS === \"undefined\" || typeof CSS.supports !== \"function\") {\n\t\treturn false;\n\t}\n\n\treturn (\n\t\tCSS.supports(\"position\", \"sticky\") ||\n\t\tCSS.supports(\"position\", \"-webkit-sticky\")\n\t);\n}\n\nfunction initializeParallaxStickyLayerContext(props: CreateContextOptions) {\n\tconst [_internal, _state] = splitProps(props, [\"root\", \"start\", \"end\"]);\n\tconst parallax = useParallax(_internal.root);\n\tconst stickySupported = supportsStickyPosition();\n\n\tconst progress = motionValue(-1);\n\tconst rawScrollProgress = motionValue(-1);\n\tconst inRange = motionValue(false);\n\tconst belowRange = motionValue(false);\n\tconst aboveRange = motionValue(false);\n\tconst normStartValue = motionValue(0);\n\tconst normEndValue = motionValue(1);\n\tconst mode = motionValue<LayerMode>(\"absolute-below\");\n\tconst handoffOffsetY = motionValue(0);\n\n\tconst activeContentAnimations = new Set<AnimationPlaybackControlsWithThen>();\n\tlet handoffAnimation: AnimationPlaybackControlsWithThen | null = null;\n\tlet exitWaitRaf: number | null = null;\n\tlet exitWaitTimeout: number | null = null;\n\tlet pendingExitVersion = 0;\n\tlet pendingExitMode: LayerMode | null = null;\n\tlet lastScrollSampleValue = 0;\n\tlet lastScrollSampleTime = 0;\n\tlet hasScrollSample = false;\n\tlet latestScrollVelocity = 0;\n\n\t_internal.root.style.top = \"0px\";\n\t_internal.root.style.right = \"0px\";\n\t_internal.root.style.bottom = \"0px\";\n\t_internal.root.style.left = \"0px\";\n\t_internal.root.style.height = `100dvh`;\n\t_internal.root.style.overflowX = \"hidden\";\n\t_internal.root.style.maxWidth = \"100%\";\n\tif (window.getComputedStyle(_internal.root).display === \"inline\") {\n\t\t_internal.root.style.display = \"block\";\n\t}\n\n\tfunction updateStyles() {\n\t\tif (!stickySupported) {\n\t\t\tconst normStart = normStartValue.get();\n\t\t\tconst normEnd = normEndValue.get();\n\t\t\tconst raw = rawScrollProgress.get();\n\t\t\tconst span = Math.max(normEnd - normStart, Number.EPSILON);\n\t\t\tconst t = Math.min(Math.max((raw - normStart) / span, 0), 1);\n\t\t\tconst pageY = _internal.start - 1 + t * (_internal.end - _internal.start);\n\n\t\t\t_internal.root.style.position = \"absolute\";\n\t\t\t_internal.root.style.transform = `translate(0px, ${pageY * 100}vh)`;\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentMode = mode.get();\n\t\tconst offset = handoffOffsetY.get();\n\t\tconst hasOffset = Math.abs(offset) >= 0.1;\n\n\t\tif (currentMode === \"sticky\") {\n\t\t\t_internal.root.style.position = \"sticky\";\n\t\t\t_internal.root.style.transform = hasOffset\n\t\t\t\t? `translate(0px, ${offset}px)`\n\t\t\t\t: \"none\";\n\t\t\treturn;\n\t\t}\n\n\t\tconst baseTransform =\n\t\t\tcurrentMode === \"absolute-below\"\n\t\t\t\t? `translate(0px, ${(_internal.start - 1) * 100}vh)`\n\t\t\t\t: `translate(0px, ${(_internal.end - 1) * 100}vh)`;\n\n\t\t_internal.root.style.position = \"absolute\";\n\t\t_internal.root.style.transform = hasOffset\n\t\t\t? `${baseTransform} translate(0px, ${offset}px)`\n\t\t\t: baseTransform;\n\t}\n\n\tfunction renderStyles() {\n\t\tframe.render(updateStyles);\n\t}\n\n\tfunction stopHandoffAnimation() {\n\t\thandoffAnimation?.stop();\n\t\thandoffAnimation = null;\n\t\thandoffOffsetY.set(0);\n\t}\n\n\tfunction clearExitWaitHandles() {\n\t\tif (exitWaitRaf !== null) {\n\t\t\twindow.cancelAnimationFrame(exitWaitRaf);\n\t\t\texitWaitRaf = null;\n\t\t}\n\t\tif (exitWaitTimeout !== null) {\n\t\t\twindow.clearTimeout(exitWaitTimeout);\n\t\t\texitWaitTimeout = null;\n\t\t}\n\t}\n\n\tfunction pruneFinishedAnimations() {\n\t\tfor (const animation of activeContentAnimations) {\n\t\t\tif (animation.state !== \"running\") {\n\t\t\t\tactiveContentAnimations.delete(animation);\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction hasActiveContentAnimations() {\n\t\tpruneFinishedAnimations();\n\t\treturn activeContentAnimations.size > 0;\n\t}\n\n\tfunction registerContentAnimation(\n\t\tanimation: AnimationPlaybackControlsWithThen,\n\t) {\n\t\tactiveContentAnimations.add(animation);\n\t\tanimation.then(\n\t\t\t() => {\n\t\t\t\tactiveContentAnimations.delete(animation);\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tactiveContentAnimations.delete(animation);\n\t\t\t},\n\t\t);\n\t}\n\n\tfunction getHandoffDuration(deltaY: number, velocity: number) {\n\t\tconst speed = Math.abs(velocity);\n\t\tif (speed <= LOW_VELOCITY_NO_TWEEN) return 0;\n\n\t\tconst byDistance = Math.min(0.12, Math.max(0.05, Math.abs(deltaY) / 1400));\n\t\tconst speedScale = Math.min(speed / 0.01, 1);\n\t\treturn Math.max(0.04, byDistance - speedScale * 0.02);\n\t}\n\n\tfunction settleHandoffOverFrames(deltaY: number, frameCount: number) {\n\t\thandoffOffsetY.set(deltaY);\n\t\tupdateStyles();\n\n\t\tlet remainingFrames = Math.max(frameCount, 1);\n\t\tconst settle = () => {\n\t\t\tremainingFrames -= 1;\n\t\t\tif (remainingFrames <= 0) {\n\t\t\t\thandoffOffsetY.set(0);\n\t\t\t\tupdateStyles();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tframe.render(settle);\n\t\t};\n\n\t\tframe.render(settle);\n\t}\n\n\tfunction cancelPendingExit() {\n\t\tpendingExitVersion += 1;\n\t\tpendingExitMode = null;\n\t\tclearExitWaitHandles();\n\t}\n\n\tfunction commitModeImmediately(nextMode: LayerMode) {\n\t\tstopHandoffAnimation();\n\t\tmode.set(nextMode);\n\t\tupdateStyles();\n\t}\n\n\tfunction waitForAnimations(nextMode: LayerMode) {\n\t\tif (\n\t\t\tpendingExitMode === nextMode &&\n\t\t\t(exitWaitRaf !== null || exitWaitTimeout !== null)\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tcancelPendingExit();\n\t\tpendingExitMode = nextMode;\n\t\tconst version = pendingExitVersion;\n\n\t\tconst completeExit = () => {\n\t\t\tif (version !== pendingExitVersion) return;\n\t\t\tclearExitWaitHandles();\n\t\t\tpendingExitMode = null;\n\n\t\t\tconst latest = Math.min(Math.max(rawScrollProgress.get(), 0), 1);\n\t\t\tconst stableMode = getTargetMode(\n\t\t\t\tlatest,\n\t\t\t\tnormStartValue.get(),\n\t\t\t\tnormEndValue.get(),\n\t\t\t);\n\t\t\tif (stableMode !== nextMode) return;\n\n\t\t\tcommitModeImmediately(nextMode);\n\t\t};\n\n\t\tif (!hasActiveContentAnimations()) {\n\t\t\tcompleteExit();\n\t\t\treturn;\n\t\t}\n\n\t\tconst tick = () => {\n\t\t\tif (version !== pendingExitVersion) return;\n\t\t\tif (!hasActiveContentAnimations()) {\n\t\t\t\tcompleteExit();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\texitWaitRaf = window.requestAnimationFrame(tick);\n\t\t};\n\n\t\texitWaitTimeout = window.setTimeout(() => {\n\t\t\tcompleteExit();\n\t\t}, EXIT_WAIT_TIMEOUT_MS);\n\t\texitWaitRaf = window.requestAnimationFrame(tick);\n\t}\n\n\tfunction getTargetMode(value: number, normStart: number, normEnd: number) {\n\t\tif (!stickySupported) {\n\t\t\tif (value <= normStart) return \"absolute-below\";\n\t\t\tif (value >= normEnd) return \"absolute-above\";\n\t\t\treturn \"absolute-below\";\n\t\t}\n\n\t\tconst current = mode.get();\n\t\tif (current === \"sticky\") {\n\t\t\tif (value < normStart - EXIT_HYSTERESIS) return \"absolute-below\";\n\t\t\tif (value > normEnd + EXIT_HYSTERESIS) return \"absolute-above\";\n\t\t\treturn \"sticky\";\n\t\t}\n\n\t\tif (current === \"absolute-below\") {\n\t\t\tif (value >= normStart + ENTER_HYSTERESIS) return \"sticky\";\n\t\t\treturn \"absolute-below\";\n\t\t}\n\n\t\tif (value <= normEnd - ENTER_HYSTERESIS) return \"sticky\";\n\t\treturn \"absolute-above\";\n\t}\n\n\tfunction getModeDecisionValue(\n\t\tvalue: number,\n\t\tnormStart: number,\n\t\tnormEnd: number,\n\t\tallowPrediction: boolean,\n\t) {\n\t\tconst now = performance.now();\n\t\tlet velocity = 0;\n\n\t\tif (hasScrollSample) {\n\t\t\tconst elapsed = Math.max(now - lastScrollSampleTime, 1);\n\t\t\tvelocity = (value - lastScrollSampleValue) / elapsed;\n\t\t}\n\n\t\tlastScrollSampleValue = value;\n\t\tlastScrollSampleTime = now;\n\t\thasScrollSample = true;\n\t\tlatestScrollVelocity = velocity;\n\n\t\tif (!allowPrediction || Math.abs(velocity) < PREDICT_MIN_VELOCITY) {\n\t\t\treturn value;\n\t\t}\n\n\t\tconst speed = Math.abs(velocity);\n\t\tconst speedScale = Math.min(speed / HIGH_VELOCITY_SKIP_HANDOFF, 1);\n\t\tconst lookaheadMs =\n\t\t\tPREDICT_LOOKAHEAD_MS +\n\t\t\tspeedScale * (MAX_PREDICT_LOOKAHEAD_MS - PREDICT_LOOKAHEAD_MS);\n\n\t\tconst predicted = Math.min(Math.max(value + velocity * lookaheadMs, 0), 1);\n\n\t\tconst currentMode = mode.get();\n\t\tif (currentMode === \"absolute-below\") {\n\t\t\tconst entryEdge = normStart + ENTER_HYSTERESIS;\n\t\t\tconst nearStart = Math.abs(value - entryEdge) <= PREDICT_ENTER_BAND;\n\t\t\tif (\n\t\t\t\tvelocity > 0 &&\n\t\t\t\tnearStart &&\n\t\t\t\tvalue < entryEdge &&\n\t\t\t\tpredicted >= entryEdge\n\t\t\t) {\n\t\t\t\treturn entryEdge;\n\t\t\t}\n\t\t}\n\n\t\tif (currentMode === \"absolute-above\") {\n\t\t\tconst entryEdge = normEnd - ENTER_HYSTERESIS;\n\t\t\tconst nearEnd = Math.abs(value - entryEdge) <= PREDICT_ENTER_BAND;\n\t\t\tif (\n\t\t\t\tvelocity < 0 &&\n\t\t\t\tnearEnd &&\n\t\t\t\tvalue > entryEdge &&\n\t\t\t\tpredicted <= entryEdge\n\t\t\t) {\n\t\t\t\treturn entryEdge;\n\t\t\t}\n\t\t}\n\n\t\tif (currentMode === \"sticky\") {\n\t\t\tconst exitTopEdge = normStart - EXIT_HYSTERESIS;\n\t\t\tconst exitBottomEdge = normEnd + EXIT_HYSTERESIS;\n\n\t\t\tconst nearTop = Math.abs(value - exitTopEdge) <= PREDICT_EXIT_BAND;\n\t\t\tif (\n\t\t\t\tvelocity < 0 &&\n\t\t\t\tnearTop &&\n\t\t\t\tvalue > exitTopEdge &&\n\t\t\t\tpredicted <= exitTopEdge\n\t\t\t) {\n\t\t\t\treturn exitTopEdge;\n\t\t\t}\n\n\t\t\tconst nearBottom = Math.abs(value - exitBottomEdge) <= PREDICT_EXIT_BAND;\n\t\t\tif (\n\t\t\t\tvelocity > 0 &&\n\t\t\t\tnearBottom &&\n\t\t\t\tvalue < exitBottomEdge &&\n\t\t\t\tpredicted >= exitBottomEdge\n\t\t\t) {\n\t\t\t\treturn exitBottomEdge;\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t}\n\n\tfunction applyModeWithHandoff(nextMode: LayerMode) {\n\t\tif (!stickySupported) {\n\t\t\tstopHandoffAnimation();\n\t\t\tmode.set(nextMode);\n\t\t\trenderStyles();\n\t\t\treturn;\n\t\t}\n\n\t\tstopHandoffAnimation();\n\n\t\tconst prevRect = _internal.root.getBoundingClientRect();\n\t\tmode.set(nextMode);\n\t\tupdateStyles();\n\n\t\tconst nextRect = _internal.root.getBoundingClientRect();\n\t\tconst deltaY = prevRect.top - nextRect.top;\n\t\tif (Math.abs(deltaY) <= HANDOFF_MIN_DELTA_PX) {\n\t\t\thandoffOffsetY.set(0);\n\t\t\trenderStyles();\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tMath.abs(latestScrollVelocity) >= HIGH_VELOCITY_SKIP_HANDOFF ||\n\t\t\tMath.abs(deltaY) >= MAX_HANDOFF_DELTA_PX\n\t\t) {\n\t\t\tsettleHandoffOverFrames(deltaY, 2);\n\t\t\treturn;\n\t\t}\n\n\t\thandoffOffsetY.set(deltaY);\n\t\tupdateStyles();\n\t\tconst duration = getHandoffDuration(deltaY, latestScrollVelocity);\n\t\tif (duration <= 0) {\n\t\t\tsettleHandoffOverFrames(deltaY, 1);\n\t\t\treturn;\n\t\t}\n\n\t\thandoffAnimation = animate([\n\t\t\t[handoffOffsetY, 0, { duration, ease: HANDOFF_EASE }],\n\t\t]);\n\t\thandoffAnimation.then(() => {\n\t\t\tif (!handoffAnimation) return;\n\t\t\thandoffAnimation = null;\n\t\t\thandoffOffsetY.set(0);\n\t\t\trenderStyles();\n\t\t});\n\t}\n\n\tfunction syncFromScroll(value: number, allowHandoff: boolean) {\n\t\tconst clamped = Math.min(Math.max(value, 0), 1);\n\t\trawScrollProgress.set(clamped);\n\n\t\tconst normStart = normStartValue.get();\n\t\tconst normEnd = normEndValue.get();\n\t\tconst range = [normStart, normEnd] as [number, number];\n\t\tconst span = Math.max(normEnd - normStart, Number.EPSILON);\n\t\tconst normalizedProgress = Math.min(\n\t\t\tMath.max((clamped - normStart) / span, 0),\n\t\t\t1,\n\t\t);\n\n\t\tinRange.set(isInRange({ range, value: clamped }));\n\t\tbelowRange.set(clamped <= normStart);\n\t\taboveRange.set(clamped >= normEnd);\n\t\tprogress.set(normalizedProgress);\n\n\t\tconst decisionValue = getModeDecisionValue(\n\t\t\tclamped,\n\t\t\tnormStart,\n\t\t\tnormEnd,\n\t\t\tallowHandoff,\n\t\t);\n\t\tconst nextMode = getTargetMode(decisionValue, normStart, normEnd);\n\t\tconst currentMode = mode.get();\n\n\t\tif (currentMode === \"sticky\" && nextMode !== \"sticky\" && allowHandoff) {\n\t\t\twaitForAnimations(nextMode);\n\t\t\tupdateStyles();\n\t\t\treturn;\n\t\t}\n\n\t\tcancelPendingExit();\n\t\tif (nextMode === currentMode) {\n\t\t\tif (!allowHandoff) {\n\t\t\t\tstopHandoffAnimation();\n\t\t\t\tupdateStyles();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (allowHandoff) {\n\t\t\tapplyModeWithHandoff(nextMode);\n\t\t\treturn;\n\t\t}\n\n\t\tcommitModeImmediately(nextMode);\n\t}\n\n\tcreateEffect(() => {\n\t\tconst range = [_internal.start, _internal.end];\n\t\tconst maxPages = parallax.maxPages;\n\t\tconst normalizedRange = normalizeTuple(range as any, maxPages);\n\t\tconst [normStart, normEnd] = normalizedRange;\n\t\tnormStartValue.set(normStart);\n\t\tnormEndValue.set(normEnd);\n\n\t\tconst initialValue = parallax.scrollYProgress.get();\n\t\tsyncFromScroll(initialValue, false);\n\t\trenderStyles();\n\n\t\tconst unsubscribe = parallax.scrollYProgress.on(\"change\", (value) => {\n\t\t\tsyncFromScroll(value, true);\n\t\t});\n\n\t\treturn onCleanup(() => {\n\t\t\tunsubscribe();\n\t\t});\n\t});\n\n\tconst unsubHandoffOffset = handoffOffsetY.on(\"change\", (_) => {\n\t\trenderStyles();\n\t});\n\n\tfunction _animate(...args: Parameters<typeof animate>) {\n\t\tconst animation = animate(...args);\n\t\tregisterContentAnimation(animation);\n\t\treturn animation;\n\t}\n\n\tonCleanup(() => {\n\t\tcancelPendingExit();\n\t\tstopHandoffAnimation();\n\t\tunsubHandoffOffset();\n\t});\n\n\treturn [progress, { animate: _animate }] as const;\n}\n\nconst ParallaxStickyLayerContextState = createContext(\n\tinitializeParallaxStickyLayerContext,\n);\n\nexport const provideParallaxStickyLayerContext = (\n\tinitialState: Omit<CreateContextOptions, \"root\">,\n\telement: WalkableNode,\n): ParallaxStickyLayerContext => {\n\tconst props = mergeProps(initialState, { root: element });\n\treturn provide(ParallaxStickyLayerContextState, props, element);\n};\n\nexport const useParallaxStickyLayerContext = (\n\tcontext: ParallaxStickyLayerContext,\n) => {\n\treturn context;\n};\n\nexport const useParallaxStickyLayer = (\n\telement: HTMLElement & ICustomElement,\n) => {\n\tconst context: ParallaxStickyLayerContext = consume(\n\t\tParallaxStickyLayerContextState,\n\t\telement,\n\t);\n\n\tif (!context) {\n\t\tthrow console.error(\n\t\t\t\"ParallaxContext not found! Please ensure to wrap your custom element with parallax-container element.\",\n\t\t);\n\t}\n\n\treturn useParallaxStickyLayerContext(context);\n};\n\nexport const withParallaxStickyLayerContext = createWithElementContext<\n\ttypeof ParallaxStickyLayerContextState,\n\tParallaxStickyLayerContext\n>(ParallaxStickyLayerContextState);\n\nexport const getParallaxStickyLayerContext = (element: Element) => {\n\tconst context = getContextFromProvider<ParallaxStickyLayerContext>(\n\t\tParallaxStickyLayerContextState,\n\t\telement,\n\t);\n\treturn useParallaxStickyLayerContext(context);\n};\n"]}
1
+ {"version":3,"sources":["../../../src/hooks/useParallaxStickyLayer.ts"],"names":["transform","isInRange","mTransform"],"mappings":";;;;;;;;;AAqCA,SAAS,qCAAqC,KAA6B,EAAA;AAC1E,EAAM,MAAA,CAAC,SAAW,EAAA,MAAM,CAAI,GAAA,UAAA,CAAW,OAAO,CAAC,MAAA,EAAQ,OAAS,EAAA,KAAK,CAAC,CAAA;AACtE,EAAM,MAAA,QAAA,GAAW,WAAY,CAAA,SAAA,CAAU,IAAI,CAAA;AAE3C,EAAM,MAAA,QAAA,GAAW,YAAY,EAAE,CAAA;AAC/B,EAAM,MAAA,OAAA,GAAU,YAAY,KAAK,CAAA;AACjC,EAAM,MAAA,UAAA,GAAa,YAAY,KAAK,CAAA;AACpC,EAAM,MAAA,UAAA,GAAa,YAAY,KAAK,CAAA;AAEpC,EAAA,MAAM,QAAW,GAAA,cAAA;AAAA,IAAe,MAC/B,OAAA,CAAQ,GAAI,EAAA,GAAI,QAAW,GAAA;AAAA,GAC5B;AACA,EAAM,MAAAA,WAAA,GAAY,eAAe,MAAM;AACtC,IAAMC,MAAAA,UAAAA,GAAY,QAAQ,GAAI,EAAA;AAC9B,IAAM,MAAA,YAAA,GAAe,WAAW,GAAI,EAAA;AACpC,IAAM,MAAA,YAAA,GAAe,WAAW,GAAI,EAAA;AACpC,IAAA,IAAIA,YAAkB,OAAA,MAAA;AACtB,IAAA,IAAI,cAAqB,OAAA,CAAA,eAAA,EAAA,CAAmB,SAAU,CAAA,KAAA,GAAQ,KAAK,GAAG,CAAA,GAAA,CAAA;AACtE,IAAA,IAAI,cAAqB,OAAA,CAAA,eAAA,EAAA,CAAmB,SAAU,CAAA,GAAA,GAAM,KAAK,GAAG,CAAA,GAAA,CAAA;AAAA,GACpE,CAAA;AACD,EAAM,MAAA,UAAA,GAAa,WAAiD,CAAA,EAAE,CAAA;AAEtE,EAAM,MAAA,MAAA,GAAS,eAAe,OAAO;AAAA,IACpC,QAAA,EAAU,SAAS,GAAI,EAAA;AAAA,IACvB,SAAA,EAAWD,YAAU,GAAI;AAAA,GACxB,CAAA,CAAA;AAEF,EAAU,SAAA,CAAA,IAAA,CAAK,MAAM,GAAM,GAAA,KAAA;AAC3B,EAAU,SAAA,CAAA,IAAA,CAAK,MAAM,KAAQ,GAAA,KAAA;AAC7B,EAAU,SAAA,CAAA,IAAA,CAAK,MAAM,MAAS,GAAA,KAAA;AAC9B,EAAU,SAAA,CAAA,IAAA,CAAK,MAAM,IAAO,GAAA,KAAA;AAC5B,EAAU,SAAA,CAAA,IAAA,CAAK,MAAM,MAAS,GAAA,CAAA,MAAA,CAAA;AAC9B,EAAU,SAAA,CAAA,IAAA,CAAK,MAAM,SAAY,GAAA,QAAA;AACjC,EAAU,SAAA,CAAA,IAAA,CAAK,MAAM,QAAW,GAAA,MAAA;AAChC,EAAA,IAAI,OAAO,gBAAiB,CAAA,SAAA,CAAU,IAAI,CAAA,CAAE,YAAY,QAAU,EAAA;AACjE,IAAU,SAAA,CAAA,IAAA,CAAK,MAAM,OAAU,GAAA,OAAA;AAAA;AAGhC,EAAA,YAAA,CAAa,MAAM;AAClB,IAAA,MAAM,KAAQ,GAAA,CAAC,SAAU,CAAA,KAAA,EAAO,UAAU,GAAG,CAAA;AAC7C,IAAA,MAAM,WAAW,QAAS,CAAA,QAAA;AAC1B,IAAM,MAAA,eAAA,GAAkB,cAAe,CAAA,KAAA,EAAc,QAAQ,CAAA;AAC7D,IAAM,MAAA,CAAC,SAAW,EAAA,OAAO,CAAI,GAAA,eAAA;AAC7B,IAAA,MAAM,cAAcE,SAAW,CAAA,eAAA,EAAwB,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAE7D,IAAA,MAAM,cAAc,QAAS,CAAA,eAAA,CAAgB,EAAG,CAAA,QAAA,EAAU,CAAC,KAAU,KAAA;AACpE,MAAA,OAAA,CAAQ,IAAI,SAAU,CAAA,EAAE,OAAO,eAAwB,EAAA,KAAA,EAAO,CAAC,CAAA;AAC/D,MAAW,UAAA,CAAA,GAAA,CAAI,SAAS,SAAS,CAAA;AACjC,MAAW,UAAA,CAAA,GAAA,CAAI,SAAS,OAAO,CAAA;AAC/B,MAAS,QAAA,CAAA,GAAA,CAAI,WAAY,CAAA,KAAK,CAAC,CAAA;AAAA,KAC/B,CAAA;AAED,IAAA,OAAO,UAAU,MAAM;AACtB,MAAY,WAAA,EAAA;AAAA,KACZ,CAAA;AAAA,GACD,CAAA;AAED,EAAA,SAAS,YAAe,GAAA;AACvB,IAAM,MAAA,CAAA,GAAI,OAAO,GAAI,EAAA;AACrB,IAAU,SAAA,CAAA,IAAA,CAAK,KAAM,CAAA,QAAA,GAAW,CAAE,CAAA,QAAA;AAClC,IAAU,SAAA,CAAA,IAAA,CAAK,KAAM,CAAA,SAAA,GAAY,CAAE,CAAA,SAAA;AAAA;AAGpC,EAAA,SAAS,YAAe,GAAA;AACvB,IAAA,KAAA,CAAM,OAAO,YAAY,CAAA;AAAA;AAG1B,EAAA,SAAS,iBAAoB,GAAA;AAC5B,IAAM,MAAA,CAAA,GAAI,WAAW,GAAI,EAAA;AACzB,IAAM,MAAA,UAAA,GAAa,IAAI,eAAgB,EAAA;AACvC,IAAA,gBAAA,CAAiB,mBAAmB,CAAC,CAAA,EAAG,WAAW,MAAM,CAAA,CAAE,KAAK,MAAM;AACrE,MAAW,UAAA,CAAA,GAAA,CAAI,EAAE,CAAA;AACjB,MAAa,YAAA,EAAA;AAAA,KACb,CAAA;AAAA;AAGF,EAAA,MAAM,WAAc,GAAA,MAAA,CAAO,EAAG,CAAA,QAAA,EAAU,CAAC,CAAM,KAAA;AAC9C,IAAA,IAAI,SAAS,GAAI,EAAA,KAAM,CAAK,IAAA,QAAA,CAAS,KAAU,KAAA,CAAA;AAC9C,MAAA,OAAO,iBAAkB,EAAA;AAC1B,IAAW,UAAA,CAAA,GAAA,CAAI,EAAE,CAAA;AACjB,IAAa,YAAA,EAAA;AAAA,GACb,CAAA;AAED,EAAA,SAAS,YAAY,IAAkC,EAAA;AACtD,IAAM,MAAA,SAAA,GAAY,OAAQ,CAAA,GAAG,IAAI,CAAA;AACjC,IAAA,UAAA,CAAW,IAAI,CAAC,GAAG,WAAW,GAAI,EAAA,EAAG,SAAS,CAAC,CAAA;AAC/C,IAAO,OAAA,SAAA;AAAA;AAGR,EAAA,SAAA,CAAU,MAAM;AACf,IAAY,WAAA,EAAA;AAAA,GACZ,CAAA;AAED,EAAA,OAAO,CAAC,QAAA,EAAU,EAAE,OAAA,EAAS,UAAU,CAAA;AACxC;AAEA,MAAM,+BAAkC,GAAA,aAAA;AAAA,EACvC;AACD,CAAA;AAEa,MAAA,iCAAA,GAAoC,CAChD,YAAA,EACA,OACgC,KAAA;AAChC,EAAA,MAAM,QAAQ,UAAW,CAAA,YAAA,EAAc,EAAE,IAAA,EAAM,SAAS,CAAA;AACxD,EAAO,OAAA,OAAA,CAAQ,+BAAiC,EAAA,KAAA,EAAO,OAAO,CAAA;AAC/D;AAEa,MAAA,6BAAA,GAAgC,CAC5C,OACI,KAAA;AACJ,EAAO,OAAA,OAAA;AACR;AAEa,MAAA,sBAAA,GAAyB,CACrC,OACI,KAAA;AACJ,EAAA,MAAM,OAAsC,GAAA,OAAA;AAAA,IAC3C,+BAAA;AAAA,IACA;AAAA,GACD;AAEA,EAAA,IAAI,CAAC,OAAS,EAAA;AACb,IAAA,MAAM,OAAQ,CAAA,KAAA;AAAA,MACb;AAAA,KACD;AAAA;AAGD,EAAA,OAAO,8BAA8B,OAAO,CAAA;AAC7C;AAEa,MAAA,8BAAA,GAAiC,yBAG5C,+BAA+B;AAEpB,MAAA,6BAAA,GAAgC,CAAC,OAAqB,KAAA;AAClE,EAAA,MAAM,OAAU,GAAA,sBAAA;AAAA,IACf,+BAAA;AAAA,IACA;AAAA,GACD;AACA,EAAA,OAAO,8BAA8B,OAAO,CAAA;AAC7C","file":"useParallaxStickyLayer.js","sourcesContent":["import { onCleanup, createEffect, splitProps, mergeProps } from \"solid-js\";\nimport {\n\ttype ICustomElement,\n\tcreateContext,\n\tprovide,\n\tconsume,\n} from \"component-register\";\nimport {\n\tmotionValue,\n\ttransformValue,\n\ttransform as mTransform,\n\tframe,\n\tanimate,\n\ttype AnimationPlaybackControlsWithThen,\n} from \"motion\";\nimport { awaitAllAnimations } from \"@brytdesigns/web-component-core/animation\";\nimport { abortablePromise } from \"@brytdesigns/web-component-core/promise\";\nimport {\n\tgetContextFromProvider,\n\tcreateWithElementContext,\n} from \"@brytdesigns/web-component-core/utils\";\n\nimport { useParallax } from \"./useParallax\";\nimport { normalizeTuple, isInRange } from \"../utils\";\n\ntype CreateContextOptions = {\n\troot: HTMLElement & ICustomElement;\n\tstart: number;\n\tend: number;\n};\n\ntype WalkableNode = Parameters<typeof provide>[2];\n\ntype ParallaxStickyLayerContext = ReturnType<\n\ttypeof initializeParallaxStickyLayerContext\n>;\n\nfunction initializeParallaxStickyLayerContext(props: CreateContextOptions) {\n\tconst [_internal, _state] = splitProps(props, [\"root\", \"start\", \"end\"]);\n\tconst parallax = useParallax(_internal.root);\n\n\tconst progress = motionValue(-1);\n\tconst inRange = motionValue(false);\n\tconst belowRange = motionValue(false);\n\tconst aboveRange = motionValue(false);\n\n\tconst position = transformValue(() =>\n\t\tinRange.get() ? \"sticky\" : \"absolute\",\n\t);\n\tconst transform = transformValue(() => {\n\t\tconst isInRange = inRange.get();\n\t\tconst isBelowRange = belowRange.get();\n\t\tconst isAboveRange = aboveRange.get();\n\t\tif (isInRange) return \"none\";\n\t\tif (isBelowRange) return `translate(0px, ${(_internal.start - 1) * 100}vh)`;\n\t\tif (isAboveRange) return `translate(0px, ${(_internal.end - 1) * 100}vh)`;\n\t});\n\tconst animations = motionValue<AnimationPlaybackControlsWithThen[]>([]);\n\n\tconst styles = transformValue(() => ({\n\t\tposition: position.get(),\n\t\ttransform: transform.get(),\n\t}));\n\n\t_internal.root.style.top = \"0px\";\n\t_internal.root.style.right = \"0px\";\n\t_internal.root.style.bottom = \"0px\";\n\t_internal.root.style.left = \"0px\";\n\t_internal.root.style.height = `100dvh`;\n\t_internal.root.style.overflowX = \"hidden\";\n\t_internal.root.style.maxWidth = \"100%\";\n\tif (window.getComputedStyle(_internal.root).display === \"inline\") {\n\t\t_internal.root.style.display = \"block\";\n\t}\n\n\tcreateEffect(() => {\n\t\tconst range = [_internal.start, _internal.end];\n\t\tconst maxPages = parallax.maxPages;\n\t\tconst normalizedRange = normalizeTuple(range as any, maxPages);\n\t\tconst [normStart, normEnd] = normalizedRange;\n\t\tconst transformer = mTransform(normalizedRange as any, [0, 1]);\n\n\t\tconst unsubscribe = parallax.scrollYProgress.on(\"change\", (value) => {\n\t\t\tinRange.set(isInRange({ range: normalizedRange as any, value }));\n\t\t\tbelowRange.set(value <= normStart);\n\t\t\taboveRange.set(value >= normEnd);\n\t\t\tprogress.set(transformer(value));\n\t\t});\n\n\t\treturn onCleanup(() => {\n\t\t\tunsubscribe();\n\t\t});\n\t});\n\n\tfunction updateStyles() {\n\t\tconst s = styles.get();\n\t\t_internal.root.style.position = s.position;\n\t\t_internal.root.style.transform = s.transform;\n\t}\n\n\tfunction renderStyles() {\n\t\tframe.render(updateStyles);\n\t}\n\n\tfunction waitForAnimations() {\n\t\tconst a = animations.get();\n\t\tconst controller = new AbortController();\n\t\tabortablePromise(awaitAllAnimations(a), controller.signal).then(() => {\n\t\t\tanimations.set([]);\n\t\t\trenderStyles();\n\t\t});\n\t}\n\n\tconst unsubStyles = styles.on(\"change\", (_) => {\n\t\tif (progress.get() === 1 || progress.get() === 0)\n\t\t\treturn waitForAnimations();\n\t\tanimations.set([]);\n\t\trenderStyles();\n\t});\n\n\tfunction _animate(...args: Parameters<typeof animate>) {\n\t\tconst animation = animate(...args);\n\t\tanimations.set([...animations.get(), animation]);\n\t\treturn animation;\n\t}\n\n\tonCleanup(() => {\n\t\tunsubStyles();\n\t});\n\n\treturn [progress, { animate: _animate }] as const;\n}\n\nconst ParallaxStickyLayerContextState = createContext(\n\tinitializeParallaxStickyLayerContext,\n);\n\nexport const provideParallaxStickyLayerContext = (\n\tinitialState: Omit<CreateContextOptions, \"root\">,\n\telement: WalkableNode,\n): ParallaxStickyLayerContext => {\n\tconst props = mergeProps(initialState, { root: element });\n\treturn provide(ParallaxStickyLayerContextState, props, element);\n};\n\nexport const useParallaxStickyLayerContext = (\n\tcontext: ParallaxStickyLayerContext,\n) => {\n\treturn context;\n};\n\nexport const useParallaxStickyLayer = (\n\telement: HTMLElement & ICustomElement,\n) => {\n\tconst context: ParallaxStickyLayerContext = consume(\n\t\tParallaxStickyLayerContextState,\n\t\telement,\n\t);\n\n\tif (!context) {\n\t\tthrow console.error(\n\t\t\t\"ParallaxContext not found! Please ensure to wrap your custom element with parallax-container element.\",\n\t\t);\n\t}\n\n\treturn useParallaxStickyLayerContext(context);\n};\n\nexport const withParallaxStickyLayerContext = createWithElementContext<\n\ttypeof ParallaxStickyLayerContextState,\n\tParallaxStickyLayerContext\n>(ParallaxStickyLayerContextState);\n\nexport const getParallaxStickyLayerContext = (element: Element) => {\n\tconst context = getContextFromProvider<ParallaxStickyLayerContext>(\n\t\tParallaxStickyLayerContextState,\n\t\telement,\n\t);\n\treturn useParallaxStickyLayerContext(context);\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brytdesigns/web-component-parallax",
3
- "version": "1.2.17",
3
+ "version": "1.2.18",
4
4
  "description": "Headless parallax animation web component",
5
5
  "main": "./dist/main/index.js",
6
6
  "module": "./dist/main/index.js",