@wyxos/vibe 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -1,44 +1,210 @@
1
- import { Fragment as e, Transition as t, computed as n, createApp as r, createBlock as i, createCommentVNode as a, createElementBlock as o, createElementVNode as s, createVNode as c, defineComponent as l, guardReactiveProps as u, h as d, nextTick as f, normalizeClass as p, normalizeProps as m, normalizeStyle as h, onBeforeUnmount as g, onMounted as _, openBlock as v, reactive as y, renderList as b, resolveDynamicComponent as x, shallowRef as S, toDisplayString as C, unref as w, useId as T, watch as E, withCtx as D, withKeys as O, withModifiers as k } from "vue";
1
+ import { Fragment as e, Transition as t, computed as n, createApp as r, createBlock as i, createCommentVNode as a, createElementBlock as o, createElementVNode as s, createTextVNode as c, createVNode as l, defineComponent as u, guardReactiveProps as d, h as f, nextTick as p, normalizeClass as m, normalizeProps as h, normalizeStyle as g, onBeforeUnmount as _, onMounted as v, openBlock as y, reactive as b, renderList as x, resolveDynamicComponent as S, shallowRef as C, toDisplayString as w, unref as T, useId as E, watch as D, withCtx as O, withKeys as k, withModifiers as A } from "vue";
2
2
  //#region src/core/mediaAsset.ts
3
- function A(e) {
3
+ function j(e) {
4
4
  return [e, ...e.items];
5
5
  }
6
- function j(e, t) {
7
- return Math.min(e.items.length, Math.max(0, t));
8
- }
9
6
  function M(e, t) {
10
- return A(e)[j(e, t)] ?? e;
7
+ return Math.min(e.items.length, Math.max(0, t));
11
8
  }
12
9
  function N(e, t) {
10
+ return j(e)[M(e, t)] ?? e;
11
+ }
12
+ function P(e, t) {
13
13
  return `${String(e)}:${t}`;
14
14
  }
15
- function P(e) {
15
+ //#endregion
16
+ //#region src/core/runtime.ts
17
+ function F(e) {
18
+ return {
19
+ activeReelPostId: e.activeReelPostId,
20
+ autoScroll: { ...e.autoScroll },
21
+ autofill: { ...e.autofill },
22
+ error: e.error,
23
+ fill: {
24
+ ...e.fill,
25
+ target: e.fill.target ? { ...e.fill.target } : null
26
+ },
27
+ infiniteScroll: e.infiniteScroll,
28
+ isLoading: e.isLoading,
29
+ isLoadingMore: e.isLoadingMore,
30
+ items: [...e.items],
31
+ layout: e.layout,
32
+ lifecycle: e.isLoading || e.isLoadingMore ? "loading" : e.error || e.nextPageError ? "error" : "loaded",
33
+ loadMoreLocked: e.loadMoreLocked,
34
+ next: e.next,
35
+ nextPageError: e.nextPageError,
36
+ reelAutoAdvance: { ...e.reelAutoAdvance },
37
+ reelInfoSheet: { ...e.reelInfoSheet },
38
+ reelOrigin: e.reelOrigin,
39
+ total: e.total
40
+ };
41
+ }
42
+ //#endregion
43
+ //#region src/components/GalleryFooter.vue?vue&type=script&setup=true&lang.ts
44
+ var I = {
45
+ key: 0,
46
+ class: "gallery-footer"
47
+ }, L = {
48
+ key: 0,
49
+ class: "load-more-status",
50
+ role: "status"
51
+ }, R = ["disabled"], z = {
52
+ key: 2,
53
+ class: "gallery-sentinel",
54
+ "aria-hidden": "true"
55
+ }, B = {
56
+ key: 3,
57
+ class: "end-feed"
58
+ }, V = ["disabled"], H = /* @__PURE__ */ u({
59
+ __name: "GalleryFooter",
60
+ props: {
61
+ canRetryEnd: { type: Boolean },
62
+ hasError: { type: Boolean },
63
+ hasNext: { type: Boolean },
64
+ infiniteScroll: { type: Boolean },
65
+ isLoading: { type: Boolean },
66
+ loadMoreLocked: { type: Boolean }
67
+ },
68
+ emits: ["loadMore", "retryEnd"],
69
+ setup(e, { emit: t }) {
70
+ let n = e, r = t;
71
+ function i() {
72
+ n.loadMoreLocked || (n.hasNext ? r("loadMore") : r("retryEnd"));
73
+ }
74
+ return (t, n) => e.hasNext || e.isLoading || e.hasError || e.canRetryEnd ? (y(), o("footer", I, [e.isLoading ? (y(), o("p", L, " Loading more… ")) : e.hasError || e.hasNext && (!e.infiniteScroll || e.loadMoreLocked) ? (y(), o("button", {
75
+ key: 1,
76
+ "data-test": "load-more",
77
+ class: "load-more-button",
78
+ type: "button",
79
+ disabled: e.loadMoreLocked,
80
+ onClick: i
81
+ }, w(e.hasError ? "Try again" : e.loadMoreLocked ? "Loading paused" : "Load more"), 9, R)) : e.hasNext ? (y(), o("span", z)) : (y(), o("div", B, [n[1] ||= s("p", {
82
+ class: "end-feed-message",
83
+ role: "status"
84
+ }, " You've reached the end. ", -1), s("button", {
85
+ "data-test": "retry-end",
86
+ class: "load-more-button",
87
+ type: "button",
88
+ disabled: e.loadMoreLocked,
89
+ onClick: n[0] ||= (e) => t.$emit("retryEnd")
90
+ }, " Check for more ", 8, V)]))])) : a("", !0);
91
+ }
92
+ }), U = /* @__PURE__ */ u({
93
+ __name: "FeedFooter",
94
+ props: {
95
+ actions: {},
96
+ canRetryEnd: { type: Boolean },
97
+ feedFooter: {},
98
+ hasError: { type: Boolean },
99
+ hasNext: { type: Boolean },
100
+ infiniteScroll: { type: Boolean },
101
+ isLoading: { type: Boolean },
102
+ loadMoreLocked: { type: Boolean },
103
+ state: {}
104
+ },
105
+ emits: ["loadMore", "retryEnd"],
106
+ setup(e, { emit: t }) {
107
+ let n = e, r = t;
108
+ function a() {
109
+ n.actions?.cancelAutofill();
110
+ }
111
+ function o() {
112
+ n.actions?.retry();
113
+ }
114
+ return (t, n) => e.feedFooter && e.actions && e.state ? (y(), i(S(e.feedFooter.component), {
115
+ key: 0,
116
+ actions: e.actions,
117
+ state: e.state,
118
+ onAutofillCancel: a,
119
+ onLoadMore: n[0] ||= (e) => r("loadMore"),
120
+ onRetry: o,
121
+ onRetryEnd: n[1] ||= (e) => r("retryEnd")
122
+ }, null, 40, ["actions", "state"])) : (y(), i(H, {
123
+ key: 1,
124
+ "can-retry-end": e.canRetryEnd,
125
+ "has-error": e.hasError,
126
+ "has-next": e.hasNext,
127
+ "infinite-scroll": e.infiniteScroll,
128
+ "is-loading": e.isLoading,
129
+ "load-more-locked": e.loadMoreLocked,
130
+ onLoadMore: n[2] ||= (e) => r("loadMore"),
131
+ onRetryEnd: n[3] ||= (e) => r("retryEnd")
132
+ }, null, 8, [
133
+ "can-retry-end",
134
+ "has-error",
135
+ "has-next",
136
+ "infinite-scroll",
137
+ "is-loading",
138
+ "load-more-locked"
139
+ ]));
140
+ }
141
+ }), W = ["role"], ee = { class: "gallery-status" }, G = /* @__PURE__ */ u({
142
+ __name: "FeedStatus",
143
+ props: {
144
+ actions: {},
145
+ canRetryEnd: { type: Boolean },
146
+ feedFooter: {},
147
+ state: {}
148
+ },
149
+ emits: ["loadMore", "retryEnd"],
150
+ setup(t, { emit: n }) {
151
+ let r = t, l = n;
152
+ return (n, u) => (y(), o("main", {
153
+ class: "gallery-shell",
154
+ role: r.state.error ? "alert" : r.state.isLoading ? "status" : void 0
155
+ }, [s("p", ee, [r.state.error ? (y(), o(e, { key: 0 }, [c(" Unable to load media. ")], 64)) : r.state.isLoading ? (y(), o(e, { key: 1 }, [c(" Loading media… ")], 64)) : (y(), o(e, { key: 2 }, [c(" No media found. ")], 64))]), t.feedFooter ? (y(), i(U, {
156
+ key: 0,
157
+ actions: t.actions,
158
+ "can-retry-end": t.canRetryEnd,
159
+ "feed-footer": t.feedFooter,
160
+ "has-error": !!t.state.nextPageError,
161
+ "has-next": t.state.next !== null,
162
+ "infinite-scroll": t.state.infiniteScroll,
163
+ "is-loading": t.state.isLoadingMore,
164
+ "load-more-locked": t.state.loadMoreLocked,
165
+ state: t.state,
166
+ onLoadMore: u[0] ||= (e) => l("loadMore"),
167
+ onRetryEnd: u[1] ||= (e) => l("retryEnd")
168
+ }, null, 8, [
169
+ "actions",
170
+ "can-retry-end",
171
+ "feed-footer",
172
+ "has-error",
173
+ "has-next",
174
+ "infinite-scroll",
175
+ "is-loading",
176
+ "load-more-locked",
177
+ "state"
178
+ ])) : a("", !0)], 8, W));
179
+ }
180
+ });
181
+ function K(e) {
16
182
  return e.scrollHeight - e.scrollTop - e.clientHeight <= 240;
17
183
  }
18
184
  //#endregion
19
185
  //#region src/core/masonry.ts
20
- function F(e) {
186
+ function te(e) {
21
187
  let t = e.preview.width ?? e.width, n = e.preview.height ?? e.height;
22
188
  return !t || !n || t <= 0 || n <= 0 ? 1 : n / t;
23
189
  }
24
- function I(e) {
190
+ function ne(e) {
25
191
  return e.reduce((t, n, r) => n < e[t] ? r : t, 0);
26
192
  }
27
- function L(e) {
193
+ function re(e) {
28
194
  return Math.max(0, e.containerHeight) + Math.max(0, e.gap);
29
195
  }
30
- function R(e, t) {
196
+ function q(e, t) {
31
197
  let n = Math.max(0, t.overscan), r = t.scrollTop - n, i = t.scrollTop + Math.max(0, t.viewportHeight) + n;
32
198
  return e.reduce((e, t, n) => (t.y + t.height >= r && t.y <= i && e.push(n), e), []);
33
199
  }
34
- function z(e, t, n) {
200
+ function J(e, t, n) {
35
201
  if (t <= 0 || e.length === 0) return {
36
202
  columns: 0,
37
203
  height: 0,
38
204
  items: []
39
205
  };
40
206
  let r = Math.max(0, n.gap), i = Number.isFinite(n.additionalHeight) ? Math.max(0, n.additionalHeight ?? 0) : 0, a = Math.max(1, n.minColumnWidth), o = Math.max(1, Math.floor((t + r) / (a + r))), s = (t - r * (o - 1)) / o, c = Array.from({ length: o }, () => 0), l = e.map((e) => {
41
- let t = I(c), n = s * F(e) + i, a = {
207
+ let t = ne(c), n = s * te(e) + i, a = {
42
208
  x: t * (s + r),
43
209
  y: c[t],
44
210
  width: s,
@@ -54,10 +220,10 @@ function z(e, t, n) {
54
220
  }
55
221
  //#endregion
56
222
  //#region src/core/scrollbar.ts
57
- function B(e, t, n) {
223
+ function Y(e, t, n) {
58
224
  return Math.min(n, Math.max(t, e));
59
225
  }
60
- function V({ contentSize: e, minimumThumbSize: t, scrollPosition: n, trackSize: r, viewportSize: i }) {
226
+ function ie({ contentSize: e, minimumThumbSize: t, scrollPosition: n, trackSize: r, viewportSize: i }) {
61
227
  let a = Math.max(0, e), o = Math.max(0, r), s = Math.max(0, i), c = Math.max(0, a - s);
62
228
  if (!(c > 0 && o > 0)) return {
63
229
  maximumScrollPosition: c,
@@ -66,23 +232,23 @@ function V({ contentSize: e, minimumThumbSize: t, scrollPosition: n, trackSize:
66
232
  thumbSize: o,
67
233
  thumbTravel: 0
68
234
  };
69
- let l = B(s / a * o, Math.min(Math.max(0, t), o), o), u = Math.max(0, o - l);
235
+ let l = Y(s / a * o, Math.min(Math.max(0, t), o), o), u = Math.max(0, o - l);
70
236
  return {
71
237
  maximumScrollPosition: c,
72
238
  scrollable: !0,
73
- thumbOffset: u * (B(n, 0, c) / c),
239
+ thumbOffset: u * (Y(n, 0, c) / c),
74
240
  thumbSize: l,
75
241
  thumbTravel: u
76
242
  };
77
243
  }
78
244
  //#endregion
79
245
  //#region src/components/GalleryScrollbar.vue?vue&type=script&setup=true&lang.ts
80
- var H = ["aria-hidden"], U = [
246
+ var ae = ["aria-hidden"], X = [
81
247
  "aria-controls",
82
248
  "aria-valuemax",
83
249
  "aria-valuenow",
84
250
  "tabindex"
85
- ], W = 32, G = 40, K = 120, ee = /* @__PURE__ */ l({
251
+ ], Z = 32, oe = 40, se = 120, ce = /* @__PURE__ */ u({
86
252
  __name: "GalleryScrollbar",
87
253
  props: {
88
254
  contentSize: {},
@@ -97,23 +263,23 @@ var H = ["aria-hidden"], U = [
97
263
  thumbOffset: 0,
98
264
  thumbSize: 0,
99
265
  thumbTravel: 0
100
- }, i = S(null), a = S(r), c = S(!1), l = S(!1), u = S(!1), d = null, m = 0, _ = 0, y = null, b = null, x = null, C = null, w = !1, T = null, D = n(() => a.value.scrollable && !t.suspended), O = n(() => ({
266
+ }, i = C(null), a = C(r), c = C(!1), l = C(!1), u = C(!1), d = null, f = 0, h = 0, v = null, b = null, x = null, S = null, w = !1, T = null, E = n(() => a.value.scrollable && !t.suspended), O = n(() => ({
101
267
  height: `${a.value.thumbSize}px`,
102
268
  transform: `translate3d(0, ${a.value.thumbOffset}px, 0)`
103
269
  }));
104
270
  function k() {
105
- y !== null && clearTimeout(y), y = setTimeout(() => {
106
- y = null, c.value || (l.value = !1);
107
- }, K);
271
+ v !== null && clearTimeout(v), v = setTimeout(() => {
272
+ v = null, c.value || (l.value = !1);
273
+ }, se);
108
274
  }
109
275
  function A() {
110
276
  l.value = !0, k();
111
277
  }
112
278
  function j() {
113
279
  let e = t.scrollElement, n = i.value;
114
- return !e || !n ? r : V({
280
+ return !e || !n ? r : ie({
115
281
  contentSize: e.scrollHeight,
116
- minimumThumbSize: W,
282
+ minimumThumbSize: Z,
117
283
  scrollPosition: e.scrollTop,
118
284
  trackSize: n.clientHeight,
119
285
  viewportSize: e.clientHeight
@@ -146,7 +312,7 @@ var H = ["aria-hidden"], U = [
146
312
  n && (n.scrollTop = Math.min(a.value.maximumScrollPosition, Math.max(0, e)), M("scroll"));
147
313
  }
148
314
  function F(e) {
149
- if (!D.value || e.target !== e.currentTarget) return;
315
+ if (!E.value || e.target !== e.currentTarget) return;
150
316
  let t = i.value;
151
317
  if (!t || a.value.thumbTravel <= 0) return;
152
318
  e.preventDefault(), A();
@@ -154,47 +320,47 @@ var H = ["aria-hidden"], U = [
154
320
  P(Math.min(1, Math.max(0, n / a.value.thumbTravel)) * a.value.maximumScrollPosition);
155
321
  }
156
322
  function I(e) {
157
- D.value && (e.preventDefault(), e.stopPropagation(), e.currentTarget.setPointerCapture?.(e.pointerId), d = e.pointerId, m = e.clientY, _ = t.scrollElement?.scrollTop ?? 0, c.value = !0, l.value = !0, y !== null && clearTimeout(y), y = null);
323
+ E.value && (e.preventDefault(), e.stopPropagation(), e.currentTarget.setPointerCapture?.(e.pointerId), d = e.pointerId, f = e.clientY, h = t.scrollElement?.scrollTop ?? 0, c.value = !0, l.value = !0, v !== null && clearTimeout(v), v = null);
158
324
  }
159
325
  function L(e) {
160
326
  if (!c.value || e.pointerId !== d || (e.preventDefault(), a.value.thumbTravel <= 0)) return;
161
- let t = (e.clientY - m) / a.value.thumbTravel * a.value.maximumScrollPosition;
162
- P(_ + t);
327
+ let t = (e.clientY - f) / a.value.thumbTravel * a.value.maximumScrollPosition;
328
+ P(h + t);
163
329
  }
164
330
  function R(e) {
165
331
  !c.value || e.pointerId !== d || (e.currentTarget.releasePointerCapture?.(e.pointerId), d = null, c.value = !1, w && (w = !1, M("content")), k());
166
332
  }
167
333
  function z(e) {
168
- if (!D.value) return;
169
- let n = t.scrollElement?.clientHeight ?? 0, r = t.scrollElement?.scrollTop ?? 0, i = e.key === "ArrowUp" ? r - G : e.key === "ArrowDown" ? r + G : e.key === "PageUp" ? r - n : e.key === "PageDown" ? r + n : e.key === "Home" ? 0 : e.key === "End" ? a.value.maximumScrollPosition : null;
334
+ if (!E.value) return;
335
+ let n = t.scrollElement?.clientHeight ?? 0, r = t.scrollElement?.scrollTop ?? 0, i = e.key === "ArrowUp" ? r - oe : e.key === "ArrowDown" ? r + oe : e.key === "PageUp" ? r - n : e.key === "PageDown" ? r + n : e.key === "Home" ? 0 : e.key === "End" ? a.value.maximumScrollPosition : null;
170
336
  i !== null && (e.preventDefault(), A(), P(i));
171
337
  }
172
338
  function B(e) {
173
- if (C?.disconnect(), !(typeof ResizeObserver > "u")) {
174
- C = new ResizeObserver(() => M("content"));
175
- for (let t of e.children) C.observe(t);
339
+ if (S?.disconnect(), !(typeof ResizeObserver > "u")) {
340
+ S = new ResizeObserver(() => M("content"));
341
+ for (let t of e.children) S.observe(t);
176
342
  }
177
343
  }
178
- return E(() => t.scrollElement, (e, t) => {
179
- t?.removeEventListener("scroll", N), x?.disconnect(), x = null, C?.disconnect(), C = null, T?.disconnect(), T = null, e?.addEventListener("scroll", N, { passive: !0 }), e && typeof ResizeObserver < "u" && (T = new ResizeObserver(() => {
344
+ return D(() => t.scrollElement, (e, t) => {
345
+ t?.removeEventListener("scroll", N), x?.disconnect(), x = null, S?.disconnect(), S = null, T?.disconnect(), T = null, e?.addEventListener("scroll", N, { passive: !0 }), e && typeof ResizeObserver < "u" && (T = new ResizeObserver(() => {
180
346
  A(), M("resize");
181
347
  }), T.observe(e), B(e)), e && typeof MutationObserver < "u" && (x = new MutationObserver(() => {
182
348
  B(e), M("content");
183
- }), x.observe(e, { childList: !0 })), f(() => M("resize"));
184
- }, { immediate: !0 }), E(() => t.contentSize, () => {
185
- f(() => M("content"));
186
- }), g(() => {
187
- t.scrollElement?.removeEventListener("scroll", N), x?.disconnect(), C?.disconnect(), T?.disconnect(), y !== null && clearTimeout(y), b !== null && cancelAnimationFrame(b);
188
- }), (t, n) => (v(), o("div", {
349
+ }), x.observe(e, { childList: !0 })), p(() => M("resize"));
350
+ }, { immediate: !0 }), D(() => t.contentSize, () => {
351
+ p(() => M("content"));
352
+ }), _(() => {
353
+ t.scrollElement?.removeEventListener("scroll", N), x?.disconnect(), S?.disconnect(), T?.disconnect(), v !== null && clearTimeout(v), b !== null && cancelAnimationFrame(b);
354
+ }), (t, n) => (y(), o("div", {
189
355
  ref_key: "trackElement",
190
356
  ref: i,
191
- class: p(["gallery-scrollbar", {
357
+ class: m(["gallery-scrollbar", {
192
358
  "gallery-scrollbar--dragging": c.value,
193
359
  "gallery-scrollbar--interacting": l.value,
194
360
  "gallery-scrollbar--ready": u.value,
195
- "gallery-scrollbar--visible": D.value
361
+ "gallery-scrollbar--visible": E.value
196
362
  }]),
197
- "aria-hidden": !D.value || void 0,
363
+ "aria-hidden": !E.value || void 0,
198
364
  onPointerdown: F
199
365
  }, [s("div", {
200
366
  class: "gallery-scrollbar-thumb",
@@ -205,70 +371,22 @@ var H = ["aria-hidden"], U = [
205
371
  "aria-valuemin": "0",
206
372
  "aria-valuenow": Math.round(e.scrollElement?.scrollTop ?? 0),
207
373
  role: "scrollbar",
208
- style: h(O.value),
209
- tabindex: D.value ? 0 : -1,
374
+ style: g(O.value),
375
+ tabindex: E.value ? 0 : -1,
210
376
  onKeydown: z,
211
377
  onPointercancel: R,
212
378
  onPointerdown: I,
213
379
  onPointermove: L,
214
380
  onPointerup: R
215
- }, null, 44, U)], 42, H));
216
- }
217
- }), q = {
218
- key: 0,
219
- class: "gallery-footer"
220
- }, J = {
221
- key: 0,
222
- class: "load-more-status",
223
- role: "status"
224
- }, Y = ["disabled"], te = {
225
- key: 2,
226
- class: "gallery-sentinel",
227
- "aria-hidden": "true"
228
- }, ne = {
229
- key: 3,
230
- class: "end-feed"
231
- }, re = ["disabled"], ie = /* @__PURE__ */ l({
232
- __name: "GalleryFooter",
233
- props: {
234
- canRetryEnd: { type: Boolean },
235
- hasError: { type: Boolean },
236
- hasNext: { type: Boolean },
237
- infiniteScroll: { type: Boolean },
238
- isLoading: { type: Boolean },
239
- loadMoreLocked: { type: Boolean }
240
- },
241
- emits: ["loadMore", "retryEnd"],
242
- setup(e, { emit: t }) {
243
- let n = e, r = t;
244
- function i() {
245
- n.loadMoreLocked || (n.hasNext ? r("loadMore") : r("retryEnd"));
246
- }
247
- return (t, n) => e.hasNext || e.isLoading || e.hasError || e.canRetryEnd ? (v(), o("footer", q, [e.isLoading ? (v(), o("p", J, " Loading more… ")) : e.hasError || e.hasNext && (!e.infiniteScroll || e.loadMoreLocked) ? (v(), o("button", {
248
- key: 1,
249
- "data-test": "load-more",
250
- class: "load-more-button",
251
- type: "button",
252
- disabled: e.loadMoreLocked,
253
- onClick: i
254
- }, C(e.hasError ? "Try again" : e.loadMoreLocked ? "Loading paused" : "Load more"), 9, Y)) : e.hasNext ? (v(), o("span", te)) : (v(), o("div", ne, [n[1] ||= s("p", {
255
- class: "end-feed-message",
256
- role: "status"
257
- }, " You've reached the end. ", -1), s("button", {
258
- "data-test": "retry-end",
259
- class: "load-more-button",
260
- type: "button",
261
- disabled: e.loadMoreLocked,
262
- onClick: n[0] ||= (e) => t.$emit("retryEnd")
263
- }, " Check for more ", 8, re)]))])) : a("", !0);
381
+ }, null, 44, X)], 42, ae));
264
382
  }
265
- }), ae = (e) => {
383
+ }), le = (e) => {
266
384
  for (let t in e) if (t.startsWith("aria-") || t === "role" || t === "title") return !0;
267
385
  return !1;
268
- }, X = (e) => e === "", Z = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) === t).join(" ").trim(), oe = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), se = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), ce = (e) => {
269
- let t = se(e);
386
+ }, ue = (e) => e === "", de = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) === t).join(" ").trim(), fe = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), pe = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), me = (e) => {
387
+ let t = pe(e);
270
388
  return t.charAt(0).toUpperCase() + t.slice(1);
271
- }, le = {
389
+ }, he = {
272
390
  xmlns: "http://www.w3.org/2000/svg",
273
391
  width: 24,
274
392
  height: 24,
@@ -278,27 +396,27 @@ var H = ["aria-hidden"], U = [
278
396
  "stroke-width": 2,
279
397
  "stroke-linecap": "round",
280
398
  "stroke-linejoin": "round"
281
- }, ue = ({ name: e, iconNode: t, absoluteStrokeWidth: n, "absolute-stroke-width": r, strokeWidth: i, "stroke-width": a, size: o = le.width, color: s = le.stroke, ...c }, { slots: l }) => d("svg", {
282
- ...le,
399
+ }, ge = ({ name: e, iconNode: t, absoluteStrokeWidth: n, "absolute-stroke-width": r, strokeWidth: i, "stroke-width": a, size: o = he.width, color: s = he.stroke, ...c }, { slots: l }) => f("svg", {
400
+ ...he,
283
401
  ...c,
284
402
  width: o,
285
403
  height: o,
286
404
  stroke: s,
287
- "stroke-width": X(n) || X(r) || n === !0 || r === !0 ? Number(i || a || le["stroke-width"]) * 24 / Number(o) : i || a || le["stroke-width"],
288
- class: Z("lucide", c.class, ...e ? [`lucide-${oe(ce(e))}-icon`, `lucide-${oe(e)}`] : ["lucide-icon"]),
289
- ...!l.default && !ae(c) && { "aria-hidden": "true" }
290
- }, [...t.map((e) => d(...e)), ...l.default ? [l.default()] : []]), de = (e, t) => (n, { slots: r, attrs: i }) => d(ue, {
405
+ "stroke-width": ue(n) || ue(r) || n === !0 || r === !0 ? Number(i || a || he["stroke-width"]) * 24 / Number(o) : i || a || he["stroke-width"],
406
+ class: de("lucide", c.class, ...e ? [`lucide-${fe(me(e))}-icon`, `lucide-${fe(e)}`] : ["lucide-icon"]),
407
+ ...!l.default && !le(c) && { "aria-hidden": "true" }
408
+ }, [...t.map((e) => f(...e)), ...l.default ? [l.default()] : []]), _e = (e, t) => (n, { slots: r, attrs: i }) => f(ge, {
291
409
  ...i,
292
410
  ...n,
293
411
  iconNode: t,
294
412
  name: e
295
- }, r), fe = de("chevron-left", [["path", {
413
+ }, r), ve = _e("chevron-left", [["path", {
296
414
  d: "m15 18-6-6 6-6",
297
415
  key: "1wnfg3"
298
- }]]), pe = de("chevron-right", [["path", {
416
+ }]]), ye = _e("chevron-right", [["path", {
299
417
  d: "m9 18 6-6-6-6",
300
418
  key: "mthhwq"
301
- }]]), me = de("pause", [["rect", {
419
+ }]]), be = _e("pause", [["rect", {
302
420
  x: "14",
303
421
  y: "3",
304
422
  width: "5",
@@ -312,10 +430,10 @@ var H = ["aria-hidden"], U = [
312
430
  height: "18",
313
431
  rx: "1",
314
432
  key: "1wsw3u"
315
- }]]), he = de("play", [["path", {
433
+ }]]), xe = _e("play", [["path", {
316
434
  d: "M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",
317
435
  key: "10ikf1"
318
- }]]), ge = de("volume-2", [
436
+ }]]), Se = _e("volume-2", [
319
437
  ["path", {
320
438
  d: "M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z",
321
439
  key: "uqj9uw"
@@ -328,7 +446,7 @@ var H = ["aria-hidden"], U = [
328
446
  d: "M19.364 18.364a9 9 0 0 0 0-12.728",
329
447
  key: "ijwkga"
330
448
  }]
331
- ]), _e = de("volume-x", [
449
+ ]), Ce = _e("volume-x", [
332
450
  ["path", {
333
451
  d: "M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z",
334
452
  key: "uqj9uw"
@@ -347,32 +465,32 @@ var H = ["aria-hidden"], U = [
347
465
  y2: "15",
348
466
  key: "5ykzw1"
349
467
  }]
350
- ]), ve = {
468
+ ]), we = {
351
469
  401: "Authentication required",
352
470
  403: "Access forbidden",
353
471
  404: "Preview not found",
354
472
  419: "Session expired",
355
473
  500: "Server error"
356
474
  };
357
- function ye(e) {
475
+ function Te(e) {
358
476
  return e.match(/\/demo-errors\/(401|403|404|419|500)\//)?.[1] ?? "Error";
359
477
  }
360
- function be(e) {
361
- return ve[ye(e)] ?? "Preview unavailable";
478
+ function Ee(e) {
479
+ return we[Te(e)] ?? "Preview unavailable";
362
480
  }
363
481
  //#endregion
364
482
  //#region src/core/mediaType.ts
365
- var xe = /\.(aac|flac|m4a|mp3|mp4|mov|ogg|opus|wav|webm)$/i;
366
- function Se(e) {
483
+ var De = /\.(aac|flac|m4a|mp3|mp4|mov|ogg|opus|wav|webm)$/i;
484
+ function Oe(e) {
367
485
  try {
368
- return xe.test(new URL(e).pathname);
486
+ return De.test(new URL(e).pathname);
369
487
  } catch {
370
- return xe.test(e.split("?")[0] ?? e);
488
+ return De.test(e.split("?")[0] ?? e);
371
489
  }
372
490
  }
373
491
  //#endregion
374
492
  //#region src/components/CardRegion.vue
375
- var Ce = /* @__PURE__ */ l({
493
+ var ke = /* @__PURE__ */ u({
376
494
  __name: "CardRegion",
377
495
  props: {
378
496
  index: {},
@@ -386,13 +504,13 @@ var Ce = /* @__PURE__ */ l({
386
504
  total: {}
387
505
  },
388
506
  setup(e) {
389
- let t = e, r = n(() => j(t.item, t.mediaIndex)), a = n(() => A(t.item)), s = n(() => M(t.item, r.value));
390
- return (t, n) => (v(), o("div", {
391
- class: p(["media-card-region", `media-card-${e.placement}`]),
392
- style: h({ height: `${e.region.height}px` }),
393
- onClick: n[0] ||= k(() => {}, ["stop"]),
394
- onKeydown: n[1] ||= k(() => {}, ["stop"])
395
- }, [(v(), i(x(e.region.component), {
507
+ let t = e, r = n(() => M(t.item, t.mediaIndex)), a = n(() => j(t.item)), s = n(() => N(t.item, r.value));
508
+ return (t, n) => (y(), o("div", {
509
+ class: m(["media-card-region", `media-card-${e.placement}`]),
510
+ style: g({ height: `${e.region.height}px` }),
511
+ onClick: n[0] ||= A(() => {}, ["stop"]),
512
+ onKeydown: n[1] ||= A(() => {}, ["stop"])
513
+ }, [(y(), i(S(e.region.component), {
396
514
  index: e.index,
397
515
  item: e.item,
398
516
  layout: e.layout,
@@ -414,18 +532,18 @@ var Ce = /* @__PURE__ */ l({
414
532
  "total"
415
533
  ]))], 38));
416
534
  }
417
- }), we = [
535
+ }), Ae = [
418
536
  "max",
419
537
  "value",
420
538
  "aria-valuetext",
421
539
  "disabled"
422
- ], Te = {
540
+ ], je = {
423
541
  key: 0,
424
542
  class: "media-controls-row"
425
- }, Ee = ["aria-label", "title"], De = { class: "media-controls-audio" }, Oe = ["aria-label", "title"], ke = ["value", "aria-valuetext"], Ae = {
543
+ }, Me = ["aria-label", "title"], Ne = { class: "media-controls-audio" }, Pe = ["aria-label", "title"], Fe = ["value", "aria-valuetext"], Ie = {
426
544
  class: "media-control-time",
427
545
  "aria-live": "off"
428
- }, je = /* @__PURE__ */ l({
546
+ }, Le = /* @__PURE__ */ u({
429
547
  __name: "MediaControls",
430
548
  props: {
431
549
  currentTime: {},
@@ -453,93 +571,93 @@ var Ce = /* @__PURE__ */ l({
453
571
  function d(e) {
454
572
  return Number(e.target.value);
455
573
  }
456
- let f = n(() => Math.max(0, r.duration)), m = n(() => l(r.currentTime, f.value)), g = n(() => ({ "--media-range-progress": `${f.value > 0 ? m.value / f.value * 100 : 0}%` })), _ = n(() => ({ "--media-range-progress": `${l(r.volume) * 100}%` }));
457
- return (t, n) => (v(), o("div", {
458
- class: p(["media-controls", `media-controls--${e.layout}`]),
574
+ let f = n(() => Math.max(0, r.duration)), p = n(() => l(r.currentTime, f.value)), h = n(() => ({ "--media-range-progress": `${f.value > 0 ? p.value / f.value * 100 : 0}%` })), _ = n(() => ({ "--media-range-progress": `${l(r.volume) * 100}%` }));
575
+ return (t, n) => (y(), o("div", {
576
+ class: m(["media-controls", `media-controls--${e.layout}`]),
459
577
  "aria-label": "Video controls",
460
- onClick: n[4] ||= k(() => {}, ["stop"]),
461
- onDblclick: n[5] ||= k(() => {}, ["stop"]),
462
- onKeydown: n[6] ||= k(() => {}, ["stop"]),
463
- onWheel: n[7] ||= k(() => {}, ["stop"])
578
+ onClick: n[4] ||= A(() => {}, ["stop"]),
579
+ onDblclick: n[5] ||= A(() => {}, ["stop"]),
580
+ onKeydown: n[6] ||= A(() => {}, ["stop"]),
581
+ onWheel: n[7] ||= A(() => {}, ["stop"])
464
582
  }, [s("input", {
465
583
  class: "media-control-range media-control-seek",
466
584
  type: "range",
467
585
  min: "0",
468
586
  max: f.value || 0,
469
587
  step: "0.1",
470
- value: m.value,
471
- style: h(g.value),
588
+ value: p.value,
589
+ style: g(h.value),
472
590
  "aria-label": "Seek video",
473
- "aria-valuetext": `${u(m.value)} of ${u(f.value)}`,
591
+ "aria-valuetext": `${u(p.value)} of ${u(f.value)}`,
474
592
  disabled: f.value <= 0,
475
593
  onInput: n[0] ||= (e) => c("seek", d(e))
476
- }, null, 44, we), e.layout === "reel" ? (v(), o("div", Te, [
594
+ }, null, 44, Ae), e.layout === "reel" ? (y(), o("div", je, [
477
595
  s("button", {
478
596
  type: "button",
479
597
  class: "media-control-button media-control-playback",
480
598
  "aria-label": e.playing ? "Pause video" : "Play video",
481
599
  title: e.playing ? "Pause" : "Play",
482
600
  onClick: n[1] ||= (e) => c("togglePlayback")
483
- }, [e.playing ? (v(), i(w(me), {
601
+ }, [e.playing ? (y(), i(T(be), {
484
602
  key: 0,
485
603
  size: 18,
486
604
  fill: "currentColor"
487
- })) : (v(), i(w(he), {
605
+ })) : (y(), i(T(xe), {
488
606
  key: 1,
489
607
  size: 18,
490
608
  fill: "currentColor"
491
- }))], 8, Ee),
492
- s("div", De, [s("button", {
609
+ }))], 8, Me),
610
+ s("div", Ne, [s("button", {
493
611
  type: "button",
494
612
  class: "media-control-button",
495
613
  "aria-label": e.muted ? "Unmute video" : "Mute video",
496
614
  title: e.muted ? "Unmute" : "Mute",
497
615
  onClick: n[2] ||= (e) => c("toggleMute")
498
- }, [e.muted || e.volume === 0 ? (v(), i(w(_e), {
616
+ }, [e.muted || e.volume === 0 ? (y(), i(T(Ce), {
499
617
  key: 0,
500
618
  size: 18
501
- })) : (v(), i(w(ge), {
619
+ })) : (y(), i(T(Se), {
502
620
  key: 1,
503
621
  size: 18
504
- }))], 8, Oe), s("input", {
622
+ }))], 8, Pe), s("input", {
505
623
  class: "media-control-range media-control-volume",
506
624
  type: "range",
507
625
  min: "0",
508
626
  max: "1",
509
627
  step: "0.05",
510
628
  value: e.volume,
511
- style: h(_.value),
629
+ style: g(_.value),
512
630
  "aria-label": "Video volume",
513
631
  "aria-valuetext": `${Math.round(e.volume * 100)} percent`,
514
632
  onInput: n[3] ||= (e) => c("volumeChange", d(e))
515
- }, null, 44, ke)]),
516
- s("output", Ae, C(u(m.value)) + " / " + C(u(f.value)), 1)
633
+ }, null, 44, Fe)]),
634
+ s("output", Ie, w(u(p.value)) + " / " + w(u(f.value)), 1)
517
635
  ])) : a("", !0)], 34));
518
636
  }
519
- }), Me = [
637
+ }), Re = [
520
638
  "data-post-id",
521
639
  "data-media-index",
522
640
  "aria-busy",
523
641
  "role",
524
642
  "tabindex"
525
- ], Ne = { class: "media-card-content" }, Pe = ["data-media-direction"], Fe = ["data-media-index"], Ie = {
643
+ ], ze = { class: "media-card-content" }, Be = ["data-media-direction"], Ve = ["data-media-index"], He = {
526
644
  key: 0,
527
645
  "data-test": "media-loading",
528
646
  class: "media-loading",
529
647
  "aria-hidden": "true"
530
- }, Le = ["aria-label"], Re = { class: "media-error-code" }, ze = [
648
+ }, Ue = ["aria-label"], We = { class: "media-error-code" }, Ge = [
531
649
  "src",
532
650
  "width",
533
651
  "height",
534
652
  "loop",
535
653
  "muted",
536
654
  "preload"
537
- ], Be = [
655
+ ], Ke = [
538
656
  "src",
539
657
  "width",
540
658
  "height",
541
659
  "fetchpriority"
542
- ], Ve = ["aria-label"], He = ["aria-label"], Ue = ["aria-label"], We = 40, Ge = 160, Ke = 24, qe = /* @__PURE__ */ l({
660
+ ], qe = ["aria-label"], Je = ["aria-label"], Ye = ["aria-label"], Xe = 40, Ze = 160, Qe = 24, $e = /* @__PURE__ */ u({
543
661
  __name: "MediaCard",
544
662
  props: {
545
663
  advanceOnMediaEnd: { type: Boolean },
@@ -566,47 +684,47 @@ var Ce = /* @__PURE__ */ l({
566
684
  "ready"
567
685
  ],
568
686
  setup(e, { emit: r }) {
569
- let l = e, u = null, d = 0, f = !1, m = null, _ = null, y = S("next"), b = r;
687
+ let c = e, u = null, d = 0, f = !1, p = null, h = null, v = C("next"), b = r;
570
688
  function x(e = !1, t = "pointer") {
571
689
  e && b("activate", t);
572
690
  }
573
- let T = n(() => A(l.item)), E = n(() => j(l.item, l.mediaIndex)), N = n(() => M(l.item, E.value)), P = n(() => l.mediaSource === "original" ? N.value.src : N.value.preview.src), F = n(() => l.mediaSource === "original" ? N.value.width : N.value.preview.width), I = n(() => l.mediaSource === "original" ? N.value.height : N.value.preview.height), L = S(null), R = S(0), z = S(0), B = S(!0), V = S(!1), H = S(1), U = 1, W = n(() => l.interactive && !!(l.cardHeader || l.cardFooter));
574
- function G(e) {
691
+ let S = n(() => j(c.item)), E = n(() => M(c.item, c.mediaIndex)), D = n(() => N(c.item, E.value)), P = n(() => c.mediaSource === "original" ? D.value.src : D.value.preview.src), F = n(() => c.mediaSource === "original" ? D.value.width : D.value.preview.width), I = n(() => c.mediaSource === "original" ? D.value.height : D.value.preview.height), L = C(null), R = C(0), z = C(0), B = C(!0), V = C(!1), H = C(1), U = 1, W = n(() => c.interactive && !!(c.cardHeader || c.cardFooter));
692
+ function ee(e) {
575
693
  return e.detail === 0 ? "keyboard" : "pointer";
576
694
  }
577
- function K(e, t) {
578
- let n = T.value.length, r = (e + n) % n;
579
- r !== E.value && (y.value = e < E.value ? "previous" : "next", b("mediaChange", r), t && t.detail > 0 && t.currentTarget?.blur());
695
+ function G(e, t) {
696
+ let n = S.value.length, r = (e + n) % n;
697
+ r !== E.value && (v.value = e < E.value ? "previous" : "next", b("mediaChange", r), t && t.detail > 0 && t.currentTarget?.blur());
580
698
  }
581
- function ee(e, t, n) {
699
+ function K(e, t, n) {
582
700
  return t === 1 ? e * 16 : t === 2 ? e * n : e;
583
701
  }
584
- function q() {
702
+ function te() {
585
703
  d = 0, f = !1, u !== null && clearTimeout(u), u = null;
586
704
  }
587
- function J() {
588
- u !== null && clearTimeout(u), u = setTimeout(q, Ge);
705
+ function ne() {
706
+ u !== null && clearTimeout(u), u = setTimeout(te, Ze);
589
707
  }
590
- function Y(e) {
591
- if (T.value.length <= 1) return;
592
- let t = e.currentTarget?.clientWidth || 1, n = ee(e.deltaX, e.deltaMode, t);
593
- if (n === 0 || (e.preventDefault(), J(), f) || (d += n, Math.abs(d) < Ke)) return;
708
+ function re(e) {
709
+ if (S.value.length <= 1) return;
710
+ let t = e.currentTarget?.clientWidth || 1, n = K(e.deltaX, e.deltaMode, t);
711
+ if (n === 0 || (e.preventDefault(), ne(), f) || (d += n, Math.abs(d) < Qe)) return;
594
712
  let r = Math.sign(d);
595
- d = 0, f = !0, K(E.value + r);
713
+ d = 0, f = !0, G(E.value + r);
596
714
  }
597
- function te(e) {
715
+ function q(e) {
598
716
  let t = e.touches[0];
599
- l.layout !== "reel" || !t || (m = t.clientX, _ = t.clientY);
717
+ c.layout !== "reel" || !t || (p = t.clientX, h = t.clientY);
600
718
  }
601
- function ne(e) {
719
+ function J(e) {
602
720
  let t = e.changedTouches[0];
603
- if (m === null || _ === null || !t) return;
604
- let n = m - t.clientX, r = _ - t.clientY;
605
- m = null, _ = null, !(Math.abs(n) <= Math.abs(r)) && (Math.abs(n) < We || K(E.value + Math.sign(n)));
721
+ if (p === null || h === null || !t) return;
722
+ let n = p - t.clientX, r = h - t.clientY;
723
+ p = null, h = null, !(Math.abs(n) <= Math.abs(r)) && (Math.abs(n) < Xe || G(E.value + Math.sign(n)));
606
724
  }
607
- let re = n(() => Se(P.value));
725
+ let Y = n(() => Oe(P.value));
608
726
  function ie(e) {
609
- l.layout === "reel" && (e.stopPropagation(), ae());
727
+ c.layout === "reel" && (e.stopPropagation(), ae());
610
728
  }
611
729
  async function ae() {
612
730
  if (L.value) {
@@ -648,23 +766,23 @@ var Ce = /* @__PURE__ */ l({
648
766
  let e = L.value;
649
767
  e && (e.muted && e.volume === 0 && (e.volume = U), e.muted = !e.muted, Z());
650
768
  }
651
- return g(() => {
652
- q();
653
- }), (n, r) => (v(), o("article", {
769
+ return _(() => {
770
+ te();
771
+ }), (n, r) => (y(), o("article", {
654
772
  "data-post-id": e.item.postId,
655
773
  "data-media-index": E.value,
656
- class: p(["media-card", {
774
+ class: m(["media-card", {
657
775
  "media-card--entering": e.entering,
658
776
  "media-card--error": e.previewState === "error"
659
777
  }]),
660
- style: h(e.itemStyle),
778
+ style: g(e.itemStyle),
661
779
  "aria-busy": e.previewState === "loading",
662
780
  role: e.interactive && !W.value ? "button" : void 0,
663
781
  tabindex: e.interactive && !W.value ? 0 : void 0,
664
- onClick: r[11] ||= (t) => x(e.interactive && !W.value, G(t)),
665
- onKeydown: [r[12] ||= O((t) => x(e.interactive && !W.value, "keyboard"), ["enter"]), r[13] ||= O(k((t) => x(e.interactive && !W.value, "keyboard"), ["prevent"]), ["space"])]
666
- }, [s("div", Ne, [
667
- e.cardHeader ? (v(), i(Ce, {
782
+ onClick: r[11] ||= (t) => x(e.interactive && !W.value, ee(t)),
783
+ onKeydown: [r[12] ||= k((t) => x(e.interactive && !W.value, "keyboard"), ["enter"]), r[13] ||= k(A((t) => x(e.interactive && !W.value, "keyboard"), ["prevent"]), ["space"])]
784
+ }, [s("div", ze, [
785
+ e.cardHeader ? (y(), i(ke, {
668
786
  key: 0,
669
787
  index: e.index,
670
788
  item: e.item,
@@ -686,28 +804,28 @@ var Ce = /* @__PURE__ */ l({
686
804
  "total"
687
805
  ])) : a("", !0),
688
806
  s("div", {
689
- class: p(["media-card-media", { "media-card-media--carousel": e.layout === "reel" && T.value.length > 1 }]),
690
- "data-media-direction": y.value,
691
- onWheel: Y,
692
- onTouchstartPassive: te,
693
- onTouchendPassive: ne
807
+ class: m(["media-card-media", { "media-card-media--carousel": e.layout === "reel" && S.value.length > 1 }]),
808
+ "data-media-direction": v.value,
809
+ onWheel: re,
810
+ onTouchstartPassive: q,
811
+ onTouchendPassive: J
694
812
  }, [
695
- c(t, { name: `media-slide-${y.value}` }, {
696
- default: D(() => [(v(), o("div", {
813
+ l(t, { name: `media-slide-${v.value}` }, {
814
+ default: O(() => [(y(), o("div", {
697
815
  key: `${e.item.postId}:${E.value}:${e.mediaSource ?? "preview"}`,
698
816
  class: "media-card-frame",
699
817
  "data-media-index": E.value
700
- }, [e.previewState === "loading" ? (v(), o("div", Ie, [...r[14] ||= [s("span", { class: "media-loading-shimmer" }, null, -1)]])) : e.previewState === "error" ? (v(), o("div", {
818
+ }, [e.previewState === "loading" ? (y(), o("div", He, [...r[14] ||= [s("span", { class: "media-loading-shimmer" }, null, -1)]])) : e.previewState === "error" ? (y(), o("div", {
701
819
  key: 1,
702
820
  "data-test": "media-error",
703
821
  class: "media-error",
704
822
  role: "img",
705
- "aria-label": `${w(ye)(P.value)} ${w(be)(P.value)}`
706
- }, [s("strong", Re, C(w(ye)(P.value)), 1), s("span", null, C(w(be)(P.value)), 1)], 8, Le)) : a("", !0), re.value ? (v(), o("video", {
823
+ "aria-label": `${T(Te)(P.value)} ${T(Ee)(P.value)}`
824
+ }, [s("strong", We, w(T(Te)(P.value)), 1), s("span", null, w(T(Ee)(P.value)), 1)], 8, Ue)) : a("", !0), Y.value ? (y(), o("video", {
707
825
  key: 2,
708
826
  ref_key: "videoElement",
709
827
  ref: L,
710
- class: p(["media-preview", {
828
+ class: m(["media-preview", {
711
829
  "media-preview--ready": e.previewState === "ready",
712
830
  "media-preview--reel-video": e.layout === "reel"
713
831
  }]),
@@ -728,9 +846,9 @@ var Ce = /* @__PURE__ */ l({
728
846
  onEnded: se,
729
847
  onClick: ie,
730
848
  onError: r[2] ||= (e) => n.$emit("error", E.value)
731
- }, null, 42, ze)) : (v(), o("img", {
849
+ }, null, 42, Ge)) : (y(), o("img", {
732
850
  key: 3,
733
- class: p(["media-preview", { "media-preview--ready": e.previewState === "ready" }]),
851
+ class: m(["media-preview", { "media-preview--ready": e.previewState === "ready" }]),
734
852
  src: P.value,
735
853
  width: F.value ?? void 0,
736
854
  height: I.value ?? void 0,
@@ -740,10 +858,10 @@ var Ce = /* @__PURE__ */ l({
740
858
  loading: "eager",
741
859
  onLoad: r[3] ||= (e) => n.$emit("ready", E.value),
742
860
  onError: r[4] ||= (e) => n.$emit("error", E.value)
743
- }, null, 42, Be))], 8, Fe))]),
861
+ }, null, 42, Ke))], 8, Ve))]),
744
862
  _: 1
745
863
  }, 8, ["name"]),
746
- re.value && e.previewState === "ready" ? (v(), i(je, {
864
+ Y.value && e.previewState === "ready" ? (y(), i(Le, {
747
865
  key: 0,
748
866
  "current-time": R.value,
749
867
  duration: z.value,
@@ -763,33 +881,33 @@ var Ce = /* @__PURE__ */ l({
763
881
  "playing",
764
882
  "volume"
765
883
  ])) : a("", !0),
766
- T.value.length > 1 ? (v(), o("div", {
884
+ S.value.length > 1 ? (y(), o("div", {
767
885
  key: 1,
768
- class: p(["media-carousel-controls", { "media-carousel-controls--persistent": e.layout === "reel" }]),
886
+ class: m(["media-carousel-controls", { "media-carousel-controls--persistent": e.layout === "reel" }]),
769
887
  "aria-label": "Media navigation"
770
888
  }, [s("button", {
771
889
  type: "button",
772
890
  class: "media-carousel-control media-carousel-control--previous",
773
891
  "aria-label": `Previous media for post ${e.item.postId}`,
774
- onClick: r[5] ||= k((e) => K(E.value - 1, e), ["stop"]),
775
- onKeydown: r[6] ||= k(() => {}, ["stop"])
776
- }, [c(w(fe), { size: 20 })], 40, Ve), s("button", {
892
+ onClick: r[5] ||= A((e) => G(E.value - 1, e), ["stop"]),
893
+ onKeydown: r[6] ||= A(() => {}, ["stop"])
894
+ }, [l(T(ve), { size: 20 })], 40, qe), s("button", {
777
895
  type: "button",
778
896
  class: "media-carousel-control media-carousel-control--next",
779
897
  "aria-label": `Next media for post ${e.item.postId}`,
780
- onClick: r[7] ||= k((e) => K(E.value + 1, e), ["stop"]),
781
- onKeydown: r[8] ||= k(() => {}, ["stop"])
782
- }, [c(w(pe), { size: 20 })], 40, He)], 2)) : a("", !0),
783
- W.value ? (v(), o("button", {
898
+ onClick: r[7] ||= A((e) => G(E.value + 1, e), ["stop"]),
899
+ onKeydown: r[8] ||= A(() => {}, ["stop"])
900
+ }, [l(T(ye), { size: 20 })], 40, Je)], 2)) : a("", !0),
901
+ W.value ? (y(), o("button", {
784
902
  key: 2,
785
903
  class: "media-card-activator",
786
904
  type: "button",
787
905
  "aria-label": `Open post ${e.item.postId}`,
788
- onClick: r[9] ||= k((e) => n.$emit("activate", G(e)), ["stop"]),
789
- onKeydown: r[10] ||= k(() => {}, ["stop"])
790
- }, null, 40, Ue)) : a("", !0)
791
- ], 42, Pe),
792
- e.cardFooter ? (v(), i(Ce, {
906
+ onClick: r[9] ||= A((e) => n.$emit("activate", ee(e)), ["stop"]),
907
+ onKeydown: r[10] ||= A(() => {}, ["stop"])
908
+ }, null, 40, Ye)) : a("", !0)
909
+ ], 42, Be),
910
+ e.cardFooter ? (y(), i(ke, {
793
911
  key: 1,
794
912
  index: e.index,
795
913
  item: e.item,
@@ -810,9 +928,9 @@ var Ce = /* @__PURE__ */ l({
810
928
  "region",
811
929
  "total"
812
930
  ])) : a("", !0)
813
- ])], 46, Me));
931
+ ])], 46, Re));
814
932
  }
815
- }), Je = { class: "masonry-feed-shell" }, Ye = ["aria-hidden", "inert"], Xe = 240, Ze = 6, Qe = 12, $e = 800, et = 1.5, tt = /* @__PURE__ */ l({
933
+ }), et = { class: "masonry-feed-shell" }, tt = ["aria-hidden", "inert"], nt = 240, rt = 6, it = 12, at = 800, ot = 1.5, st = /* @__PURE__ */ u({
816
934
  __name: "MasonryFeed",
817
935
  props: {
818
936
  enteringPostIds: {},
@@ -821,6 +939,8 @@ var Ce = /* @__PURE__ */ l({
821
939
  canRetryEnd: { type: Boolean },
822
940
  cardFooter: {},
823
941
  cardHeader: {},
942
+ feedFooter: {},
943
+ feedFooterActions: {},
824
944
  hasNext: { type: Boolean },
825
945
  infiniteScroll: { type: Boolean },
826
946
  isLoadingMore: { type: Boolean },
@@ -829,6 +949,7 @@ var Ce = /* @__PURE__ */ l({
829
949
  mediaIndices: {},
830
950
  nextPageError: { type: Boolean },
831
951
  previewStates: {},
952
+ state: {},
832
953
  total: {}
833
954
  },
834
955
  emits: [
@@ -840,23 +961,23 @@ var Ce = /* @__PURE__ */ l({
840
961
  "retryEnd"
841
962
  ],
842
963
  setup(t, { expose: r, emit: a }) {
843
- let l = t, u = a, d = S(null), f = `vibe-masonry-${T()}`, m = S(null), _ = S(0), y = S(Ze), x = S(0), C = S(0), D = S(0), O = null, k = null, A = null, j = n(() => z(l.items, _.value, {
844
- additionalHeight: (l.cardHeader?.height ?? 0) + (l.cardFooter?.height ?? 0),
845
- gap: y.value,
846
- minColumnWidth: Xe
847
- })), M = n(() => ({ height: `${j.value.height}px` })), F = n(() => {
848
- let e = Math.max($e, C.value * et), t = {
849
- scrollTop: x.value - D.value,
850
- viewportHeight: C.value
851
- }, n = R(j.value.items, {
964
+ let c = t, u = a, d = C(null), f = `vibe-masonry-${E()}`, p = C(null), h = C(0), v = C(rt), b = C(0), S = C(0), w = C(0), O = null, k = null, A = null, j = n(() => J(c.items, h.value, {
965
+ additionalHeight: (c.cardHeader?.height ?? 0) + (c.cardFooter?.height ?? 0),
966
+ gap: v.value,
967
+ minColumnWidth: nt
968
+ })), M = n(() => ({ height: `${j.value.height}px` })), N = n(() => {
969
+ let e = Math.max(at, S.value * ot), t = {
970
+ scrollTop: b.value - w.value,
971
+ viewportHeight: S.value
972
+ }, n = q(j.value.items, {
852
973
  ...t,
853
974
  overscan: e
854
- }), r = new Set(R(j.value.items, {
975
+ }), r = new Set(q(j.value.items, {
855
976
  ...t,
856
977
  overscan: 0
857
978
  }));
858
979
  return n.flatMap((e) => {
859
- let t = l.items[e];
980
+ let t = c.items[e];
860
981
  return t ? [{
861
982
  fetchPriority: r.has(e) ? "high" : "low",
862
983
  index: e,
@@ -864,15 +985,15 @@ var Ce = /* @__PURE__ */ l({
864
985
  }] : [];
865
986
  });
866
987
  });
867
- function I(e) {
868
- let t = j.value.items[e], n = l.items[e]?.postId;
988
+ function F(e) {
989
+ let t = j.value.items[e], n = c.items[e]?.postId;
869
990
  if (!t) return {};
870
- let r = n !== void 0 && l.enteringPostIds.has(n) ? L({
991
+ let r = n !== void 0 && c.enteringPostIds.has(n) ? re({
871
992
  containerHeight: j.value.height,
872
- gap: y.value
993
+ gap: v.value
873
994
  }) : 0;
874
995
  return {
875
- "--masonry-entry-delay": `${n === void 0 ? 0 : l.entryDelays.get(n) ?? 0}ms`,
996
+ "--masonry-entry-delay": `${n === void 0 ? 0 : c.entryDelays.get(n) ?? 0}ms`,
876
997
  top: `${t.y}px`,
877
998
  left: `${t.x}px`,
878
999
  width: `${t.width}px`,
@@ -880,58 +1001,58 @@ var Ce = /* @__PURE__ */ l({
880
1001
  transform: `translate3d(0, ${r}px, 0)`
881
1002
  };
882
1003
  }
883
- function B() {
1004
+ function I() {
884
1005
  let e = d.value;
885
1006
  if (!e) return;
886
- x.value = e.scrollTop, C.value = e.clientHeight;
887
- let t = m.value;
888
- t && (D.value = t.getBoundingClientRect().top - e.getBoundingClientRect().top + e.scrollTop);
1007
+ b.value = e.scrollTop, S.value = e.clientHeight;
1008
+ let t = p.value;
1009
+ t && (w.value = t.getBoundingClientRect().top - e.getBoundingClientRect().top + e.scrollTop);
889
1010
  }
890
- function V(e) {
1011
+ function L(e) {
891
1012
  let t = e.ownerDocument.documentElement.clientWidth;
892
- _.value = e.clientWidth, y.value = Math.min(Qe, Math.max(Ze, t * .0075)), B();
1013
+ h.value = e.clientWidth, v.value = Math.min(it, Math.max(rt, t * .0075)), I();
893
1014
  }
894
- function H(e) {
1015
+ function R(e) {
895
1016
  let t = e.currentTarget;
896
- t && (x.value = t.scrollTop, !l.loadMoreLocked && l.infiniteScroll && P(t) && u("loadMore"));
1017
+ t && (b.value = t.scrollTop, !c.loadMoreLocked && c.infiniteScroll && K(t) && u("loadMore"));
897
1018
  }
898
- function U() {
1019
+ function z() {
899
1020
  let e = d.value;
900
- !l.loadMoreLocked && e && P(e) && u("loadMore");
1021
+ !c.loadMoreLocked && e && K(e) && u("loadMore");
901
1022
  }
902
- function W() {
1023
+ function B() {
903
1024
  return d.value;
904
1025
  }
905
- return E(m, (e) => {
906
- O?.disconnect(), O = null, A !== null && cancelAnimationFrame(A), e && (V(e), !(typeof ResizeObserver > "u") && (O = new ResizeObserver(([t]) => {
1026
+ return D(p, (e) => {
1027
+ O?.disconnect(), O = null, A !== null && cancelAnimationFrame(A), e && (L(e), !(typeof ResizeObserver > "u") && (O = new ResizeObserver(([t]) => {
907
1028
  let n = t?.contentRect.width ?? e.clientWidth;
908
- Math.abs(n - _.value) < .5 || (A = requestAnimationFrame(() => {
909
- A = null, V(e);
1029
+ Math.abs(n - h.value) < .5 || (A = requestAnimationFrame(() => {
1030
+ A = null, L(e);
910
1031
  }));
911
1032
  }), O.observe(e)));
912
- }), E(d, (e) => {
913
- k?.disconnect(), k = null, e && (B(), !(typeof ResizeObserver > "u") && (k = new ResizeObserver(B), k.observe(e)));
914
- }), g(() => {
1033
+ }), D(d, (e) => {
1034
+ k?.disconnect(), k = null, e && (I(), !(typeof ResizeObserver > "u") && (k = new ResizeObserver(I), k.observe(e)));
1035
+ }), _(() => {
915
1036
  O?.disconnect(), k?.disconnect(), A !== null && cancelAnimationFrame(A);
916
1037
  }), r({
917
- getScrollElement: W,
918
- loadIfNearBottom: U
919
- }), (n, r) => (v(), o("div", Je, [s("main", {
1038
+ getScrollElement: B,
1039
+ loadIfNearBottom: z
1040
+ }), (n, r) => (y(), o("div", et, [s("main", {
920
1041
  id: f,
921
1042
  ref_key: "galleryElement",
922
1043
  ref: d,
923
- class: p(["gallery-shell masonry-feed", { "masonry-feed--suspended": t.suspended }]),
1044
+ class: m(["gallery-shell masonry-feed", { "masonry-feed--suspended": t.suspended }]),
924
1045
  "data-layout-mode": "masonry",
925
1046
  "aria-hidden": t.suspended || void 0,
926
1047
  inert: t.suspended || void 0,
927
- onScrollPassive: H
1048
+ onScrollPassive: R
928
1049
  }, [s("section", {
929
1050
  ref_key: "masonryElement",
930
- ref: m,
931
- class: p(["masonry", { "masonry--ready": _.value > 0 }]),
932
- style: h(M.value),
1051
+ ref: p,
1052
+ class: m(["masonry", { "masonry--ready": h.value > 0 }]),
1053
+ style: g(M.value),
933
1054
  "aria-label": "Media gallery"
934
- }, [(v(!0), o(e, null, b(F.value, ({ fetchPriority: e, item: n, index: r }) => (v(), i(qe, {
1055
+ }, [(y(!0), o(e, null, x(N.value, ({ fetchPriority: e, item: n, index: r }) => (y(), i($e, {
935
1056
  key: n.postId,
936
1057
  class: "masonry-item",
937
1058
  entering: t.enteringPostIds.has(n.postId),
@@ -940,12 +1061,12 @@ var Ce = /* @__PURE__ */ l({
940
1061
  "card-header": t.cardHeader,
941
1062
  index: r,
942
1063
  item: n,
943
- "item-style": I(r),
1064
+ "item-style": F(r),
944
1065
  interactive: "",
945
1066
  layout: "masonry",
946
1067
  "loaded-count": t.items.length,
947
1068
  "media-index": t.mediaIndices.get(n.postId) ?? 0,
948
- "preview-state": t.previewStates.get(w(N)(n.postId, t.mediaIndices.get(n.postId) ?? 0)) ?? "loading",
1069
+ "preview-state": t.previewStates.get(T(P)(n.postId, t.mediaIndices.get(n.postId) ?? 0)) ?? "loading",
949
1070
  total: t.total,
950
1071
  onActivate: (e) => u("activate", n.postId, e),
951
1072
  onMediaChange: (e) => u("mediaChange", n.postId, e),
@@ -967,23 +1088,29 @@ var Ce = /* @__PURE__ */ l({
967
1088
  "onMediaChange",
968
1089
  "onReady",
969
1090
  "onError"
970
- ]))), 128))], 6), c(ie, {
1091
+ ]))), 128))], 6), l(U, {
1092
+ actions: t.feedFooterActions,
971
1093
  "can-retry-end": t.canRetryEnd,
1094
+ "feed-footer": t.feedFooter,
972
1095
  "has-error": t.nextPageError,
973
1096
  "has-next": t.hasNext,
974
1097
  "infinite-scroll": t.infiniteScroll,
975
1098
  "is-loading": t.isLoadingMore,
976
1099
  "load-more-locked": t.loadMoreLocked,
1100
+ state: t.state,
977
1101
  onLoadMore: r[0] ||= (e) => u("loadMore"),
978
1102
  onRetryEnd: r[1] ||= (e) => u("retryEnd")
979
1103
  }, null, 8, [
1104
+ "actions",
980
1105
  "can-retry-end",
1106
+ "feed-footer",
981
1107
  "has-error",
982
1108
  "has-next",
983
1109
  "infinite-scroll",
984
1110
  "is-loading",
985
- "load-more-locked"
986
- ])], 42, Ye), c(ee, {
1111
+ "load-more-locked",
1112
+ "state"
1113
+ ])], 42, tt), l(ce, {
987
1114
  "content-size": j.value.height,
988
1115
  "controls-id": f,
989
1116
  "scroll-element": d.value,
@@ -994,7 +1121,7 @@ var Ce = /* @__PURE__ */ l({
994
1121
  "suspended"
995
1122
  ])]));
996
1123
  }
997
- }), nt = ["aria-label"], rt = /* @__PURE__ */ l({
1124
+ }), ct = ["aria-label"], lt = /* @__PURE__ */ u({
998
1125
  __name: "ReelAutoAdvanceProgress",
999
1126
  props: {
1000
1127
  durationMs: {},
@@ -1003,18 +1130,18 @@ var Ce = /* @__PURE__ */ l({
1003
1130
  emits: ["complete"],
1004
1131
  setup(e, { emit: t }) {
1005
1132
  let r = e, i = t, a = n(() => ({ "--vibe-reel-auto-advance-duration": `${r.durationMs}ms` }));
1006
- return (t, n) => (v(), o("div", {
1133
+ return (t, n) => (y(), o("div", {
1007
1134
  class: "reel-auto-advance",
1008
1135
  "data-test": "reel-auto-advance",
1009
1136
  role: "timer",
1010
1137
  "aria-label": e.label
1011
1138
  }, [s("span", {
1012
1139
  class: "reel-auto-advance-progress",
1013
- style: h(a.value),
1140
+ style: g(a.value),
1014
1141
  onAnimationend: n[0] ||= (e) => i("complete")
1015
- }, null, 36)], 8, nt));
1142
+ }, null, 36)], 8, ct));
1016
1143
  }
1017
- }), it = ["data-active-post-id", "data-active-media-index"], at = 2, ot = /* @__PURE__ */ l({
1144
+ }), ut = ["data-active-post-id", "data-active-media-index"], dt = 2, ft = /* @__PURE__ */ u({
1018
1145
  __name: "ReelFeed",
1019
1146
  props: {
1020
1147
  initialPostId: {},
@@ -1023,6 +1150,8 @@ var Ce = /* @__PURE__ */ l({
1023
1150
  canRetryEnd: { type: Boolean },
1024
1151
  cardFooter: {},
1025
1152
  cardHeader: {},
1153
+ feedFooter: {},
1154
+ feedFooterActions: {},
1026
1155
  hasNext: { type: Boolean },
1027
1156
  infiniteScroll: { type: Boolean },
1028
1157
  isLoadingMore: { type: Boolean },
@@ -1031,6 +1160,7 @@ var Ce = /* @__PURE__ */ l({
1031
1160
  mediaIndices: {},
1032
1161
  nextPageError: { type: Boolean },
1033
1162
  previewStates: {},
1163
+ state: {},
1034
1164
  total: {}
1035
1165
  },
1036
1166
  emits: [
@@ -1041,93 +1171,93 @@ var Ce = /* @__PURE__ */ l({
1041
1171
  "ready",
1042
1172
  "retryEnd"
1043
1173
  ],
1044
- setup(t, { expose: r, emit: l }) {
1045
- let u = t, d = l, m = S(null), y = u.initialPostId === null || u.initialPostId === void 0 ? -1 : u.items.findIndex((e) => e.postId === u.initialPostId), x = S(Math.max(0, y)), C = S(!1), T = 0, D = null, O = null, k = null, j = n(() => ({ gridTemplateRows: `repeat(${u.items.length}, 100cqh)` })), F = n(() => {
1046
- let e = Math.max(0, x.value - at), t = Math.min(u.items.length - 1, x.value + at);
1174
+ setup(t, { expose: r, emit: c }) {
1175
+ let u = t, d = c, f = C(null), h = u.initialPostId === null || u.initialPostId === void 0 ? -1 : u.items.findIndex((e) => e.postId === u.initialPostId), b = C(Math.max(0, h)), S = C(!1), w = 0, E = null, O = null, k = null, A = n(() => ({ gridTemplateRows: `repeat(${u.items.length}, 100cqh)` })), M = n(() => {
1176
+ let e = Math.max(0, b.value - dt), t = Math.min(u.items.length - 1, b.value + dt);
1047
1177
  return u.items.slice(e, t + 1).map((t, n) => ({
1048
- fetchPriority: e + n === x.value ? "high" : "low",
1178
+ fetchPriority: e + n === b.value ? "high" : "low",
1049
1179
  index: e + n,
1050
1180
  item: t
1051
1181
  }));
1052
- }), I = n(() => u.items[x.value]?.postId), L = n(() => u.items[x.value]), R = n(() => {
1053
- let e = I.value;
1182
+ }), F = n(() => u.items[b.value]?.postId), I = n(() => u.items[b.value]), L = n(() => {
1183
+ let e = F.value;
1054
1184
  return e === void 0 ? 0 : u.mediaIndices.get(e) ?? 0;
1185
+ }), R = n(() => {
1186
+ let e = F.value;
1187
+ return e === void 0 ? "loading" : u.previewStates.get(P(e, L.value)) ?? "loading";
1055
1188
  }), z = n(() => {
1056
1189
  let e = I.value;
1057
- return e === void 0 ? "loading" : u.previewStates.get(N(e, R.value)) ?? "loading";
1058
- }), B = n(() => {
1059
- let e = L.value;
1060
1190
  if (!e) return "";
1061
- let t = M(e, R.value);
1191
+ let t = N(e, L.value);
1062
1192
  return u.mediaSource === "original" ? t.src : t.preview.src;
1063
- }), V = n(() => z.value === "ready" && Se(B.value)), H = n(() => [
1064
- I.value,
1065
- R.value,
1193
+ }), B = n(() => R.value === "ready" && Oe(z.value)), V = n(() => [
1194
+ F.value,
1195
+ L.value,
1066
1196
  u.items.length,
1067
1197
  u.loadMoreLocked,
1068
1198
  u.reelAutoAdvance.enabled,
1069
1199
  u.reelAutoAdvance.includePostItems,
1070
1200
  u.reelAutoAdvance.intervalMs
1071
- ].join(":")), U = n(() => {
1072
- let e = L.value, t = !!(e && u.reelAutoAdvance.includePostItems && R.value < A(e).length - 1), n = u.reelAutoAdvance.intervalMs / 1e3;
1201
+ ].join(":")), H = n(() => {
1202
+ let e = I.value, t = !!(e && u.reelAutoAdvance.includePostItems && L.value < j(e).length - 1), n = u.reelAutoAdvance.intervalMs / 1e3;
1073
1203
  return `Auto advance to the next ${t ? "post item" : "post"} in ${n}s`;
1074
- }), W = n(() => u.reelAutoAdvance.enabled && L.value !== void 0 && z.value !== "loading" && !V.value);
1075
- function G(e) {
1204
+ }), W = n(() => u.reelAutoAdvance.enabled && I.value !== void 0 && R.value !== "loading" && !B.value);
1205
+ function ee(e) {
1076
1206
  return { gridRow: `${e + 1}` };
1077
1207
  }
1078
- function K(e) {
1079
- let t = T || e.clientHeight;
1208
+ function G(e) {
1209
+ let t = w || e.clientHeight;
1080
1210
  return t <= 0 || u.items.length === 0 ? 0 : Math.min(u.items.length - 1, Math.max(0, Math.round(e.scrollTop / t)));
1081
1211
  }
1082
- function ee(e) {
1212
+ function te(e) {
1083
1213
  let t = e.currentTarget;
1084
- t && (C.value || (x.value = K(t)), !u.loadMoreLocked && u.infiniteScroll && P(t) && d("loadMore"));
1214
+ t && (S.value || (b.value = G(t)), !u.loadMoreLocked && u.infiniteScroll && K(t) && d("loadMore"));
1085
1215
  }
1086
- function q() {
1087
- let e = m.value;
1088
- e && (te(!0), T = e.clientHeight, e.scrollTop = x.value * T, O !== null && cancelAnimationFrame(O), O = requestAnimationFrame(() => {
1089
- e.scrollTop = x.value * e.clientHeight, T = e.clientHeight, O = null;
1090
- }), J());
1216
+ function ne() {
1217
+ let e = f.value;
1218
+ e && (J(!0), w = e.clientHeight, e.scrollTop = b.value * w, O !== null && cancelAnimationFrame(O), O = requestAnimationFrame(() => {
1219
+ e.scrollTop = b.value * e.clientHeight, w = e.clientHeight, O = null;
1220
+ }), re());
1091
1221
  }
1092
- function J() {
1222
+ function re() {
1093
1223
  k !== null && clearTimeout(k), k = setTimeout(() => {
1094
1224
  k = null;
1095
- let e = m.value;
1096
- e && (T = e.clientHeight, e.scrollTop = x.value * T), te(!1);
1225
+ let e = f.value;
1226
+ e && (w = e.clientHeight, e.scrollTop = b.value * w), J(!1);
1097
1227
  }, 120);
1098
1228
  }
1099
- function Y() {
1100
- te(!0);
1101
- let e = m.value;
1102
- e && (T = e.clientHeight, e.scrollTop = x.value * T), J();
1229
+ function q() {
1230
+ J(!0);
1231
+ let e = f.value;
1232
+ e && (w = e.clientHeight, e.scrollTop = b.value * w), re();
1103
1233
  }
1104
- function te(e) {
1105
- C.value = e, m.value?.toggleAttribute("data-resizing", e);
1234
+ function J(e) {
1235
+ S.value = e, f.value?.toggleAttribute("data-resizing", e);
1106
1236
  }
1107
- function ne() {
1108
- let e = m.value;
1109
- !u.loadMoreLocked && e && P(e) && d("loadMore");
1237
+ function Y() {
1238
+ let e = f.value;
1239
+ !u.loadMoreLocked && e && K(e) && d("loadMore");
1110
1240
  }
1111
- function re(e) {
1112
- let t = L.value;
1241
+ function ie(e) {
1242
+ let t = I.value;
1113
1243
  if (!t) return !1;
1114
- let n = A(t).length;
1244
+ let n = j(t).length;
1115
1245
  if (n <= 1) return !1;
1116
- let r = (R.value + e + n) % n;
1246
+ let r = (L.value + e + n) % n;
1117
1247
  return d("mediaChange", t.postId, r), !0;
1118
1248
  }
1119
1249
  function ae(e) {
1120
- let t = x.value + e;
1121
- return !m.value || t < 0 || t >= u.items.length ? !1 : (Z(t), !0);
1250
+ let t = b.value + e;
1251
+ return !f.value || t < 0 || t >= u.items.length ? !1 : (Z(t), !0);
1122
1252
  }
1123
1253
  function X() {
1124
1254
  return typeof window.matchMedia == "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
1125
1255
  }
1126
1256
  function Z(e) {
1127
- let t = m.value;
1257
+ let t = f.value;
1128
1258
  if (!t) return;
1129
- let n = e * (T || t.clientHeight);
1130
- if (x.value = e, !X() && typeof t.scrollTo == "function") {
1259
+ let n = e * (w || t.clientHeight);
1260
+ if (b.value = e, !X() && typeof t.scrollTo == "function") {
1131
1261
  t.scrollTo({
1132
1262
  behavior: "smooth",
1133
1263
  top: n
@@ -1138,13 +1268,13 @@ var Ce = /* @__PURE__ */ l({
1138
1268
  }
1139
1269
  function oe() {
1140
1270
  if (!u.reelAutoAdvance.enabled) return;
1141
- let e = L.value;
1271
+ let e = I.value;
1142
1272
  if (!e) return;
1143
- if (u.reelAutoAdvance.includePostItems && R.value < A(e).length - 1) {
1144
- d("mediaChange", e.postId, R.value + 1);
1273
+ if (u.reelAutoAdvance.includePostItems && L.value < j(e).length - 1) {
1274
+ d("mediaChange", e.postId, L.value + 1);
1145
1275
  return;
1146
1276
  }
1147
- let t = x.value + 1, n = u.items[t];
1277
+ let t = b.value + 1, n = u.items[t];
1148
1278
  if (!n) {
1149
1279
  u.hasNext && !u.loadMoreLocked && d("loadMore");
1150
1280
  return;
@@ -1152,38 +1282,38 @@ var Ce = /* @__PURE__ */ l({
1152
1282
  u.reelAutoAdvance.includePostItems && (u.mediaIndices.get(n.postId) ?? 0) !== 0 && d("mediaChange", n.postId, 0), Z(t);
1153
1283
  }
1154
1284
  function se(e, t) {
1155
- !u.reelAutoAdvance.enabled || e !== I.value || t !== R.value || !V.value || oe();
1285
+ !u.reelAutoAdvance.enabled || e !== F.value || t !== L.value || !B.value || oe();
1156
1286
  }
1157
- return E(m, (e) => {
1158
- D?.disconnect(), D = null, e && (T = e.clientHeight, !(typeof ResizeObserver > "u") && (D = new ResizeObserver(q), D.observe(e)));
1159
- }), E(() => u.items.length, async (e) => {
1160
- x.value = Math.min(x.value, Math.max(0, e - 1)), await f(), q();
1161
- }), E(I, (e) => {
1287
+ return D(f, (e) => {
1288
+ E?.disconnect(), E = null, e && (w = e.clientHeight, !(typeof ResizeObserver > "u") && (E = new ResizeObserver(ne), E.observe(e)));
1289
+ }), D(() => u.items.length, async (e) => {
1290
+ b.value = Math.min(b.value, Math.max(0, e - 1)), await p(), ne();
1291
+ }), D(F, (e) => {
1162
1292
  e !== void 0 && d("activeChange", e);
1163
- }, { immediate: !0 }), _(() => {
1164
- window.addEventListener("resize", Y), window.addEventListener("orientationchange", Y), y >= 0 && f(q);
1165
- }), g(() => {
1166
- window.removeEventListener("resize", Y), window.removeEventListener("orientationchange", Y), D?.disconnect(), O !== null && cancelAnimationFrame(O), k !== null && clearTimeout(k);
1293
+ }, { immediate: !0 }), v(() => {
1294
+ window.addEventListener("resize", q), window.addEventListener("orientationchange", q), h >= 0 && p(ne);
1295
+ }), _(() => {
1296
+ window.removeEventListener("resize", q), window.removeEventListener("orientationchange", q), E?.disconnect(), O !== null && cancelAnimationFrame(O), k !== null && clearTimeout(k);
1167
1297
  }), r({
1168
- activeIndex: x,
1169
- activePostId: I,
1170
- changeActiveMedia: re,
1171
- loadIfNearBottom: ne,
1298
+ activeIndex: b,
1299
+ activePostId: F,
1300
+ changeActiveMedia: ie,
1301
+ loadIfNearBottom: Y,
1172
1302
  moveActivePost: ae
1173
- }), (n, r) => (v(), o("main", {
1174
- class: p(["reel-shell", {
1303
+ }), (n, r) => (y(), o("main", {
1304
+ class: m(["reel-shell", {
1175
1305
  "reel-shell--has-footer": !!t.cardFooter,
1176
1306
  "reel-shell--has-header": !!t.cardHeader
1177
1307
  }]),
1178
1308
  "data-layout-mode": "reel"
1179
1309
  }, [
1180
- t.cardHeader && L.value ? (v(), i(Ce, {
1310
+ t.cardHeader && I.value ? (y(), i(ke, {
1181
1311
  key: 0,
1182
- index: x.value,
1183
- item: L.value,
1312
+ index: b.value,
1313
+ item: I.value,
1184
1314
  layout: "reel",
1185
1315
  "loaded-count": t.items.length,
1186
- "media-index": R.value,
1316
+ "media-index": L.value,
1187
1317
  "media-source": t.mediaSource,
1188
1318
  placement: "header",
1189
1319
  region: t.cardHeader,
@@ -1199,29 +1329,29 @@ var Ce = /* @__PURE__ */ l({
1199
1329
  ])) : a("", !0),
1200
1330
  s("div", {
1201
1331
  ref_key: "galleryElement",
1202
- ref: m,
1332
+ ref: f,
1203
1333
  class: "gallery-shell reel-feed",
1204
- "data-active-post-id": I.value,
1205
- "data-active-media-index": R.value,
1206
- onScrollPassive: ee
1334
+ "data-active-post-id": F.value,
1335
+ "data-active-media-index": L.value,
1336
+ onScrollPassive: te
1207
1337
  }, [s("section", {
1208
1338
  class: "reel-track",
1209
- style: h(j.value),
1339
+ style: g(A.value),
1210
1340
  "aria-label": "Media gallery"
1211
- }, [(v(!0), o(e, null, b(F.value, ({ fetchPriority: e, item: n, index: r }) => (v(), i(qe, {
1341
+ }, [(y(!0), o(e, null, x(M.value, ({ fetchPriority: e, item: n, index: r }) => (y(), i($e, {
1212
1342
  key: n.postId,
1213
- "advance-on-media-end": u.reelAutoAdvance.enabled && r === x.value,
1343
+ "advance-on-media-end": u.reelAutoAdvance.enabled && r === b.value,
1214
1344
  class: "reel-item",
1215
1345
  entering: !1,
1216
1346
  "fetch-priority": e,
1217
1347
  index: r,
1218
1348
  item: n,
1219
- "item-style": G(r),
1349
+ "item-style": ee(r),
1220
1350
  layout: "reel",
1221
1351
  "loaded-count": t.items.length,
1222
1352
  "media-index": t.mediaIndices.get(n.postId) ?? 0,
1223
1353
  "media-source": t.mediaSource,
1224
- "preview-state": t.previewStates.get(w(N)(n.postId, t.mediaIndices.get(n.postId) ?? 0)) ?? "loading",
1354
+ "preview-state": t.previewStates.get(T(P)(n.postId, t.mediaIndices.get(n.postId) ?? 0)) ?? "loading",
1225
1355
  total: t.total,
1226
1356
  onMediaChange: (e) => d("mediaChange", n.postId, e),
1227
1357
  onEnded: (e) => se(n.postId, e),
@@ -1242,30 +1372,36 @@ var Ce = /* @__PURE__ */ l({
1242
1372
  "onEnded",
1243
1373
  "onReady",
1244
1374
  "onError"
1245
- ]))), 128))], 4), c(ie, {
1375
+ ]))), 128))], 4), l(U, {
1376
+ actions: t.feedFooterActions,
1246
1377
  "can-retry-end": t.canRetryEnd,
1378
+ "feed-footer": t.feedFooter,
1247
1379
  "has-error": t.nextPageError,
1248
1380
  "has-next": t.hasNext,
1249
1381
  "infinite-scroll": t.infiniteScroll,
1250
1382
  "is-loading": t.isLoadingMore,
1251
1383
  "load-more-locked": t.loadMoreLocked,
1384
+ state: t.state,
1252
1385
  onLoadMore: r[0] ||= (e) => d("loadMore"),
1253
1386
  onRetryEnd: r[1] ||= (e) => d("retryEnd")
1254
1387
  }, null, 8, [
1388
+ "actions",
1255
1389
  "can-retry-end",
1390
+ "feed-footer",
1256
1391
  "has-error",
1257
1392
  "has-next",
1258
1393
  "infinite-scroll",
1259
1394
  "is-loading",
1260
- "load-more-locked"
1261
- ])], 40, it),
1262
- t.cardFooter && L.value ? (v(), i(Ce, {
1395
+ "load-more-locked",
1396
+ "state"
1397
+ ])], 40, ut),
1398
+ t.cardFooter && I.value ? (y(), i(ke, {
1263
1399
  key: 1,
1264
- index: x.value,
1265
- item: L.value,
1400
+ index: b.value,
1401
+ item: I.value,
1266
1402
  layout: "reel",
1267
1403
  "loaded-count": t.items.length,
1268
- "media-index": R.value,
1404
+ "media-index": L.value,
1269
1405
  "media-source": t.mediaSource,
1270
1406
  placement: "footer",
1271
1407
  region: t.cardFooter,
@@ -1279,24 +1415,24 @@ var Ce = /* @__PURE__ */ l({
1279
1415
  "region",
1280
1416
  "total"
1281
1417
  ])) : a("", !0),
1282
- W.value ? (v(), i(rt, {
1283
- key: H.value,
1418
+ W.value ? (y(), i(lt, {
1419
+ key: V.value,
1284
1420
  "duration-ms": t.reelAutoAdvance.intervalMs,
1285
- label: U.value,
1421
+ label: H.value,
1286
1422
  onComplete: oe
1287
1423
  }, null, 8, ["duration-ms", "label"])) : a("", !0)
1288
1424
  ], 2));
1289
1425
  }
1290
- }), st = ["data-info-sheet-open", "data-info-sheet-mode"], ct = ["aria-hidden", "inert"], lt = {
1426
+ }), pt = ["data-info-sheet-open", "data-info-sheet-mode"], mt = ["aria-hidden", "inert"], ht = {
1291
1427
  key: 0,
1292
1428
  class: "reel-info-sheet-layer",
1293
1429
  "data-test": "reel-info-sheet"
1294
- }, ut = [
1430
+ }, gt = [
1295
1431
  "role",
1296
1432
  "aria-modal",
1297
1433
  "tabindex",
1298
1434
  "data-active-post-id"
1299
- ], dt = /* @__PURE__ */ l({
1435
+ ], _t = /* @__PURE__ */ u({
1300
1436
  __name: "ReelLayout",
1301
1437
  props: {
1302
1438
  infoSheet: {},
@@ -1309,6 +1445,8 @@ var Ce = /* @__PURE__ */ l({
1309
1445
  canRetryEnd: { type: Boolean },
1310
1446
  cardFooter: {},
1311
1447
  cardHeader: {},
1448
+ feedFooter: {},
1449
+ feedFooterActions: {},
1312
1450
  hasNext: { type: Boolean },
1313
1451
  infiniteScroll: { type: Boolean },
1314
1452
  isLoadingMore: { type: Boolean },
@@ -1317,6 +1455,7 @@ var Ce = /* @__PURE__ */ l({
1317
1455
  mediaIndices: {},
1318
1456
  nextPageError: { type: Boolean },
1319
1457
  previewStates: {},
1458
+ state: {},
1320
1459
  total: {}
1321
1460
  },
1322
1461
  emits: [
@@ -1328,82 +1467,84 @@ var Ce = /* @__PURE__ */ l({
1328
1467
  "ready",
1329
1468
  "retryEnd"
1330
1469
  ],
1331
- setup(e, { expose: r, emit: l }) {
1332
- let d = e, h = l, _ = S(null), y = S(null), b = null, C = n(() => {
1333
- let e = d.initialPostId === null || d.initialPostId === void 0 ? -1 : d.items.findIndex((e) => e.postId === d.initialPostId);
1470
+ setup(e, { expose: r, emit: c }) {
1471
+ let u = e, f = c, g = C(null), v = C(null), b = null, x = n(() => {
1472
+ let e = u.initialPostId === null || u.initialPostId === void 0 ? -1 : u.items.findIndex((e) => e.postId === u.initialPostId);
1334
1473
  return Math.max(0, e);
1335
- }), w = n(() => d.items[C.value]), T = n(() => {
1474
+ }), w = n(() => u.items[x.value]), T = n(() => {
1336
1475
  let e = w.value?.postId;
1337
- return e === void 0 ? 0 : d.mediaIndices.get(e) ?? 0;
1338
- }), O = n(() => !!(d.infoSheet && d.infoSheetEnabled && w.value)), k = n(() => {
1476
+ return e === void 0 ? 0 : u.mediaIndices.get(e) ?? 0;
1477
+ }), E = n(() => !!(u.infoSheet && u.infoSheetEnabled && w.value)), k = n(() => {
1339
1478
  let e = w.value;
1340
1479
  return e ? {
1341
- close: j,
1342
- index: C.value,
1480
+ close: A,
1481
+ index: x.value,
1343
1482
  item: e,
1344
1483
  layout: "reel",
1345
- loadedCount: d.items.length,
1346
- mediaCount: A(e).length,
1484
+ loadedCount: u.items.length,
1485
+ mediaCount: j(e).length,
1347
1486
  mediaIndex: T.value,
1348
- mediaItem: M(e, T.value),
1349
- mediaSource: d.mediaSource ?? "preview",
1350
- origin: d.origin,
1351
- total: d.total
1487
+ mediaItem: N(e, T.value),
1488
+ mediaSource: u.mediaSource ?? "preview",
1489
+ origin: u.origin,
1490
+ total: u.total
1352
1491
  } : null;
1353
1492
  });
1354
- function j() {
1355
- h("closeInfoSheet");
1493
+ function A() {
1494
+ f("closeInfoSheet");
1356
1495
  }
1357
- function N(e) {
1358
- return _.value?.changeActiveMedia(e) ?? !1;
1496
+ function M(e) {
1497
+ return g.value?.changeActiveMedia(e) ?? !1;
1359
1498
  }
1360
1499
  function P() {
1361
- _.value?.loadIfNearBottom();
1500
+ g.value?.loadIfNearBottom();
1362
1501
  }
1363
1502
  function F(e) {
1364
- return _.value?.moveActivePost(e) ?? !1;
1503
+ return g.value?.moveActivePost(e) ?? !1;
1365
1504
  }
1366
1505
  function I(e, t) {
1367
- h("error", e, t);
1506
+ f("error", e, t);
1368
1507
  }
1369
1508
  function L(e, t) {
1370
- h("mediaChange", e, t);
1509
+ f("mediaChange", e, t);
1371
1510
  }
1372
1511
  function R(e, t) {
1373
- h("ready", e, t);
1512
+ f("ready", e, t);
1374
1513
  }
1375
- return E(() => ({
1376
- overlay: d.infoSheetOverlay,
1377
- visible: O.value
1514
+ return D(() => ({
1515
+ overlay: u.infoSheetOverlay,
1516
+ visible: E.value
1378
1517
  }), async (e, t) => {
1379
1518
  if (e.visible && !t?.visible) {
1380
- b = document.activeElement instanceof HTMLElement ? document.activeElement : null, e.overlay && (await f(), y.value?.focus({ preventScroll: !0 }));
1519
+ b = document.activeElement instanceof HTMLElement ? document.activeElement : null, e.overlay && (await p(), v.value?.focus({ preventScroll: !0 }));
1381
1520
  return;
1382
1521
  }
1383
1522
  if (!e.visible && t?.visible && b?.isConnected) {
1384
1523
  let e = b;
1385
- b = null, await f(), e.focus({ preventScroll: !0 });
1524
+ b = null, await p(), e.focus({ preventScroll: !0 });
1386
1525
  }
1387
- }), g(() => {
1526
+ }), _(() => {
1388
1527
  b = null;
1389
1528
  }), r({
1390
- changeActiveMedia: N,
1529
+ changeActiveMedia: M,
1391
1530
  loadIfNearBottom: P,
1392
1531
  moveActivePost: F
1393
- }), (n, r) => (v(), o("section", {
1394
- class: p(["reel-layout", `reel-layout--${e.infoSheetOverlay ? "overlay" : "layout"}`]),
1395
- "data-info-sheet-open": O.value || void 0,
1532
+ }), (n, r) => (y(), o("section", {
1533
+ class: m(["reel-layout", `reel-layout--${e.infoSheetOverlay ? "overlay" : "layout"}`]),
1534
+ "data-info-sheet-open": E.value || void 0,
1396
1535
  "data-info-sheet-mode": e.infoSheetOverlay ? "overlay" : "layout"
1397
1536
  }, [s("div", {
1398
1537
  class: "reel-layout-main",
1399
- "aria-hidden": e.infoSheetOverlay && O.value || void 0,
1400
- inert: e.infoSheetOverlay && O.value || void 0
1401
- }, [c(ot, {
1538
+ "aria-hidden": e.infoSheetOverlay && E.value || void 0,
1539
+ inert: e.infoSheetOverlay && E.value || void 0
1540
+ }, [l(ft, {
1402
1541
  ref_key: "reelFeed",
1403
- ref: _,
1542
+ ref: g,
1404
1543
  "can-retry-end": e.canRetryEnd,
1405
1544
  "card-footer": e.cardFooter,
1406
1545
  "card-header": e.cardHeader,
1546
+ "feed-footer": e.feedFooter,
1547
+ "feed-footer-actions": e.feedFooterActions,
1407
1548
  "has-next": e.hasNext,
1408
1549
  "infinite-scroll": e.infiniteScroll,
1409
1550
  "initial-post-id": e.initialPostId,
@@ -1415,17 +1556,20 @@ var Ce = /* @__PURE__ */ l({
1415
1556
  "next-page-error": e.nextPageError,
1416
1557
  "preview-states": e.previewStates,
1417
1558
  "reel-auto-advance": e.reelAutoAdvance,
1559
+ state: e.state,
1418
1560
  total: e.total,
1419
- onActiveChange: r[0] ||= (e) => h("activeChange", e),
1561
+ onActiveChange: r[0] ||= (e) => f("activeChange", e),
1420
1562
  onError: I,
1421
- onLoadMore: r[1] ||= (e) => h("loadMore"),
1563
+ onLoadMore: r[1] ||= (e) => f("loadMore"),
1422
1564
  onMediaChange: L,
1423
1565
  onReady: R,
1424
- onRetryEnd: r[2] ||= (e) => h("retryEnd")
1566
+ onRetryEnd: r[2] ||= (e) => f("retryEnd")
1425
1567
  }, null, 8, [
1426
1568
  "can-retry-end",
1427
1569
  "card-footer",
1428
1570
  "card-header",
1571
+ "feed-footer",
1572
+ "feed-footer-actions",
1429
1573
  "has-next",
1430
1574
  "infinite-scroll",
1431
1575
  "initial-post-id",
@@ -1437,38 +1581,30 @@ var Ce = /* @__PURE__ */ l({
1437
1581
  "next-page-error",
1438
1582
  "preview-states",
1439
1583
  "reel-auto-advance",
1584
+ "state",
1440
1585
  "total"
1441
- ])], 8, ct), c(t, { name: "vibe-info-sheet" }, {
1442
- default: D(() => [O.value && e.infoSheet && k.value ? (v(), o("div", lt, [s("aside", {
1586
+ ])], 8, mt), l(t, { name: "vibe-info-sheet" }, {
1587
+ default: O(() => [E.value && e.infoSheet && k.value ? (y(), o("div", ht, [s("aside", {
1443
1588
  ref_key: "sheetElement",
1444
- ref: y,
1589
+ ref: v,
1445
1590
  class: "reel-info-sheet",
1446
1591
  role: e.infoSheetOverlay ? "dialog" : "complementary",
1447
1592
  "aria-label": "Reel information",
1448
1593
  "aria-modal": e.infoSheetOverlay ? "true" : void 0,
1449
1594
  tabindex: e.infoSheetOverlay ? -1 : void 0,
1450
1595
  "data-active-post-id": w.value?.postId
1451
- }, [(v(), i(x(e.infoSheet.component), m(u(k.value)), null, 16))], 8, ut)])) : a("", !0)]),
1596
+ }, [(y(), i(S(e.infoSheet.component), h(d(k.value)), null, 16))], 8, gt)])) : a("", !0)]),
1452
1597
  _: 1
1453
- })], 10, st));
1598
+ })], 10, pt));
1454
1599
  }
1455
- }), ft = {
1456
- key: 0,
1457
- class: "gallery-shell",
1458
- role: "alert"
1459
- }, pt = {
1460
- key: 1,
1461
- class: "gallery-shell",
1462
- role: "status"
1463
- }, mt = {
1464
- key: 2,
1465
- class: "gallery-shell"
1466
- }, ht = 35, gt = /* @__PURE__ */ l({
1600
+ }), vt = 35, yt = /* @__PURE__ */ u({
1467
1601
  __name: "VibeSurface",
1468
1602
  props: {
1469
1603
  canRetryEnd: { type: Boolean },
1470
1604
  cardFooter: {},
1471
1605
  cardHeader: {},
1606
+ feedFooter: {},
1607
+ feedFooterActions: {},
1472
1608
  reelInfoSheet: {},
1473
1609
  state: {}
1474
1610
  },
@@ -1480,85 +1616,85 @@ var Ce = /* @__PURE__ */ l({
1480
1616
  "reelInfoSheetChange",
1481
1617
  "retryEnd"
1482
1618
  ],
1483
- setup(r, { expose: l, emit: u }) {
1484
- let d = r, p = u, m = S(null), y = S(null), b = S(null), x = S(null), C = S({}), w = S(!1), T = S(/* @__PURE__ */ new Set()), O = S(/* @__PURE__ */ new Map()), k = S(/* @__PURE__ */ new Map()), A = S(/* @__PURE__ */ new Map()), M = S(/* @__PURE__ */ new Map()), P = n(() => d.state.reelMediaSource === "original" ? M.value : A.value), F = new Set(d.state.items.map((e) => e.postId)), I = null, L = null, R = !1;
1485
- function z() {
1619
+ setup(r, { expose: s, emit: c }) {
1620
+ let u = r, d = c, f = C(null), m = C(null), h = C(null), b = C(null), x = C({}), S = C(!1), w = C(/* @__PURE__ */ new Set()), T = C(/* @__PURE__ */ new Map()), E = C(/* @__PURE__ */ new Map()), k = C(/* @__PURE__ */ new Map()), A = C(/* @__PURE__ */ new Map()), j = n(() => F(u.state)), N = n(() => u.state.reelMediaSource === "original" ? A.value : k.value), I = new Set(u.state.items.map((e) => e.postId)), L = null, R = null, z = !1;
1621
+ function B() {
1486
1622
  return typeof window.matchMedia == "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
1487
1623
  }
1488
- function B() {
1489
- I !== null && cancelAnimationFrame(I), I = requestAnimationFrame(() => {
1490
- I = requestAnimationFrame(() => {
1491
- I = null, T.value = /* @__PURE__ */ new Set();
1624
+ function V() {
1625
+ L !== null && cancelAnimationFrame(L), L = requestAnimationFrame(() => {
1626
+ L = requestAnimationFrame(() => {
1627
+ L = null, w.value = /* @__PURE__ */ new Set();
1492
1628
  });
1493
1629
  });
1494
1630
  }
1495
- function V(e, t, n) {
1496
- let r = N(e, t);
1497
- A.value.get(r) !== n && (A.value = new Map(A.value).set(r, n));
1498
- }
1499
1631
  function H(e, t, n) {
1500
- let r = N(e, t);
1501
- M.value.get(r) !== n && (M.value = new Map(M.value).set(r, n));
1632
+ let r = P(e, t);
1633
+ k.value.get(r) !== n && (k.value = new Map(k.value).set(r, n));
1502
1634
  }
1503
- function U(e, t) {
1504
- V(e, t, "error");
1635
+ function U(e, t, n) {
1636
+ let r = P(e, t);
1637
+ A.value.get(r) !== n && (A.value = new Map(A.value).set(r, n));
1505
1638
  }
1506
1639
  function W(e, t) {
1507
- V(e, t, "ready");
1508
- }
1509
- function G(e, t) {
1510
1640
  H(e, t, "error");
1511
1641
  }
1512
- function K(e, t) {
1642
+ function ee(e, t) {
1513
1643
  H(e, t, "ready");
1514
1644
  }
1515
- function ee(e, t) {
1516
- if (d.state.reelMediaSource === "original") {
1517
- G(e, t);
1518
- return;
1519
- }
1520
- U(e, t);
1645
+ function K(e, t) {
1646
+ U(e, t, "error");
1521
1647
  }
1522
- function q(e, t) {
1523
- if (d.state.reelMediaSource === "original") {
1648
+ function te(e, t) {
1649
+ U(e, t, "ready");
1650
+ }
1651
+ function ne(e, t) {
1652
+ if (u.state.reelMediaSource === "original") {
1524
1653
  K(e, t);
1525
1654
  return;
1526
1655
  }
1527
1656
  W(e, t);
1528
1657
  }
1529
- function J(e, t) {
1530
- let n = d.state.items.find((t) => t.postId === e);
1658
+ function re(e, t) {
1659
+ if (u.state.reelMediaSource === "original") {
1660
+ te(e, t);
1661
+ return;
1662
+ }
1663
+ ee(e, t);
1664
+ }
1665
+ function q(e, t) {
1666
+ let n = u.state.items.find((t) => t.postId === e);
1531
1667
  if (!n) return;
1532
- let r = j(n, t);
1533
- (k.value.get(e) ?? 0) !== r && (k.value = new Map(k.value).set(e, r));
1668
+ let r = M(n, t);
1669
+ (E.value.get(e) ?? 0) !== r && (E.value = new Map(E.value).set(e, r));
1534
1670
  }
1535
- async function Y() {
1536
- await f(), (d.state.layout === "reel" || d.state.reelOrigin === "masonry" ? y.value : m.value)?.loadIfNearBottom();
1671
+ async function J() {
1672
+ await p(), (u.state.layout === "reel" || u.state.reelOrigin === "masonry" ? m.value : f.value)?.loadIfNearBottom();
1537
1673
  }
1538
- function te(e) {
1539
- return d.state.isLoading || d.state.items.length === 0 || d.state.layout !== "reel" && d.state.reelOrigin !== "masonry" ? !1 : y.value?.changeActiveMedia?.(e) ?? !1;
1674
+ function Y(e) {
1675
+ return u.state.isLoading || u.state.items.length === 0 || u.state.layout !== "reel" && u.state.reelOrigin !== "masonry" ? !1 : m.value?.changeActiveMedia?.(e) ?? !1;
1540
1676
  }
1541
- function ne(e) {
1542
- return d.state.isLoading || d.state.items.length === 0 || d.state.layout !== "reel" && d.state.reelOrigin !== "masonry" ? !1 : y.value?.moveActivePost?.(e) ?? !1;
1677
+ function ie(e) {
1678
+ return u.state.isLoading || u.state.items.length === 0 || u.state.layout !== "reel" && u.state.reelOrigin !== "masonry" ? !1 : m.value?.moveActivePost?.(e) ?? !1;
1543
1679
  }
1544
- function re() {
1545
- return d.state.layout !== "masonry" || d.state.reelOrigin === "masonry" ? null : m.value?.getScrollElement?.() ?? null;
1680
+ function ae() {
1681
+ return u.state.layout !== "masonry" || u.state.reelOrigin === "masonry" ? null : f.value?.getScrollElement?.() ?? null;
1546
1682
  }
1547
- function ie(e, t) {
1548
- L = e, R = t === "keyboard", C.value = Z(e), p("openReel", e), f(() => b.value?.focus());
1683
+ function X(e, t) {
1684
+ R = e, z = t === "keyboard", x.value = se(e), d("openReel", e), p(() => h.value?.focus());
1549
1685
  }
1550
- function ae(e) {
1551
- let t = x.value?.querySelectorAll(".masonry-feed [data-post-id]") ?? [];
1686
+ function Z(e) {
1687
+ let t = b.value?.querySelectorAll(".masonry-feed [data-post-id]") ?? [];
1552
1688
  return Array.from(t).find((t) => t.dataset.postId === String(e)) ?? null;
1553
1689
  }
1554
- function X(e, t) {
1555
- let n = ae(e), r = n?.querySelector(".media-card-activator") ?? n;
1690
+ function oe(e, t) {
1691
+ let n = Z(e), r = n?.querySelector(".media-card-activator") ?? n;
1556
1692
  r && (r.classList.toggle("media-card-focus-silent", !t), t || r.addEventListener("blur", () => {
1557
1693
  r.classList.remove("media-card-focus-silent");
1558
1694
  }, { once: !0 }), r?.focus({ preventScroll: !0 }));
1559
1695
  }
1560
- function Z(e) {
1561
- let t = x.value, n = ae(e);
1696
+ function se(e) {
1697
+ let t = b.value, n = Z(e);
1562
1698
  if (t === null || n === null) return {};
1563
1699
  let r = t.getBoundingClientRect(), i = n.getBoundingClientRect();
1564
1700
  return {
@@ -1568,26 +1704,26 @@ var Ce = /* @__PURE__ */ l({
1568
1704
  "--vibe-reel-origin-left": `${Math.max(0, i.left - r.left)}px`
1569
1705
  };
1570
1706
  }
1571
- function oe() {
1572
- d.state.reelOrigin === "masonry" && (L ??= d.state.activeReelPostId, w.value = !0, p("closeReel"));
1707
+ function ce() {
1708
+ u.state.reelOrigin === "masonry" && (R ??= u.state.activeReelPostId, S.value = !0, d("closeReel"));
1573
1709
  }
1574
- function se() {
1575
- let e = L, t = R;
1576
- w.value = !1, L = null, R = !1, C.value = {}, f(() => {
1577
- e !== null && X(e, t);
1710
+ function le() {
1711
+ let e = R, t = z;
1712
+ S.value = !1, R = null, z = !1, x.value = {}, p(() => {
1713
+ e !== null && oe(e, t);
1578
1714
  });
1579
1715
  }
1580
- function ce(e) {
1581
- let t = d.state.layout === "reel" || d.state.reelOrigin === "masonry";
1582
- if (e.key === "Escape" && d.state.reelOrigin === "masonry") {
1583
- e.preventDefault(), oe();
1716
+ function ue(e) {
1717
+ let t = u.state.layout === "reel" || u.state.reelOrigin === "masonry";
1718
+ if (e.key === "Escape" && u.state.reelOrigin === "masonry") {
1719
+ e.preventDefault(), ce();
1584
1720
  return;
1585
1721
  }
1586
- if (e.key === "Escape" && t && d.state.reelInfoSheet.enabled) {
1587
- e.preventDefault(), p("reelInfoSheetChange", !1);
1722
+ if (e.key === "Escape" && t && u.state.reelInfoSheet.enabled) {
1723
+ e.preventDefault(), d("reelInfoSheetChange", !1);
1588
1724
  return;
1589
1725
  }
1590
- if (e.defaultPrevented || e.altKey || e.ctrlKey || e.metaKey || e.shiftKey || w.value || d.state.layout !== "reel" && d.state.reelOrigin !== "masonry") return;
1726
+ if (e.defaultPrevented || e.altKey || e.ctrlKey || e.metaKey || e.shiftKey || S.value || u.state.layout !== "reel" && u.state.reelOrigin !== "masonry") return;
1591
1727
  let n = e.target;
1592
1728
  if (n instanceof HTMLElement && (n.isContentEditable || [
1593
1729
  "INPUT",
@@ -1595,64 +1731,82 @@ var Ce = /* @__PURE__ */ l({
1595
1731
  "TEXTAREA"
1596
1732
  ].includes(n.tagName))) return;
1597
1733
  let r = e.key === "ArrowLeft" ? -1 : e.key === "ArrowRight" ? 1 : 0;
1598
- r !== 0 && y.value?.changeActiveMedia?.(r) && e.preventDefault();
1734
+ r !== 0 && m.value?.changeActiveMedia?.(r) && e.preventDefault();
1599
1735
  }
1600
- return E(() => d.state.items.map((e) => e.postId), (e) => {
1601
- let t = e.filter((e) => !F.has(e));
1602
- if (F = new Set(e), t.length === 0 || z()) return;
1736
+ return D(() => u.state.items.map((e) => e.postId), (e) => {
1737
+ let t = e.filter((e) => !I.has(e));
1738
+ if (I = new Set(e), t.length === 0 || B()) return;
1603
1739
  let n = /* @__PURE__ */ new Map();
1604
1740
  e.forEach((e) => {
1605
- let t = O.value.get(e);
1741
+ let t = T.value.get(e);
1606
1742
  t !== void 0 && n.set(e, t);
1607
1743
  }), t.forEach((e, t) => {
1608
- n.set(e, t * ht);
1609
- }), O.value = n, T.value = new Set([...T.value, ...t]), B();
1610
- }, { flush: "sync" }), _(() => window.addEventListener("keydown", ce)), g(() => {
1611
- window.removeEventListener("keydown", ce), I !== null && cancelAnimationFrame(I);
1612
- }), l({
1613
- changeActiveReelMedia: te,
1614
- getAutoScrollElement: re,
1615
- loadIfNearBottom: Y,
1616
- moveActiveReelPost: ne
1617
- }), (n, l) => (v(), o("div", {
1744
+ n.set(e, t * vt);
1745
+ }), T.value = n, w.value = new Set([...w.value, ...t]), V();
1746
+ }, { flush: "sync" }), v(() => window.addEventListener("keydown", ue)), _(() => {
1747
+ window.removeEventListener("keydown", ue), L !== null && cancelAnimationFrame(L);
1748
+ }), s({
1749
+ changeActiveReelMedia: Y,
1750
+ getAutoScrollElement: ae,
1751
+ loadIfNearBottom: J,
1752
+ moveActiveReelPost: ie
1753
+ }), (n, s) => (y(), o("div", {
1618
1754
  ref_key: "surfaceElement",
1619
- ref: x,
1755
+ ref: b,
1620
1756
  class: "vibe-surface"
1621
- }, [r.state.error ? (v(), o("main", ft, [...l[10] ||= [s("p", { class: "gallery-status" }, " Unable to load media. ", -1)]])) : r.state.isLoading ? (v(), o("main", pt, [...l[11] ||= [s("p", { class: "gallery-status" }, " Loading media… ", -1)]])) : r.state.items.length === 0 ? (v(), o("main", mt, [...l[12] ||= [s("p", { class: "gallery-status" }, " No media found. ", -1)]])) : r.state.layout === "reel" ? (v(), i(dt, {
1622
- key: 3,
1757
+ }, [r.state.error || r.state.isLoading || r.state.items.length === 0 ? (y(), i(G, {
1758
+ key: 0,
1759
+ actions: r.feedFooterActions,
1760
+ "can-retry-end": r.canRetryEnd,
1761
+ "feed-footer": r.feedFooter,
1762
+ state: j.value,
1763
+ onLoadMore: s[0] ||= (e) => d("loadMore"),
1764
+ onRetryEnd: s[1] ||= (e) => d("retryEnd")
1765
+ }, null, 8, [
1766
+ "actions",
1767
+ "can-retry-end",
1768
+ "feed-footer",
1769
+ "state"
1770
+ ])) : r.state.layout === "reel" ? (y(), i(_t, {
1771
+ key: 1,
1623
1772
  ref_key: "reelRenderer",
1624
- ref: y,
1773
+ ref: m,
1625
1774
  "can-retry-end": r.canRetryEnd,
1626
1775
  "has-next": r.state.next !== null,
1627
1776
  "card-footer": r.cardFooter,
1628
1777
  "card-header": r.cardHeader,
1778
+ "feed-footer": r.feedFooter,
1779
+ "feed-footer-actions": r.feedFooterActions,
1629
1780
  "infinite-scroll": r.state.infiniteScroll,
1630
1781
  "is-loading-more": r.state.isLoadingMore,
1631
1782
  items: r.state.items,
1632
1783
  "load-more-locked": r.state.loadMoreLocked,
1633
1784
  "media-source": r.state.reelMediaSource,
1634
- "media-indices": k.value,
1785
+ "media-indices": E.value,
1635
1786
  "initial-post-id": r.state.activeReelPostId,
1636
1787
  "info-sheet": r.reelInfoSheet,
1637
1788
  "info-sheet-enabled": r.state.reelInfoSheet.enabled,
1638
1789
  "info-sheet-overlay": r.state.reelInfoSheetOverlay,
1639
1790
  "next-page-error": !!r.state.nextPageError,
1640
1791
  origin: "reel",
1641
- "preview-states": P.value,
1792
+ "preview-states": N.value,
1642
1793
  "reel-auto-advance": r.state.reelAutoAdvance,
1794
+ state: j.value,
1643
1795
  total: r.state.total,
1644
- onActiveChange: l[0] ||= (e) => p("activeReelChange", e),
1645
- onCloseInfoSheet: l[1] ||= (e) => p("reelInfoSheetChange", !1),
1646
- onError: ee,
1647
- onLoadMore: l[2] ||= (e) => p("loadMore"),
1648
- onMediaChange: J,
1649
- onReady: q,
1650
- onRetryEnd: l[3] ||= (e) => p("retryEnd")
1796
+ onActiveChange: s[2] ||= (e) => d("activeReelChange", e),
1797
+ onCloseInfoSheet: s[3] ||= (e) => d("reelInfoSheetChange", !1),
1798
+ onError: ne,
1799
+ onLoadMore: s[4] ||= (e) => d("loadMore"),
1800
+ onMediaChange: q,
1801
+ onReady: re,
1802
+ onRetryEnd: s[5] ||= (e) => d("retryEnd")
1651
1803
  }, null, 8, [
1652
1804
  "can-retry-end",
1653
1805
  "has-next",
1654
1806
  "card-footer",
1655
1807
  "card-header",
1808
+ "feed-footer",
1809
+ "feed-footer-actions",
1656
1810
  "infinite-scroll",
1657
1811
  "is-loading-more",
1658
1812
  "items",
@@ -1666,37 +1820,43 @@ var Ce = /* @__PURE__ */ l({
1666
1820
  "next-page-error",
1667
1821
  "preview-states",
1668
1822
  "reel-auto-advance",
1823
+ "state",
1669
1824
  "total"
1670
- ])) : (v(), o(e, { key: 4 }, [c(tt, {
1825
+ ])) : (y(), o(e, { key: 2 }, [l(st, {
1671
1826
  ref_key: "masonryRenderer",
1672
- ref: m,
1827
+ ref: f,
1673
1828
  "can-retry-end": r.canRetryEnd,
1674
- "entering-post-ids": T.value,
1675
- "entry-delays": O.value,
1829
+ "entering-post-ids": w.value,
1830
+ "entry-delays": T.value,
1676
1831
  "card-footer": r.cardFooter,
1677
1832
  "card-header": r.cardHeader,
1833
+ "feed-footer": r.feedFooter,
1834
+ "feed-footer-actions": r.feedFooterActions,
1678
1835
  "has-next": r.state.next !== null,
1679
1836
  "infinite-scroll": r.state.infiniteScroll,
1680
1837
  "is-loading-more": r.state.isLoadingMore,
1681
1838
  items: r.state.items,
1682
1839
  "load-more-locked": r.state.loadMoreLocked,
1683
- "media-indices": k.value,
1840
+ "media-indices": E.value,
1684
1841
  "next-page-error": !!r.state.nextPageError,
1685
- "preview-states": A.value,
1686
- suspended: r.state.reelOrigin === "masonry" || w.value,
1842
+ "preview-states": k.value,
1843
+ suspended: r.state.reelOrigin === "masonry" || S.value,
1844
+ state: j.value,
1687
1845
  total: r.state.total,
1688
- onActivate: ie,
1689
- onError: U,
1690
- onLoadMore: l[4] ||= (e) => p("loadMore"),
1691
- onMediaChange: J,
1692
- onReady: W,
1693
- onRetryEnd: l[5] ||= (e) => p("retryEnd")
1846
+ onActivate: X,
1847
+ onError: W,
1848
+ onLoadMore: s[6] ||= (e) => d("loadMore"),
1849
+ onMediaChange: q,
1850
+ onReady: ee,
1851
+ onRetryEnd: s[7] ||= (e) => d("retryEnd")
1694
1852
  }, null, 8, [
1695
1853
  "can-retry-end",
1696
1854
  "entering-post-ids",
1697
1855
  "entry-delays",
1698
1856
  "card-footer",
1699
1857
  "card-header",
1858
+ "feed-footer",
1859
+ "feed-footer-actions",
1700
1860
  "has-next",
1701
1861
  "infinite-scroll",
1702
1862
  "is-loading-more",
@@ -1706,27 +1866,30 @@ var Ce = /* @__PURE__ */ l({
1706
1866
  "next-page-error",
1707
1867
  "preview-states",
1708
1868
  "suspended",
1869
+ "state",
1709
1870
  "total"
1710
- ]), c(t, {
1871
+ ]), l(t, {
1711
1872
  name: "vibe-reel-viewer",
1712
- onAfterLeave: se
1873
+ onAfterLeave: le
1713
1874
  }, {
1714
- default: D(() => [r.state.reelOrigin === "masonry" ? (v(), o("section", {
1875
+ default: O(() => [r.state.reelOrigin === "masonry" ? (y(), o("section", {
1715
1876
  key: 0,
1716
1877
  ref_key: "reelOverlay",
1717
- ref: b,
1878
+ ref: h,
1718
1879
  class: "vibe-reel-overlay",
1719
1880
  role: "dialog",
1720
1881
  "aria-label": "Media viewer",
1721
1882
  "aria-modal": "true",
1722
1883
  tabindex: "-1",
1723
- style: h(C.value)
1724
- }, [c(dt, {
1884
+ style: g(x.value)
1885
+ }, [l(_t, {
1725
1886
  ref_key: "reelRenderer",
1726
- ref: y,
1887
+ ref: m,
1727
1888
  "can-retry-end": r.canRetryEnd,
1728
1889
  "card-footer": r.cardFooter,
1729
1890
  "card-header": r.cardHeader,
1891
+ "feed-footer": r.feedFooter,
1892
+ "feed-footer-actions": r.feedFooterActions,
1730
1893
  "has-next": r.state.next !== null,
1731
1894
  "infinite-scroll": r.state.infiniteScroll,
1732
1895
  "initial-post-id": r.state.activeReelPostId,
@@ -1736,24 +1899,27 @@ var Ce = /* @__PURE__ */ l({
1736
1899
  "is-loading-more": r.state.isLoadingMore,
1737
1900
  items: r.state.items,
1738
1901
  "load-more-locked": r.state.loadMoreLocked,
1739
- "media-indices": k.value,
1902
+ "media-indices": E.value,
1740
1903
  "media-source": "original",
1741
1904
  "next-page-error": !!r.state.nextPageError,
1742
1905
  origin: "masonry",
1743
- "preview-states": M.value,
1906
+ "preview-states": A.value,
1744
1907
  "reel-auto-advance": r.state.reelAutoAdvance,
1908
+ state: j.value,
1745
1909
  total: r.state.total,
1746
- onActiveChange: l[6] ||= (e) => p("activeReelChange", e),
1747
- onCloseInfoSheet: l[7] ||= (e) => p("reelInfoSheetChange", !1),
1748
- onError: G,
1749
- onLoadMore: l[8] ||= (e) => p("loadMore"),
1750
- onMediaChange: J,
1751
- onReady: K,
1752
- onRetryEnd: l[9] ||= (e) => p("retryEnd")
1910
+ onActiveChange: s[8] ||= (e) => d("activeReelChange", e),
1911
+ onCloseInfoSheet: s[9] ||= (e) => d("reelInfoSheetChange", !1),
1912
+ onError: K,
1913
+ onLoadMore: s[10] ||= (e) => d("loadMore"),
1914
+ onMediaChange: q,
1915
+ onReady: te,
1916
+ onRetryEnd: s[11] ||= (e) => d("retryEnd")
1753
1917
  }, null, 8, [
1754
1918
  "can-retry-end",
1755
1919
  "card-footer",
1756
1920
  "card-header",
1921
+ "feed-footer",
1922
+ "feed-footer-actions",
1757
1923
  "has-next",
1758
1924
  "infinite-scroll",
1759
1925
  "initial-post-id",
@@ -1767,6 +1933,7 @@ var Ce = /* @__PURE__ */ l({
1767
1933
  "next-page-error",
1768
1934
  "preview-states",
1769
1935
  "reel-auto-advance",
1936
+ "state",
1770
1937
  "total"
1771
1938
  ])], 4)) : a("", !0)]),
1772
1939
  _: 1
@@ -1775,7 +1942,7 @@ var Ce = /* @__PURE__ */ l({
1775
1942
  });
1776
1943
  //#endregion
1777
1944
  //#region src/core/page.ts
1778
- function _t(e) {
1945
+ function bt(e) {
1779
1946
  if (!e || typeof e != "object" || !Array.isArray(e.items)) throw TypeError("Vibe loadPage must resolve to a page with an items array.");
1780
1947
  if (e.next !== null && typeof e.next != "string" && typeof e.next != "number") throw TypeError("Vibe page next must be a string, number, or null.");
1781
1948
  if (e.total !== void 0 && (!Number.isFinite(e.total) || e.total < 0)) throw TypeError("Vibe page total must be a non-negative number when provided.");
@@ -1787,32 +1954,32 @@ function Q(e, t) {
1787
1954
  }
1788
1955
  //#endregion
1789
1956
  //#region src/core/requestDelay.ts
1790
- var vt = 2e3, yt = 1e4, bt = 250, xt = {
1957
+ var xt = 2e3, St = 1e4, Ct = 250, wt = {
1791
1958
  delayRemainingMs: null,
1792
1959
  nextRequestAt: null
1793
1960
  };
1794
- function St(e, t) {
1961
+ function Tt(e, t) {
1795
1962
  return e === void 0 ? t : Math.floor(e);
1796
1963
  }
1797
- function Ct(e, t) {
1964
+ function Et(e, t) {
1798
1965
  for (let [n, r] of [["delayStepMs", e.delayStepMs], ["delayMaxMs", e.delayMaxMs]]) if (r !== void 0 && (!Number.isFinite(r) || r < 0)) throw TypeError(`Vibe ${t} ${n} must be a non-negative number.`);
1799
1966
  }
1800
- function wt(e, t = {}) {
1801
- let n = St(t.delayStepMs, vt), r = St(t.delayMaxMs, yt);
1967
+ function Dt(e, t = {}) {
1968
+ let n = Tt(t.delayStepMs, xt), r = Tt(t.delayMaxMs, St);
1802
1969
  return Math.min(Math.max(0, e) * n, r);
1803
1970
  }
1804
1971
  function $(e) {
1805
- if (e == null || !Number.isFinite(e)) return { ...xt };
1972
+ if (e == null || !Number.isFinite(e)) return { ...wt };
1806
1973
  let t = Math.max(0, Math.floor(e - Date.now()));
1807
1974
  return t > 0 ? {
1808
1975
  delayRemainingMs: t,
1809
1976
  nextRequestAt: e
1810
- } : { ...xt };
1977
+ } : { ...wt };
1811
1978
  }
1812
- async function Tt({ delayMs: e, onChange: t, signal: n }) {
1979
+ async function Ot({ delayMs: e, onChange: t, signal: n }) {
1813
1980
  if (n.aborted) throw new DOMException("Aborted", "AbortError");
1814
1981
  if (e <= 0) {
1815
- t({ ...xt });
1982
+ t({ ...wt });
1816
1983
  return;
1817
1984
  }
1818
1985
  let r = Date.now() + e;
@@ -1820,9 +1987,9 @@ async function Tt({ delayMs: e, onChange: t, signal: n }) {
1820
1987
  delayRemainingMs: e,
1821
1988
  nextRequestAt: r
1822
1989
  }), await new Promise((i, a) => {
1823
- let o = !1, s = setInterval(f, bt), c = setTimeout(() => u(), e);
1990
+ let o = !1, s = setInterval(f, Ct), c = setTimeout(() => u(), e);
1824
1991
  function l() {
1825
- clearInterval(s), clearTimeout(c), n.removeEventListener("abort", d), t({ ...xt });
1992
+ clearInterval(s), clearTimeout(c), n.removeEventListener("abort", d), t({ ...wt });
1826
1993
  }
1827
1994
  function u(e) {
1828
1995
  o || (o = !0, l(), e ? a(e) : i());
@@ -1837,13 +2004,13 @@ async function Tt({ delayMs: e, onChange: t, signal: n }) {
1837
2004
  n.addEventListener("abort", d, { once: !0 });
1838
2005
  });
1839
2006
  }
1840
- var Et = class {
2007
+ var kt = class {
1841
2008
  interval = null;
1842
2009
  constructor(e) {
1843
2010
  this.onChange = e;
1844
2011
  }
1845
2012
  clear() {
1846
- this.interval !== null && clearInterval(this.interval), this.interval = null, this.onChange({ ...xt });
2013
+ this.interval !== null && clearInterval(this.interval), this.interval = null, this.onChange({ ...wt });
1847
2014
  }
1848
2015
  sync(e) {
1849
2016
  this.clear();
@@ -1851,21 +2018,24 @@ var Et = class {
1851
2018
  this.onChange(t), t.delayRemainingMs !== null && (this.interval = setInterval(() => {
1852
2019
  let t = $(e);
1853
2020
  this.onChange(t), t.delayRemainingMs === null && this.clear();
1854
- }, bt));
2021
+ }, Ct));
1855
2022
  }
1856
2023
  };
1857
- function Dt(e) {
2024
+ function At(e, t = !0) {
2025
+ return e.maxAdditionalPages === "unlimited" ? Infinity : (e.maxAdditionalPages ?? 10) + (t ? 1 : 0);
2026
+ }
2027
+ function jt(e) {
1858
2028
  return `${typeof e}:${String(e)}`;
1859
2029
  }
1860
- function Ot(e, t) {
2030
+ function Mt(e, t) {
1861
2031
  if (!Number.isInteger(e) || e <= 0) throw TypeError(`Vibe ${t} must be a positive integer.`);
1862
2032
  }
1863
- function kt(e) {
2033
+ function Nt(e) {
1864
2034
  if (!e) return;
1865
- if (Ot(e.pageSize, "autofill pageSize"), e.strategy === "frontend") {
1866
- Ct(e, "frontend autofill");
2035
+ if (Mt(e.pageSize, "autofill pageSize"), e.strategy === "frontend") {
2036
+ Et(e, "frontend autofill");
1867
2037
  let t = e.maxAdditionalPages;
1868
- if (t !== void 0 && (!Number.isInteger(t) || t < 0)) throw TypeError("Vibe autofill maxAdditionalPages must be a non-negative integer.");
2038
+ if (t !== void 0 && t !== "unlimited" && (!Number.isInteger(t) || t < 0)) throw TypeError("Vibe autofill maxAdditionalPages must be a non-negative integer or \"unlimited\".");
1869
2039
  return;
1870
2040
  }
1871
2041
  if (!e.feedKey.trim()) throw TypeError("Vibe backend autofill requires a feedKey.");
@@ -1875,7 +2045,7 @@ function kt(e) {
1875
2045
  if (t.pageSize !== e.pageSize) throw TypeError("Vibe backend autofill initialSession pageSize must match autofill pageSize.");
1876
2046
  }
1877
2047
  }
1878
- function At(e, t, n = !0) {
2048
+ function Pt(e, t, n = !0) {
1879
2049
  if (!e) return {
1880
2050
  cycleId: null,
1881
2051
  delayRemainingMs: null,
@@ -1909,7 +2079,7 @@ function At(e, t, n = !0) {
1909
2079
  strategy: e.strategy
1910
2080
  };
1911
2081
  }
1912
- function jt(e) {
2082
+ function Ft(e) {
1913
2083
  return [
1914
2084
  "cancelling",
1915
2085
  "filling",
@@ -1917,9 +2087,9 @@ function jt(e) {
1917
2087
  "waiting"
1918
2088
  ].includes(e.status);
1919
2089
  }
1920
- async function Mt(e, t, n) {
2090
+ async function It(e, t, n) {
1921
2091
  let r = t.autofill;
1922
- if (!jt(r) || !r.cycleId) return;
2092
+ if (!Ft(r) || !r.cycleId) return;
1923
2093
  let i = {
1924
2094
  cycleId: r.cycleId,
1925
2095
  feedKey: r.feedKey ?? "",
@@ -1932,20 +2102,20 @@ async function Mt(e, t, n) {
1932
2102
  throw r.error = e, r.status = "error", e;
1933
2103
  }
1934
2104
  }
1935
- function Nt(e, t, n) {
2105
+ function Lt(e, t, n) {
1936
2106
  return e?.strategy === "backend" && t.feedKey === e.feedKey && t.sessionId === n.sessionId;
1937
2107
  }
1938
- async function Pt({ existingItems: e, initialCursor: t, loadPage: n, maximumRequests: r, onDelayChange: i, onProgress: a, options: o, receivedOffset: s = 0, requestOffset: c = 0, signal: l }) {
1939
- let u = [], d = [...e], f = /* @__PURE__ */ new Set(), p = r ?? 1 + (o.maxAdditionalPages ?? 10), m = t, h = t, g = 0, _;
2108
+ async function Rt({ existingItems: e, initialCursor: t, loadPage: n, maximumRequests: r, onDelayChange: i, onProgress: a, options: o, receivedOffset: s = 0, requestOffset: c = 0, signal: l }) {
2109
+ let u = [], d = [...e], f = /* @__PURE__ */ new Set(), p = r ?? At(o), m = t, h = t, g = 0, _;
1940
2110
  for (; g < p;) {
1941
- let e = Dt(m);
2111
+ let e = jt(m);
1942
2112
  if (f.has(e)) throw Error("Vibe autofill received a repeated cursor.");
1943
- f.add(e), await Tt({
1944
- delayMs: wt(c + g, o),
2113
+ f.add(e), await Ot({
2114
+ delayMs: Dt(c + g, o),
1945
2115
  onChange: i,
1946
2116
  signal: l
1947
2117
  });
1948
- let t = _t(await n({
2118
+ let t = bt(await n({
1949
2119
  cursor: m,
1950
2120
  signal: l
1951
2121
  }));
@@ -1985,30 +2155,30 @@ async function Pt({ existingItems: e, initialCursor: t, loadPage: n, maximumRequ
1985
2155
  total: _
1986
2156
  };
1987
2157
  }
1988
- var Ft = 100;
1989
- function It(e, t) {
2158
+ var zt = 100;
2159
+ function Bt(e, t) {
1990
2160
  if (!Number.isFinite(t) || t <= 0) throw TypeError(`Vibe ${e} must be a positive number.`);
1991
2161
  }
1992
- function Lt(e, t, n) {
2162
+ function Vt(e, t, n) {
1993
2163
  return Math.min(n, Math.max(t, e));
1994
2164
  }
1995
- function Rt(e) {
2165
+ function Ht(e) {
1996
2166
  if (!e) return;
1997
2167
  let t = e.minSpeedPxPerSecond ?? 20, n = e.maxSpeedPxPerSecond ?? 240;
1998
- if (It("autoScroll.minSpeedPxPerSecond", t), It("autoScroll.maxSpeedPxPerSecond", n), t > n) throw TypeError("Vibe autoScroll.minSpeedPxPerSecond cannot exceed maxSpeedPxPerSecond.");
1999
- e.speedPxPerSecond !== void 0 && It("autoScroll.speedPxPerSecond", e.speedPxPerSecond);
2168
+ if (Bt("autoScroll.minSpeedPxPerSecond", t), Bt("autoScroll.maxSpeedPxPerSecond", n), t > n) throw TypeError("Vibe autoScroll.minSpeedPxPerSecond cannot exceed maxSpeedPxPerSecond.");
2169
+ e.speedPxPerSecond !== void 0 && Bt("autoScroll.speedPxPerSecond", e.speedPxPerSecond);
2000
2170
  }
2001
- function zt(e) {
2171
+ function Ut(e) {
2002
2172
  let t = e?.minSpeedPxPerSecond ?? 20, n = e?.maxSpeedPxPerSecond ?? 240;
2003
2173
  return {
2004
2174
  enabled: e?.enabled ?? !1,
2005
2175
  maxSpeedPxPerSecond: n,
2006
2176
  minSpeedPxPerSecond: t,
2007
2177
  paused: !1,
2008
- speedPxPerSecond: Lt(e?.speedPxPerSecond ?? 80, t, n)
2178
+ speedPxPerSecond: Vt(e?.speedPxPerSecond ?? 80, t, n)
2009
2179
  };
2010
2180
  }
2011
- var Bt = class {
2181
+ var Wt = class {
2012
2182
  frame = null;
2013
2183
  lastTimestamp = null;
2014
2184
  mounted = !1;
@@ -2028,9 +2198,9 @@ var Bt = class {
2028
2198
  this.options.state.enabled && (this.options.state.paused = e, this.lastTimestamp = null, e ? this.cancelFrame() : this.schedule());
2029
2199
  }
2030
2200
  setSpeed(e) {
2031
- It("auto-scroll speed", e);
2201
+ Bt("auto-scroll speed", e);
2032
2202
  let t = this.options.state;
2033
- t.speedPxPerSecond = Lt(e, t.minSpeedPxPerSecond, t.maxSpeedPxPerSecond);
2203
+ t.speedPxPerSecond = Vt(e, t.minSpeedPxPerSecond, t.maxSpeedPxPerSecond);
2034
2204
  }
2035
2205
  tick = (e) => {
2036
2206
  this.frame = null;
@@ -2042,7 +2212,7 @@ var Bt = class {
2042
2212
  return;
2043
2213
  }
2044
2214
  if (this.lastTimestamp !== null) {
2045
- let r = Math.min(Ft, Math.max(0, e - this.lastTimestamp)), i = Math.max(0, n.scrollHeight - n.clientHeight);
2215
+ let r = Math.min(zt, Math.max(0, e - this.lastTimestamp)), i = Math.max(0, n.scrollHeight - n.clientHeight);
2046
2216
  n.scrollTop = Math.min(i, n.scrollTop + t.speedPxPerSecond * r / 1e3);
2047
2217
  }
2048
2218
  this.lastTimestamp = e, this.schedule();
@@ -2056,7 +2226,7 @@ var Bt = class {
2056
2226
  };
2057
2227
  //#endregion
2058
2228
  //#region src/core/backendAutofill.ts
2059
- async function Vt(e, t, n, r) {
2229
+ async function Gt(e, t, n, r) {
2060
2230
  let i = await e.onUnderfilled(n);
2061
2231
  if (!r()) return;
2062
2232
  if (!i.sessionId.trim()) throw TypeError("Vibe backend autofill requires a sessionId.");
@@ -2070,27 +2240,27 @@ async function Vt(e, t, n, r) {
2070
2240
  status: "waiting"
2071
2241
  });
2072
2242
  }
2073
- function Ht(e, t) {
2243
+ function Kt(e, t) {
2074
2244
  ["complete", "exhausted"].includes(t.status) && t.items && (e.items = Q(e.items, t.items)), t.next !== void 0 && (e.next = t.next), t.total !== void 0 && (e.total = t.total);
2075
2245
  }
2076
- function Ut(e, t, n) {
2246
+ function qt(e, t, n) {
2077
2247
  let r = t.autofill;
2078
- return !Nt(e, n, r) || n.sequence <= r.sequence || ["cancelled", "cancelling"].includes(r.status) || ["complete", "exhausted"].includes(n.status) && n.next === void 0 ? !1 : (Ht(t, n), Object.assign(r, $(n.status === "waiting" ? n.nextRequestAt : null)), r.error = n.error ?? null, r.missing = Math.max(0, (r.pageSize ?? 0) - n.received), r.received = n.received, n.requests !== void 0 && (r.requests = n.requests), r.sequence = n.sequence, r.status = n.status, !0);
2248
+ return !Lt(e, n, r) || n.sequence <= r.sequence || ["cancelled", "cancelling"].includes(r.status) || ["complete", "exhausted"].includes(n.status) && n.next === void 0 ? !1 : (Kt(t, n), Object.assign(r, $(n.status === "waiting" ? n.nextRequestAt : null)), r.error = n.error ?? null, r.missing = Math.max(0, (r.pageSize ?? 0) - n.received), r.received = n.received, n.requests !== void 0 && (r.requests = n.requests), r.sequence = n.sequence, r.status = n.status, !0);
2079
2249
  }
2080
- function Wt(e, t, n) {
2081
- return e?.strategy !== "backend" || n.feedKey !== e.feedKey || n.pageSize !== e.pageSize ? !1 : (t.autofill = At(e, n), Ht(t, n), !0);
2250
+ function Jt(e, t, n) {
2251
+ return e?.strategy !== "backend" || n.feedKey !== e.feedKey || n.pageSize !== e.pageSize ? !1 : (t.autofill = Pt(e, n), Kt(t, n), !0);
2082
2252
  }
2083
- var Gt = 1.5;
2084
- function Kt(e) {
2253
+ var Yt = 1.5;
2254
+ function Xt(e) {
2085
2255
  let t = Math.min(e.screenWidth, e.screenHeight);
2086
2256
  if (t > 0 && t < 600) return !0;
2087
- let n = Math.min(e.viewportWidth, e.viewportHeight), r = t >= n * Gt;
2257
+ let n = Math.min(e.viewportWidth, e.viewportHeight), r = t >= n * Yt;
2088
2258
  return !e.hasHover && n > 0 && n < 600 && r;
2089
2259
  }
2090
- function qt(e) {
2091
- return Kt(e) ? "reel" : "masonry";
2260
+ function Zt(e) {
2261
+ return Xt(e) ? "reel" : "masonry";
2092
2262
  }
2093
- function Jt(e) {
2263
+ function Qt(e) {
2094
2264
  let t = e.ownerDocument.defaultView, n = e.ownerDocument.documentElement;
2095
2265
  return {
2096
2266
  hasHover: typeof t?.matchMedia == "function" && t.matchMedia("(hover: hover)").matches,
@@ -2100,15 +2270,15 @@ function Jt(e) {
2100
2270
  viewportWidth: n.clientWidth
2101
2271
  };
2102
2272
  }
2103
- function Yt(e) {
2104
- return Kt(Jt(e));
2273
+ function $t(e) {
2274
+ return Xt(Qt(e));
2105
2275
  }
2106
- function Xt(e) {
2107
- return qt(Jt(e));
2276
+ function en(e) {
2277
+ return Zt(Qt(e));
2108
2278
  }
2109
2279
  //#endregion
2110
2280
  //#region src/core/initialAutofill.ts
2111
- async function Zt({ cycleId: e, isCurrent: t, onLastCursor: n, options: r, signal: i, state: a }) {
2281
+ async function tn({ cycleId: e, isCurrent: t, onLastCursor: n, options: r, signal: i, state: a }) {
2112
2282
  let o = r.autofill;
2113
2283
  if (!o) return;
2114
2284
  let s = a.items.length;
@@ -2121,7 +2291,7 @@ async function Zt({ cycleId: e, isCurrent: t, onLastCursor: n, options: r, signa
2121
2291
  return;
2122
2292
  }
2123
2293
  if (o.strategy === "backend") {
2124
- await Vt(o, a, {
2294
+ await Gt(o, a, {
2125
2295
  cycleId: e,
2126
2296
  feedKey: o.feedKey,
2127
2297
  items: [...a.items],
@@ -2138,11 +2308,11 @@ async function Zt({ cycleId: e, isCurrent: t, onLastCursor: n, options: r, signa
2138
2308
  a.autofill.status = "exhausted";
2139
2309
  return;
2140
2310
  }
2141
- let c = await Pt({
2311
+ let c = await Rt({
2142
2312
  existingItems: a.items,
2143
2313
  initialCursor: a.next,
2144
2314
  loadPage: r.loadPage,
2145
- maximumRequests: o.maxAdditionalPages ?? 10,
2315
+ maximumRequests: At(o, !1),
2146
2316
  onDelayChange: (e) => {
2147
2317
  t() && Object.assign(a.autofill, e);
2148
2318
  },
@@ -2163,13 +2333,13 @@ async function Zt({ cycleId: e, isCurrent: t, onLastCursor: n, options: r, signa
2163
2333
  }
2164
2334
  //#endregion
2165
2335
  //#region src/core/fill.ts
2166
- function Qt(e) {
2336
+ function nn(e) {
2167
2337
  return "pages" in e ? { pages: e.pages } : { until: "end" };
2168
2338
  }
2169
- function $t(e) {
2339
+ function rn(e) {
2170
2340
  return `${typeof e}:${String(e)}`;
2171
2341
  }
2172
- function en(e) {
2342
+ function an(e) {
2173
2343
  if (!e || typeof e != "object") throw TypeError("Vibe fill target must be an object.");
2174
2344
  if ("pages" in e) {
2175
2345
  if (!Number.isInteger(e.pages) || e.pages <= 0) throw TypeError("Vibe fill pages must be a positive integer.");
@@ -2178,20 +2348,20 @@ function en(e) {
2178
2348
  if ("until" in e && e.until === "end") return { until: "end" };
2179
2349
  throw TypeError("Vibe fill target must be { pages } or { until: 'end' }.");
2180
2350
  }
2181
- function tn(e) {
2351
+ function on(e) {
2182
2352
  if (!e) return;
2183
2353
  if (e.strategy === "frontend") {
2184
- Ct(e, "frontend fill");
2354
+ Et(e, "frontend fill");
2185
2355
  return;
2186
2356
  }
2187
2357
  if (!e.feedKey.trim()) throw TypeError("Vibe backend fill requires a feedKey.");
2188
2358
  let t = e.initialSession;
2189
2359
  if (t) {
2190
2360
  if (t.feedKey !== e.feedKey) throw TypeError("Vibe backend fill initialSession feedKey must match fill feedKey.");
2191
- en(t.target);
2361
+ an(t.target);
2192
2362
  }
2193
2363
  }
2194
- function nn(e, t, n = !0) {
2364
+ function sn(e, t, n = !0) {
2195
2365
  let r = e?.strategy === "backend" && n ? e.initialSession : void 0, i = t ?? r, a = $(i?.nextRequestAt);
2196
2366
  return {
2197
2367
  completedPages: i?.completedPages ?? 0,
@@ -2205,10 +2375,10 @@ function nn(e, t, n = !0) {
2205
2375
  sessionId: i?.sessionId ?? null,
2206
2376
  status: i?.status ?? "idle",
2207
2377
  strategy: e?.strategy ?? null,
2208
- target: i ? Qt(i.target) : null
2378
+ target: i ? nn(i.target) : null
2209
2379
  };
2210
2380
  }
2211
- function rn(e) {
2381
+ function cn(e) {
2212
2382
  return [
2213
2383
  "cancelling",
2214
2384
  "filling",
@@ -2216,17 +2386,17 @@ function rn(e) {
2216
2386
  "waiting"
2217
2387
  ].includes(e.status);
2218
2388
  }
2219
- async function an({ existingItems: e, initialCursor: t, loadPage: n, onDelayChange: r, onProgress: i, options: a, signal: o, target: s }) {
2389
+ async function ln({ existingItems: e, initialCursor: t, loadPage: n, onDelayChange: r, onProgress: i, options: a, signal: o, target: s }) {
2220
2390
  let c = [], l = [...e], u = /* @__PURE__ */ new Set(), d = 0, f = t, p = t, m = 0, h;
2221
2391
  for (; p !== null;) {
2222
- let e = $t(f);
2392
+ let e = rn(f);
2223
2393
  if (u.has(e)) throw Error("Vibe fill received a repeated cursor.");
2224
- u.add(e), await Tt({
2225
- delayMs: wt(d, a),
2394
+ u.add(e), await Ot({
2395
+ delayMs: Dt(d, a),
2226
2396
  onChange: r,
2227
2397
  signal: o
2228
2398
  });
2229
- let t = _t(await n({
2399
+ let t = bt(await n({
2230
2400
  cursor: f,
2231
2401
  signal: o
2232
2402
  }));
@@ -2268,7 +2438,7 @@ async function an({ existingItems: e, initialCursor: t, loadPage: n, onDelayChan
2268
2438
  }
2269
2439
  //#endregion
2270
2440
  //#region src/core/backendFill.ts
2271
- async function on(e, t, n, r) {
2441
+ async function un(e, t, n, r) {
2272
2442
  let i = await e.onStart(n);
2273
2443
  if (r()) {
2274
2444
  if (!i.sessionId.trim()) throw TypeError("Vibe backend fill requires a sessionId.");
@@ -2282,22 +2452,22 @@ async function on(e, t, n, r) {
2282
2452
  });
2283
2453
  }
2284
2454
  }
2285
- function sn(e, t, n) {
2455
+ function dn(e, t, n) {
2286
2456
  return e?.strategy === "backend" && n.feedKey === e.feedKey && n.sessionId === t.fill.sessionId;
2287
2457
  }
2288
- function cn(e) {
2458
+ function fn(e) {
2289
2459
  return Number.isInteger(e.completedPages) && e.completedPages >= 0 && Number.isInteger(e.received) && e.received >= 0 && Number.isInteger(e.sequence) && e.sequence >= 0;
2290
2460
  }
2291
- function ln(e, t) {
2461
+ function pn(e, t) {
2292
2462
  if (!["complete", "exhausted"].includes(t.status)) return !0;
2293
2463
  let n = e.fill.target;
2294
2464
  return !n || !Array.isArray(t.items) || t.next === void 0 || t.lastCursor === void 0 ? !1 : t.status === "exhausted" ? "pages" in n && t.completedPages < n.pages && t.next === null : "pages" in n ? t.completedPages === n.pages : t.next === null;
2295
2465
  }
2296
- function un(e, t, n) {
2466
+ function mn(e, t, n) {
2297
2467
  t.total !== void 0 && (e.total = t.total), ["complete", "exhausted"].includes(t.status) && (e.items = Q(e.items, t.items ?? []), e.next = t.next ?? null, n(t.lastCursor ?? null));
2298
2468
  }
2299
- function dn(e, t, n, r) {
2300
- return !sn(e, t, n) || !cn(n) || n.sequence <= t.fill.sequence || ["cancelled", "cancelling"].includes(t.fill.status) || !ln(t, n) ? !1 : (un(t, n, r), Object.assign(t.fill, {
2469
+ function hn(e, t, n, r) {
2470
+ return !dn(e, t, n) || !fn(n) || n.sequence <= t.fill.sequence || ["cancelled", "cancelling"].includes(t.fill.status) || !pn(t, n) ? !1 : (mn(t, n, r), Object.assign(t.fill, {
2301
2471
  ...$(n.status === "waiting" ? n.nextRequestAt : null),
2302
2472
  completedPages: n.completedPages,
2303
2473
  error: n.error ?? null,
@@ -2306,41 +2476,41 @@ function dn(e, t, n, r) {
2306
2476
  status: n.status
2307
2477
  }), !0);
2308
2478
  }
2309
- function fn(e, t, n, r) {
2479
+ function gn(e, t, n, r) {
2310
2480
  if (e?.strategy !== "backend" || n.feedKey !== e.feedKey) return !1;
2311
2481
  let i = t.fill;
2312
- return t.fill = nn(e, n), !cn(n) || !ln(t, n) ? (t.fill = i, !1) : (un(t, n, r), !0);
2482
+ return t.fill = sn(e, n), !fn(n) || !pn(t, n) ? (t.fill = i, !1) : (mn(t, n, r), !0);
2313
2483
  }
2314
2484
  //#endregion
2315
2485
  //#region src/core/fillController.ts
2316
- var pn = class {
2486
+ var _n = class {
2317
2487
  abortController = null;
2318
2488
  cycle = 0;
2319
2489
  delayCountdown;
2320
2490
  requestVersion = 0;
2321
2491
  constructor(e) {
2322
- this.options = e, this.delayCountdown = new Et((e) => {
2492
+ this.options = e, this.delayCountdown = new kt((e) => {
2323
2493
  Object.assign(this.options.state.fill, e);
2324
2494
  }), this.syncBackendCountdown();
2325
2495
  }
2326
2496
  isActive() {
2327
- return rn(this.options.state.fill);
2497
+ return cn(this.options.state.fill);
2328
2498
  }
2329
2499
  applyUpdate(e) {
2330
- let t = dn(this.options.fill, this.options.state, e, this.options.onLastCursor);
2500
+ let t = hn(this.options.fill, this.options.state, e, this.options.onLastCursor);
2331
2501
  return t && this.syncBackendCountdown(), t;
2332
2502
  }
2333
2503
  restoreSession(e) {
2334
- let t = fn(this.options.fill, this.options.state, e, this.options.onLastCursor);
2504
+ let t = gn(this.options.fill, this.options.state, e, this.options.onLastCursor);
2335
2505
  return t && this.syncBackendCountdown(), t;
2336
2506
  }
2337
2507
  async start(e) {
2338
2508
  let t = this.options.fill;
2339
2509
  if (!t) throw Error("Vibe fill is not configured.");
2340
2510
  if (this.isActive()) throw Error("Vibe fill is already active.");
2341
- let n = en(e), r = `vibe-fill-${Date.now().toString(36)}-${++this.cycle}`;
2511
+ let n = an(e), r = `vibe-fill-${Date.now().toString(36)}-${++this.cycle}`;
2342
2512
  if (this.options.state.fill = {
2343
- ...nn(t, void 0, !1),
2513
+ ...sn(t, void 0, !1),
2344
2514
  cycleId: r,
2345
2515
  status: "filling",
2346
2516
  target: n
@@ -2351,7 +2521,7 @@ var pn = class {
2351
2521
  let i = ++this.requestVersion, a = new AbortController();
2352
2522
  this.abortController = a;
2353
2523
  try {
2354
- t.strategy === "frontend" ? await this.startFrontend(t, n, a, i) : (await on(t, this.options.state, {
2524
+ t.strategy === "frontend" ? await this.startFrontend(t, n, a, i) : (await un(t, this.options.state, {
2355
2525
  cycleId: r,
2356
2526
  feedKey: t.feedKey,
2357
2527
  items: [...this.options.state.items],
@@ -2369,7 +2539,7 @@ var pn = class {
2369
2539
  }
2370
2540
  async cancel() {
2371
2541
  let { fill: e, state: t } = this.options;
2372
- if (!rn(t.fill) || !t.fill.cycleId) return;
2542
+ if (!cn(t.fill) || !t.fill.cycleId) return;
2373
2543
  let n = {
2374
2544
  cycleId: t.fill.cycleId,
2375
2545
  feedKey: t.fill.feedKey ?? "",
@@ -2383,7 +2553,7 @@ var pn = class {
2383
2553
  }
2384
2554
  }
2385
2555
  reset() {
2386
- this.abortLocalRequest(), this.delayCountdown.clear(), this.options.state.fill = nn(this.options.fill, void 0, !1);
2556
+ this.abortLocalRequest(), this.delayCountdown.clear(), this.options.state.fill = sn(this.options.fill, void 0, !1);
2387
2557
  }
2388
2558
  destroy() {
2389
2559
  this.abortLocalRequest(), this.delayCountdown.clear();
@@ -2399,7 +2569,7 @@ var pn = class {
2399
2569
  if (!i) throw Error("Vibe frontend fill requires loadPage.");
2400
2570
  let a = this.options.state;
2401
2571
  a.isLoadingMore = !0;
2402
- let o = await an({
2572
+ let o = await ln({
2403
2573
  existingItems: a.items,
2404
2574
  initialCursor: a.next,
2405
2575
  loadPage: i,
@@ -2424,45 +2594,55 @@ var pn = class {
2424
2594
  this.delayCountdown.sync(e.strategy === "backend" && e.status === "waiting" ? e.nextRequestAt : null);
2425
2595
  }
2426
2596
  };
2427
- function mn(e) {
2597
+ //#endregion
2598
+ //#region src/core/feedFooter.ts
2599
+ function vn(e) {
2600
+ return {
2601
+ cancelAutofill: () => e.cancelAutofill(),
2602
+ loadMore: () => e.loadNext(),
2603
+ retry: () => e.reload(),
2604
+ retryEnd: () => e.retryEnd()
2605
+ };
2606
+ }
2607
+ function yn(e) {
2428
2608
  if (!Number.isFinite(e) || e <= 0) throw TypeError("Vibe reelAutoAdvance.intervalMs must be a positive number.");
2429
2609
  }
2430
- function hn(e) {
2431
- e?.intervalMs !== void 0 && mn(e.intervalMs);
2610
+ function bn(e) {
2611
+ e?.intervalMs !== void 0 && yn(e.intervalMs);
2432
2612
  }
2433
- function gn(e) {
2613
+ function xn(e) {
2434
2614
  return {
2435
2615
  enabled: e?.enabled ?? !1,
2436
2616
  includePostItems: e?.includePostItems ?? !1,
2437
2617
  intervalMs: e?.intervalMs ?? 5e3
2438
2618
  };
2439
2619
  }
2440
- function _n(e, t) {
2620
+ function Sn(e, t) {
2441
2621
  if (typeof t == "boolean") {
2442
2622
  e.enabled = t;
2443
2623
  return;
2444
2624
  }
2445
- hn(t), t.enabled !== void 0 && (e.enabled = t.enabled), t.includePostItems !== void 0 && (e.includePostItems = t.includePostItems), t.intervalMs !== void 0 && (e.intervalMs = t.intervalMs);
2625
+ bn(t), t.enabled !== void 0 && (e.enabled = t.enabled), t.includePostItems !== void 0 && (e.includePostItems = t.includePostItems), t.intervalMs !== void 0 && (e.intervalMs = t.intervalMs);
2446
2626
  }
2447
2627
  //#endregion
2448
2628
  //#region src/core/reelInfoSheet.ts
2449
- function vn(e) {
2629
+ function Cn(e) {
2450
2630
  return { enabled: e?.enabled ?? !1 };
2451
2631
  }
2452
- function yn(e, t, n) {
2632
+ function wn(e, t, n) {
2453
2633
  if (n && !t) throw Error("Vibe cannot enable reelInfoSheet without a configured component.");
2454
2634
  e.enabled = n;
2455
2635
  }
2456
2636
  //#endregion
2457
2637
  //#region src/core/initialRuntimeState.ts
2458
- function bn(e, t) {
2638
+ function Tn(e, t) {
2459
2639
  let n = e.initialPage;
2460
2640
  return {
2461
2641
  activeReelPostId: null,
2462
- autoScroll: zt(e.autoScroll),
2463
- autofill: At(e.autofill),
2642
+ autoScroll: Ut(e.autoScroll),
2643
+ autofill: Pt(e.autofill),
2464
2644
  error: null,
2465
- fill: nn(e.fill),
2645
+ fill: sn(e.fill),
2466
2646
  infiniteScroll: e.infiniteScroll ?? !0,
2467
2647
  isLoading: !n,
2468
2648
  isLoadingMore: !1,
@@ -2471,8 +2651,8 @@ function bn(e, t) {
2471
2651
  loadMoreLocked: !1,
2472
2652
  next: n?.next ?? null,
2473
2653
  nextPageError: null,
2474
- reelAutoAdvance: gn(e.reelAutoAdvance),
2475
- reelInfoSheet: vn(e.reelInfoSheet),
2654
+ reelAutoAdvance: xn(e.reelAutoAdvance),
2655
+ reelInfoSheet: Cn(e.reelInfoSheet),
2476
2656
  reelInfoSheetOverlay: !1,
2477
2657
  reelMediaSource: "original",
2478
2658
  reelOrigin: null,
@@ -2481,16 +2661,16 @@ function bn(e, t) {
2481
2661
  }
2482
2662
  //#endregion
2483
2663
  //#region src/core/options.ts
2484
- function xn(e, t) {
2664
+ function En(e, t) {
2485
2665
  if (t && (!Number.isFinite(t.height) || t.height <= 0)) throw TypeError(`Vibe ${e} height must be a positive number.`);
2486
2666
  }
2487
- function Sn(e) {
2488
- if (Rt(e.autoScroll), xn("cardHeader", e.cardHeader), xn("cardFooter", e.cardFooter), kt(e.autofill), tn(e.fill), hn(e.reelAutoAdvance), !e.initialPage && !e.loadPage) throw TypeError("Vibe requires either initialPage or loadPage.");
2667
+ function Dn(e) {
2668
+ if (Ht(e.autoScroll), En("cardHeader", e.cardHeader), En("cardFooter", e.cardFooter), Nt(e.autofill), on(e.fill), bn(e.reelAutoAdvance), !e.initialPage && !e.loadPage) throw TypeError("Vibe requires either initialPage or loadPage.");
2489
2669
  if (e.initialPage?.next !== null && !e.loadPage) throw TypeError("Vibe requires loadPage when initialPage has a next cursor.");
2490
2670
  if (e.fill?.strategy === "frontend" && !e.loadPage) throw TypeError("Vibe frontend fill requires loadPage.");
2491
2671
  if (e.fill?.strategy === "backend" && e.fill.initialSession && !e.initialPage) throw TypeError("Vibe backend fill restoration requires initialPage.");
2492
2672
  }
2493
- function Cn(e) {
2673
+ function On(e) {
2494
2674
  if (typeof e != "string") return e;
2495
2675
  if (typeof document > "u") throw Error("Vibe cannot resolve a selector without a document.");
2496
2676
  let t = document.querySelector(e);
@@ -2499,7 +2679,7 @@ function Cn(e) {
2499
2679
  }
2500
2680
  //#endregion
2501
2681
  //#region src/core/vibeRouting.ts
2502
- var wn = class {
2682
+ var kn = class {
2503
2683
  routedReelPostId = null;
2504
2684
  reelRouteIsActive = !1;
2505
2685
  constructor(e, t) {
@@ -2526,37 +2706,7 @@ var wn = class {
2526
2706
  let i = this.reelRouteIsActive ? "replace" : "push";
2527
2707
  this.reelRouteIsActive = !0, this.routedReelPostId = e, this.options.router[i](r);
2528
2708
  }
2529
- };
2530
- //#endregion
2531
- //#region src/core/runtime.ts
2532
- function Tn(e) {
2533
- return {
2534
- activeReelPostId: e.activeReelPostId,
2535
- autoScroll: { ...e.autoScroll },
2536
- autofill: { ...e.autofill },
2537
- error: e.error,
2538
- fill: {
2539
- ...e.fill,
2540
- target: e.fill.target ? { ...e.fill.target } : null
2541
- },
2542
- infiniteScroll: e.infiniteScroll,
2543
- isLoading: e.isLoading,
2544
- isLoadingMore: e.isLoadingMore,
2545
- items: [...e.items],
2546
- layout: e.layout,
2547
- lifecycle: e.isLoading || e.isLoadingMore ? "loading" : e.error || e.nextPageError ? "error" : "loaded",
2548
- loadMoreLocked: e.loadMoreLocked,
2549
- next: e.next,
2550
- nextPageError: e.nextPageError,
2551
- reelAutoAdvance: { ...e.reelAutoAdvance },
2552
- reelInfoSheet: { ...e.reelInfoSheet },
2553
- reelOrigin: e.reelOrigin,
2554
- total: e.total
2555
- };
2556
- }
2557
- //#endregion
2558
- //#region src/core/createVibe.ts
2559
- var En = class {
2709
+ }, An = class {
2560
2710
  app = null;
2561
2711
  autoScroll;
2562
2712
  autofillDelayCountdown;
@@ -2574,26 +2724,28 @@ var En = class {
2574
2724
  lastLoadedCursor = null;
2575
2725
  state;
2576
2726
  constructor(e) {
2577
- this.options = e, Sn(e), this.layoutMode = e.layout ?? "masonry", this.state = y(bn(e, this.layoutMode)), this.autoScroll = new Bt({
2727
+ this.options = e, Dn(e), this.layoutMode = e.layout ?? "masonry", this.state = b(Tn(e, this.layoutMode)), this.autoScroll = new Wt({
2578
2728
  getScrollElement: () => this.surface?.getAutoScrollElement() ?? null,
2579
2729
  state: this.state.autoScroll
2580
- }), this.autofillDelayCountdown = new Et((e) => Object.assign(this.state.autofill, e)), this.syncAutofillCountdown(), this.fillController = new pn({
2730
+ }), this.autofillDelayCountdown = new kt((e) => Object.assign(this.state.autofill, e)), this.syncAutofillCountdown(), this.fillController = new _n({
2581
2731
  fill: e.fill,
2582
2732
  loadPage: e.loadPage,
2583
2733
  onLastCursor: (e) => {
2584
2734
  this.lastLoadedCursor = e;
2585
2735
  },
2586
2736
  state: this.state
2587
- }), this.routing = new wn(e.routing, this.state), this.startStateNotifications();
2737
+ }), this.routing = new kn(e.routing, this.state), this.startStateNotifications();
2588
2738
  }
2589
2739
  async mount() {
2590
2740
  if (this.app) throw Error("Vibe is already mounted.");
2591
2741
  this.startStateNotifications();
2592
- let e = Cn(this.options.target);
2593
- this.target = e, this.startResponsiveLayout(), this.app = r(gt, {
2742
+ let e = On(this.options.target);
2743
+ this.target = e, this.startResponsiveLayout(), this.app = r(yt, {
2594
2744
  canRetryEnd: !!this.options.loadPage,
2595
2745
  cardFooter: this.options.cardFooter,
2596
2746
  cardHeader: this.options.cardHeader,
2747
+ feedFooter: this.options.feedFooter,
2748
+ feedFooterActions: vn(this),
2597
2749
  reelInfoSheet: this.options.reelInfoSheet,
2598
2750
  state: this.state,
2599
2751
  onActiveReelChange: (e) => this.setActiveReelPost(e),
@@ -2612,7 +2764,7 @@ var En = class {
2612
2764
  this.autoScroll.destroy(), this.fillController.destroy(), this.cancelRequest(), this.stopResponsiveLayout(), this.stopStateWatcher?.(), this.stopStateWatcher = null, this.app?.unmount(), this.app = null, this.surface = null, this.target = null;
2613
2765
  }
2614
2766
  getState() {
2615
- return Tn(this.state);
2767
+ return F(this.state);
2616
2768
  }
2617
2769
  nextReelMediaItem() {
2618
2770
  return this.surface?.changeActiveReelMedia(1) ?? !1;
@@ -2639,11 +2791,11 @@ var En = class {
2639
2791
  this.autoScroll.setSpeed(e);
2640
2792
  }
2641
2793
  applyAutofillUpdate(e) {
2642
- let t = Ut(this.options.autofill, this.state, e);
2794
+ let t = qt(this.options.autofill, this.state, e);
2643
2795
  return t && this.syncAutofillCountdown(), t;
2644
2796
  }
2645
2797
  async cancelAutofill() {
2646
- await Mt(this.options.autofill, this.state, () => this.cancelRequest());
2798
+ await It(this.options.autofill, this.state, () => this.cancelRequest());
2647
2799
  }
2648
2800
  applyFillUpdate(e) {
2649
2801
  return this.fillController.applyUpdate(e);
@@ -2652,11 +2804,11 @@ var En = class {
2652
2804
  return this.fillController.cancel();
2653
2805
  }
2654
2806
  async fill(e) {
2655
- if (this.pendingRequest || jt(this.state.autofill)) throw Error("Vibe cannot fill while another page operation is active.");
2807
+ if (this.pendingRequest || Ft(this.state.autofill)) throw Error("Vibe cannot fill while another page operation is active.");
2656
2808
  await this.fillController.start(e);
2657
2809
  }
2658
2810
  restoreAutofillSession(e) {
2659
- let t = Wt(this.options.autofill, this.state, e);
2811
+ let t = Jt(this.options.autofill, this.state, e);
2660
2812
  return t && this.syncAutofillCountdown(), t;
2661
2813
  }
2662
2814
  restoreFillSession(e) {
@@ -2664,27 +2816,27 @@ var En = class {
2664
2816
  }
2665
2817
  async loadNext() {
2666
2818
  if (this.pendingRequest) return this.pendingRequest;
2667
- if (!this.state.loadMoreLocked && !(jt(this.state.autofill) || this.fillController.isActive()) && !(this.state.next === null || !this.options.loadPage)) return this.state.isLoadingMore = !0, this.state.nextPageError = null, this.startRequest(this.state.next, !0);
2819
+ if (!this.state.loadMoreLocked && !(Ft(this.state.autofill) || this.fillController.isActive()) && !(this.state.next === null || !this.options.loadPage)) return this.state.isLoadingMore = !0, this.state.nextPageError = null, this.startRequest(this.state.next, !0);
2668
2820
  }
2669
2821
  async reload() {
2670
2822
  if (!this.options.loadPage) throw Error("Vibe cannot reload without loadPage.");
2671
- return jt(this.state.autofill) && await this.cancelAutofill(), this.fillController.isActive() && await this.cancelFill(), this.cancelRequest(), this.state.autofill = At(this.options.autofill, void 0, !1), this.fillController.reset(), this.state.error = null, this.state.isLoading = !0, this.state.items = [], this.state.next = null, this.state.nextPageError = null, this.state.total = null, this.startRequest(null, !1);
2823
+ return Ft(this.state.autofill) && await this.cancelAutofill(), this.fillController.isActive() && await this.cancelFill(), this.cancelRequest(), this.state.autofill = Pt(this.options.autofill, void 0, !1), this.fillController.reset(), this.state.error = null, this.state.isLoading = !0, this.state.items = [], this.state.next = null, this.state.nextPageError = null, this.state.total = null, this.startRequest(null, !1);
2672
2824
  }
2673
2825
  async retryEnd() {
2674
2826
  if (this.pendingRequest) return this.pendingRequest;
2675
- if (!this.state.loadMoreLocked && !(jt(this.state.autofill) || this.fillController.isActive()) && !(this.state.next !== null || !this.options.loadPage)) return this.state.isLoadingMore = !0, this.state.nextPageError = null, this.startRequest(this.lastLoadedCursor, !0);
2827
+ if (!this.state.loadMoreLocked && !(Ft(this.state.autofill) || this.fillController.isActive()) && !(this.state.next !== null || !this.options.loadPage)) return this.state.isLoadingMore = !0, this.state.nextPageError = null, this.startRequest(this.lastLoadedCursor, !0);
2676
2828
  }
2677
2829
  setInfiniteScroll(e) {
2678
- this.state.infiniteScroll = e, e && f(() => this.surface?.loadIfNearBottom());
2830
+ this.state.infiniteScroll = e, e && p(() => this.surface?.loadIfNearBottom());
2679
2831
  }
2680
2832
  setLoadMoreLocked(e) {
2681
- this.state.loadMoreLocked !== e && (this.state.loadMoreLocked = e, !e && this.state.infiniteScroll && f(() => this.surface?.loadIfNearBottom()));
2833
+ this.state.loadMoreLocked !== e && (this.state.loadMoreLocked = e, !e && this.state.infiniteScroll && p(() => this.surface?.loadIfNearBottom()));
2682
2834
  }
2683
2835
  setReelAutoAdvance(e) {
2684
- _n(this.state.reelAutoAdvance, e);
2836
+ Sn(this.state.reelAutoAdvance, e);
2685
2837
  }
2686
2838
  setReelInfoSheet(e) {
2687
- yn(this.state.reelInfoSheet, this.options.reelInfoSheet, e);
2839
+ wn(this.state.reelInfoSheet, this.options.reelInfoSheet, e);
2688
2840
  }
2689
2841
  setLayout(e) {
2690
2842
  e !== this.layoutMode && (this.layoutMode = e, e === "responsive" ? this.handleResponsiveLayout() : this.applyLayout(e));
@@ -2694,8 +2846,8 @@ var En = class {
2694
2846
  }
2695
2847
  handleResponsiveLayout = () => {
2696
2848
  if (!this.target) return;
2697
- let e = Xt(this.target);
2698
- this.state.reelInfoSheetOverlay = Yt(this.target), this.state.reelMediaSource = e === "reel" ? "preview" : "original", this.layoutMode === "responsive" && this.applyLayout(e);
2849
+ let e = en(this.target);
2850
+ this.state.reelInfoSheetOverlay = $t(this.target), this.state.reelMediaSource = e === "reel" ? "preview" : "original", this.layoutMode === "responsive" && this.applyLayout(e);
2699
2851
  };
2700
2852
  startResponsiveLayout() {
2701
2853
  if (!this.target) return;
@@ -2727,7 +2879,7 @@ var En = class {
2727
2879
  this.abortController = i;
2728
2880
  try {
2729
2881
  if (a?.strategy === "frontend") {
2730
- let o = await Pt({
2882
+ let o = await Rt({
2731
2883
  existingItems: t ? this.state.items : [],
2732
2884
  initialCursor: e,
2733
2885
  loadPage: n,
@@ -2749,7 +2901,7 @@ var En = class {
2749
2901
  });
2750
2902
  return;
2751
2903
  }
2752
- let c = _t(await n({
2904
+ let c = bt(await n({
2753
2905
  cursor: e,
2754
2906
  signal: i.signal
2755
2907
  }));
@@ -2764,7 +2916,7 @@ var En = class {
2764
2916
  this.state.autofill.status = "complete";
2765
2917
  return;
2766
2918
  }
2767
- await Vt(a, this.state, {
2919
+ await Gt(a, this.state, {
2768
2920
  cycleId: o,
2769
2921
  feedKey: a.feedKey,
2770
2922
  items: u.slice(l.length),
@@ -2789,7 +2941,7 @@ var En = class {
2789
2941
  this.autofillDelayCountdown.clear();
2790
2942
  let t = `vibe-autofill-${Date.now().toString(36)}-${++this.autofillCycle}`;
2791
2943
  return this.state.autofill = {
2792
- ...At(e, void 0, !1),
2944
+ ...Pt(e, void 0, !1),
2793
2945
  cycleId: t,
2794
2946
  status: "filling"
2795
2947
  }, t;
@@ -2807,7 +2959,7 @@ var En = class {
2807
2959
  startInitialAutofill() {
2808
2960
  let e = ++this.requestVersion, t = new AbortController(), n = this.beginAutofillCycle();
2809
2961
  this.abortController = t, this.state.isLoadingMore = !0;
2810
- let r = Zt({
2962
+ let r = tn({
2811
2963
  cycleId: n,
2812
2964
  isCurrent: () => e === this.requestVersion,
2813
2965
  onLastCursor: (e) => {
@@ -2825,14 +2977,14 @@ var En = class {
2825
2977
  }
2826
2978
  startStateNotifications() {
2827
2979
  let e = this.options.onStateChange;
2828
- !e || this.stopStateWatcher || (e(this.getState()), this.stopStateWatcher = E(this.state, () => e(this.getState()), {
2980
+ !e || this.stopStateWatcher || (e(this.getState()), this.stopStateWatcher = D(this.state, () => e(this.getState()), {
2829
2981
  deep: !0,
2830
2982
  flush: "post"
2831
2983
  }));
2832
2984
  }
2833
2985
  };
2834
- function Dn(e) {
2835
- return new En(e);
2986
+ function jn(e) {
2987
+ return new An(e);
2836
2988
  }
2837
2989
  //#endregion
2838
- export { Dn as createVibe };
2990
+ export { jn as createVibe };