peek-carousel 1.0.2 → 1.0.4

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.
@@ -4,338 +4,245 @@
4
4
  * @license MIT
5
5
  * @author lledellebell
6
6
  */
7
- const LAYOUT_MODES = Object.freeze({
8
- STACK: 'stack',
9
- RADIAL: 'radial',
10
- CLASSIC: 'classic'
11
- });
12
- const DEFAULT_OPTIONS = Object.freeze({
7
+ const M = Object.freeze({
8
+ STACK: "stack",
9
+ RADIAL: "radial",
10
+ CLASSIC: "classic"
11
+ }), P = Object.freeze({
13
12
  startIndex: 1,
14
- layoutMode: LAYOUT_MODES.STACK,
15
- autoRotate: false,
13
+ layoutMode: M.STACK,
14
+ autoRotate: !1,
16
15
  autoRotateInterval: 2500,
17
16
  preloadRange: 2,
18
17
  swipeThreshold: 50,
19
18
  dragThreshold: 80,
20
- enableKeyboard: true,
21
- enableWheel: true,
22
- enableTouch: true,
23
- enableMouse: true,
24
- showNavigation: true,
25
- showCounter: true,
26
- showIndicators: true,
27
- showAutoRotateButton: true
19
+ enableKeyboard: !0,
20
+ enableWheel: !0,
21
+ enableTouch: !0,
22
+ enableMouse: !0,
23
+ showNavigation: !0,
24
+ showCounter: !0,
25
+ showIndicators: !0,
26
+ showAutoRotateButton: !0
28
27
  });
29
- function validateOptions(options) {
30
- const validated = {
31
- ...DEFAULT_OPTIONS,
32
- ...options
33
- };
34
- if (validated.startIndex < 0) {
35
- console.warn('PeekCarousel: startIndex는 0 이상이어야 합니다. 기본값 1 사용');
36
- validated.startIndex = 1;
37
- }
38
- if (!Object.values(LAYOUT_MODES).includes(validated.layoutMode)) {
39
- console.warn(`PeekCarousel: 유효하지 않은 layoutMode "${validated.layoutMode}". 기본값 "stack" 사용`);
40
- validated.layoutMode = LAYOUT_MODES.STACK;
41
- }
42
- if (validated.autoRotateInterval < 100) {
43
- console.warn('PeekCarousel: autoRotateInterval은 100ms 이상이어야 합니다. 기본값 2500 사용');
44
- validated.autoRotateInterval = 2500;
45
- }
46
- if (validated.preloadRange < 0) {
47
- console.warn('PeekCarousel: preloadRange는 0 이상이어야 합니다. 기본값 2 사용');
48
- validated.preloadRange = 2;
49
- }
50
- return validated;
28
+ function L(a) {
29
+ const t = { ...P, ...a };
30
+ return t.startIndex < 0 && (console.warn("PeekCarousel: startIndex는 0 이상이어야 합니다. 기본값 1 사용"), t.startIndex = 1), Object.values(M).includes(t.layoutMode) || (console.warn(`PeekCarousel: 유효하지 않은 layoutMode "${t.layoutMode}". 기본값 "stack" 사용`), t.layoutMode = M.STACK), t.autoRotateInterval < 100 && (console.warn("PeekCarousel: autoRotateInterval은 100ms 이상이어야 합니다. 기본값 2500 사용"), t.autoRotateInterval = 2500), t.preloadRange < 0 && (console.warn("PeekCarousel: preloadRange는 0 이상이어야 합니다. 기본값 2 사용"), t.preloadRange = 2), t;
51
31
  }
52
-
53
- const CLASS_NAMES = Object.freeze({
54
- carousel: 'peek-carousel',
55
- track: 'peek-carousel__track',
56
- item: 'peek-carousel__item',
57
- itemActive: 'peek-carousel__item--active',
58
- itemPrev: 'peek-carousel__item--prev',
59
- itemNext: 'peek-carousel__item--next',
60
- itemCenter: 'peek-carousel__item--center',
61
- itemHidden: 'peek-carousel__item--hidden',
62
- itemDraggingLeft: 'peek-carousel__item--dragging-left',
63
- itemDraggingRight: 'peek-carousel__item--dragging-right',
64
- figure: 'peek-carousel__figure',
65
- image: 'peek-carousel__image',
66
- caption: 'peek-carousel__caption',
67
- nav: 'peek-carousel__nav',
68
- navBtn: 'nav-btn',
69
- btn: 'peek-carousel__btn',
70
- prevBtn: 'prev-btn',
71
- nextBtn: 'next-btn',
72
- autoRotateBtn: 'auto-rotate-btn',
73
- btnAutoRotate: 'peek-carousel__btn--auto-rotate',
74
- btnActive: 'peek-carousel__btn--active',
75
- controls: 'peek-carousel__controls',
76
- indicators: 'peek-carousel__indicators',
77
- indicator: 'indicator',
78
- indicatorPeek: 'peek-carousel__indicator',
79
- indicatorActive: 'peek-carousel__indicator--active',
80
- indicatorProgress: 'peek-carousel__indicator--progress',
81
- indicatorCompleted: 'peek-carousel__indicator--completed',
82
- counter: 'peek-carousel__counter',
83
- counterCurrent: 'peek-carousel__counter-current',
84
- counterSeparator: 'peek-carousel__counter-separator',
85
- counterTotal: 'peek-carousel__counter-total',
86
- playIcon: 'play-icon',
87
- pauseIcon: 'pause-icon'
88
- });
89
- const SELECTORS = Object.freeze({
90
- carousel: '.peek-carousel__track',
91
- item: '.peek-carousel__item',
92
- indicator: '.indicator',
93
- prevBtn: '.prev-btn',
94
- nextBtn: '.next-btn',
95
- autoRotateBtn: '.auto-rotate-btn',
96
- playIcon: '.play-icon',
97
- pauseIcon: '.pause-icon',
98
- image: 'img'
99
- });
100
- const ARIA = Object.freeze({
101
- current: 'aria-current',
102
- selected: 'aria-selected',
103
- pressed: 'aria-pressed',
104
- label: 'aria-label',
105
- tabindex: 'tabindex'
106
- });
107
- const BREAKPOINTS = Object.freeze({
108
- mobile: 768 // [개발참고] px
109
- });
110
- const DURATIONS = Object.freeze({
32
+ const r = Object.freeze({
33
+ carousel: "peek-carousel",
34
+ track: "peek-carousel__track",
35
+ item: "peek-carousel__item",
36
+ itemActive: "peek-carousel__item--active",
37
+ itemPrev: "peek-carousel__item--prev",
38
+ itemNext: "peek-carousel__item--next",
39
+ itemCenter: "peek-carousel__item--center",
40
+ itemHidden: "peek-carousel__item--hidden",
41
+ itemDraggingLeft: "peek-carousel__item--dragging-left",
42
+ itemDraggingRight: "peek-carousel__item--dragging-right",
43
+ figure: "peek-carousel__figure",
44
+ image: "peek-carousel__image",
45
+ caption: "peek-carousel__caption",
46
+ nav: "peek-carousel__nav",
47
+ navBtn: "nav-btn",
48
+ btn: "peek-carousel__btn",
49
+ prevBtn: "prev-btn",
50
+ nextBtn: "next-btn",
51
+ autoRotateBtn: "auto-rotate-btn",
52
+ btnAutoRotate: "peek-carousel__btn--auto-rotate",
53
+ btnActive: "peek-carousel__btn--active",
54
+ controls: "peek-carousel__controls",
55
+ indicators: "peek-carousel__indicators",
56
+ indicator: "indicator",
57
+ indicatorPeek: "peek-carousel__indicator",
58
+ indicatorActive: "peek-carousel__indicator--active",
59
+ indicatorProgress: "peek-carousel__indicator--progress",
60
+ indicatorCompleted: "peek-carousel__indicator--completed",
61
+ counter: "peek-carousel__counter",
62
+ counterCurrent: "peek-carousel__counter-current",
63
+ counterSeparator: "peek-carousel__counter-separator",
64
+ counterTotal: "peek-carousel__counter-total",
65
+ playIcon: "play-icon",
66
+ pauseIcon: "pause-icon"
67
+ }), C = Object.freeze({
68
+ carousel: ".peek-carousel__track",
69
+ item: ".peek-carousel__item",
70
+ indicator: ".indicator",
71
+ prevBtn: ".prev-btn",
72
+ nextBtn: ".next-btn",
73
+ autoRotateBtn: ".auto-rotate-btn",
74
+ playIcon: ".play-icon",
75
+ pauseIcon: ".pause-icon",
76
+ image: "img"
77
+ }), g = Object.freeze({
78
+ current: "aria-current",
79
+ selected: "aria-selected",
80
+ pressed: "aria-pressed",
81
+ label: "aria-label",
82
+ tabindex: "tabindex"
83
+ }), H = Object.freeze({
84
+ mobile: 768
85
+ // [개발참고] px
86
+ }), E = Object.freeze({
111
87
  transition: 500,
112
88
  // [개발참고] ms
113
- progressReset: 10 // [개발참고] ms
114
- });
115
- const KEYS = Object.freeze({
116
- arrowLeft: 'ArrowLeft',
117
- arrowRight: 'ArrowRight',
118
- home: 'Home',
119
- end: 'End',
120
- space: ' '
89
+ progressReset: 10
90
+ // [개발참고] ms
91
+ }), b = Object.freeze({
92
+ arrowLeft: "ArrowLeft",
93
+ arrowRight: "ArrowRight",
94
+ home: "Home",
95
+ end: "End",
96
+ space: " "
121
97
  });
122
-
123
- function getElement(selector) {
124
- if (typeof selector === 'string') {
125
- return document.querySelector(selector);
126
- }
127
- return selector instanceof HTMLElement ? selector : null;
98
+ function N(a) {
99
+ return typeof a == "string" ? document.querySelector(a) : a instanceof HTMLElement ? a : null;
128
100
  }
129
- function getElements(selector, parent = document) {
130
- if (typeof selector !== 'string') return [];
131
- return Array.from(parent.querySelectorAll(selector));
101
+ function $(a, t = document) {
102
+ return typeof a != "string" ? [] : Array.from(t.querySelectorAll(a));
132
103
  }
133
- function addClass(element, ...classes) {
134
- if (element instanceof HTMLElement && classes.length > 0) {
135
- element.classList.add(...classes);
136
- }
104
+ function f(a, ...t) {
105
+ a instanceof HTMLElement && t.length > 0 && a.classList.add(...t);
137
106
  }
138
- function removeClass(element, ...classes) {
139
- if (element instanceof HTMLElement && classes.length > 0) {
140
- element.classList.remove(...classes);
141
- }
107
+ function v(a, ...t) {
108
+ a instanceof HTMLElement && t.length > 0 && a.classList.remove(...t);
142
109
  }
143
- function setCSSVar(element, property, value) {
144
- if (element instanceof HTMLElement && property) {
145
- element.style.setProperty(property, value);
146
- }
110
+ function B(a, t, e) {
111
+ a instanceof HTMLElement && t && a.style.setProperty(t, e);
147
112
  }
148
- function setAttribute(element, name, value) {
149
- if (element instanceof HTMLElement && name) {
150
- element.setAttribute(name, value);
151
- }
113
+ function I(a, t, e) {
114
+ a instanceof HTMLElement && t && a.setAttribute(t, e);
152
115
  }
153
-
154
- const loadingCache = new Map();
155
- function preloadImage(src) {
156
- return new Promise((resolve, reject) => {
157
- if (!src) {
158
- reject(new Error('이미지 소스가 제공되지 않았습니다'));
116
+ const A = /* @__PURE__ */ new Map();
117
+ function O(a) {
118
+ return new Promise((t, e) => {
119
+ if (!a) {
120
+ e(new Error("이미지 소스가 제공되지 않았습니다"));
159
121
  return;
160
122
  }
161
- if (loadingCache.has(src)) {
162
- return loadingCache.get(src);
163
- }
164
- const img = new Image();
165
- const promise = new Promise((res, rej) => {
166
- img.onload = () => {
167
- loadingCache.delete(src);
168
- res(img);
169
- };
170
- img.onerror = () => {
171
- loadingCache.delete(src);
172
- rej(new Error(`이미지 로드 실패: ${src}`));
173
- };
174
- img.src = src;
123
+ if (A.has(a))
124
+ return A.get(a);
125
+ const s = new Image(), i = new Promise((o, n) => {
126
+ s.onload = () => {
127
+ A.delete(a), o(s);
128
+ }, s.onerror = () => {
129
+ A.delete(a), n(new Error(`이미지 로드 실패: ${a}`));
130
+ }, s.src = a;
175
131
  });
176
- loadingCache.set(src, promise);
177
- promise.then(resolve, reject);
132
+ A.set(a, i), i.then(t, e);
178
133
  });
179
134
  }
180
- function preloadImages(sources) {
181
- if (!sources || sources.length === 0) {
135
+ function z(a) {
136
+ if (!a || a.length === 0)
182
137
  return Promise.resolve([]);
183
- }
184
- const uniqueSources = [...new Set(sources)];
185
- return Promise.all(uniqueSources.map(src => preloadImage(src)));
138
+ const t = [...new Set(a)];
139
+ return Promise.all(t.map((e) => O(e)));
186
140
  }
187
- function preloadImagesInRange(items, currentIndex, range) {
188
- if (!items || items.length === 0 || range < 0) {
141
+ function X(a, t, e) {
142
+ if (!a || a.length === 0 || e < 0)
189
143
  return;
144
+ const s = a.length, i = /* @__PURE__ */ new Set();
145
+ for (let o = 1; o <= e; o++) {
146
+ const n = (t - o + s) % s, l = (t + o) % s, u = a[n]?.querySelector("img"), d = a[l]?.querySelector("img");
147
+ u && u.src && !u.complete && i.add(u.src), d && d.src && !d.complete && i.add(d.src);
190
148
  }
191
- const totalItems = items.length;
192
- const imagesToPreload = new Set();
193
- for (let distance = 1; distance <= range; distance++) {
194
- const prevIndex = (currentIndex - distance + totalItems) % totalItems;
195
- const nextIndex = (currentIndex + distance) % totalItems;
196
- const prevImg = items[prevIndex]?.querySelector('img');
197
- const nextImg = items[nextIndex]?.querySelector('img');
198
- if (prevImg && prevImg.src && !prevImg.complete) {
199
- imagesToPreload.add(prevImg.src);
200
- }
201
- if (nextImg && nextImg.src && !nextImg.complete) {
202
- imagesToPreload.add(nextImg.src);
203
- }
204
- }
205
- if (imagesToPreload.size > 0) {
206
- preloadImages([...imagesToPreload]).catch(err => {
207
- console.warn('일부 이미지 프리로드 실패:', err);
208
- });
209
- }
149
+ i.size > 0 && z([...i]).catch((o) => {
150
+ console.warn("일부 이미지 프리로드 실패:", o);
151
+ });
210
152
  }
211
-
212
- const iconCache = new Map();
213
- function createSVGIcon(path, options = {}) {
153
+ const R = /* @__PURE__ */ new Map();
154
+ function j(a, t = {}) {
214
155
  const {
215
- width = 24,
216
- height = 24,
217
- viewBox = '0 0 24 24',
218
- fill = 'none',
219
- stroke = 'currentColor',
220
- strokeWidth = 2,
221
- strokeLinecap = 'round',
222
- strokeLinejoin = 'round',
223
- className = ''
224
- } = options;
225
- const cacheKey = `${path}-${JSON.stringify(options)}`;
226
- if (iconCache.has(cacheKey)) {
227
- return iconCache.get(cacheKey);
228
- }
229
- const svg = `<svg width="${width}" height="${height}" viewBox="${viewBox}" fill="${fill}" xmlns="http://www.w3.org/2000/svg" class="${className}"><path d="${path}" stroke="${stroke}" stroke-width="${strokeWidth}" stroke-linecap="${strokeLinecap}" stroke-linejoin="${strokeLinejoin}"/></svg>`;
230
- iconCache.set(cacheKey, svg);
231
- return svg;
156
+ width: e = 24,
157
+ height: s = 24,
158
+ viewBox: i = "0 0 24 24",
159
+ fill: o = "none",
160
+ stroke: n = "currentColor",
161
+ strokeWidth: l = 2,
162
+ strokeLinecap: u = "round",
163
+ strokeLinejoin: d = "round",
164
+ className: h = ""
165
+ } = t, c = `${a}-${JSON.stringify(t)}`;
166
+ if (R.has(c))
167
+ return R.get(c);
168
+ const p = `<svg width="${e}" height="${s}" viewBox="${i}" fill="${o}" xmlns="http://www.w3.org/2000/svg" class="${h}"><path d="${a}" stroke="${n}" stroke-width="${l}" stroke-linecap="${u}" stroke-linejoin="${d}"/></svg>`;
169
+ return R.set(c, p), p;
232
170
  }
233
- const ICONS = {
171
+ const W = {
234
172
  prev: {
235
- path: 'M15 18L9 12L15 6',
173
+ path: "M15 18L9 12L15 6",
236
174
  options: {}
237
175
  },
238
176
  next: {
239
- path: 'M9 18L15 12L9 6',
177
+ path: "M9 18L15 12L9 6",
240
178
  options: {}
241
179
  },
242
180
  play: {
243
- path: 'M8 6.5v11l9-5.5z',
181
+ path: "M8 6.5v11l9-5.5z",
244
182
  options: {
245
- fill: 'currentColor',
246
- stroke: 'currentColor',
183
+ fill: "currentColor",
184
+ stroke: "currentColor",
247
185
  strokeWidth: 0,
248
- strokeLinecap: 'round',
249
- strokeLinejoin: 'round'
186
+ strokeLinecap: "round",
187
+ strokeLinejoin: "round"
250
188
  }
251
189
  },
252
190
  pause: {
253
- path: 'M7 5.5C7 5.22386 7.22386 5 7.5 5H9.5C9.77614 5 10 5.22386 10 5.5V18.5C10 18.7761 9.77614 19 9.5 19H7.5C7.22386 19 7 18.7761 7 18.5V5.5ZM14 5.5C14 5.22386 14.2239 5 14.5 5H16.5C16.7761 5 17 5.22386 17 5.5V18.5C17 18.7761 16.7761 19 16.5 19H14.5C14.2239 19 14 18.7761 14 18.5V5.5Z',
191
+ path: "M7 5.5C7 5.22386 7.22386 5 7.5 5H9.5C9.77614 5 10 5.22386 10 5.5V18.5C10 18.7761 9.77614 19 9.5 19H7.5C7.22386 19 7 18.7761 7 18.5V5.5ZM14 5.5C14 5.22386 14.2239 5 14.5 5H16.5C16.7761 5 17 5.22386 17 5.5V18.5C17 18.7761 16.7761 19 16.5 19H14.5C14.2239 19 14 18.7761 14 18.5V5.5Z",
254
192
  options: {
255
- fill: 'currentColor',
256
- stroke: 'none'
193
+ fill: "currentColor",
194
+ stroke: "none"
257
195
  }
258
196
  }
259
197
  };
260
- function getIcon(iconName, customOptions = {}) {
261
- const icon = ICONS[iconName];
262
- if (!icon) {
263
- console.warn(`PeekCarousel: 아이콘 "${iconName}"을 찾을 수 없습니다`);
264
- return '';
265
- }
266
- const options = {
267
- ...icon.options,
268
- ...customOptions
269
- };
270
- return createSVGIcon(icon.path, options);
198
+ function D(a, t = {}) {
199
+ const e = W[a];
200
+ if (!e)
201
+ return console.warn(`PeekCarousel: 아이콘 "${a}"을 찾을 수 없습니다`), "";
202
+ const s = { ...e.options, ...t };
203
+ return j(e.path, s);
271
204
  }
272
- function injectIcon(button, iconName, options = {}) {
273
- if (!button || !(button instanceof HTMLElement)) return;
274
- if (button.querySelector('svg')) {
205
+ function _(a, t, e = {}) {
206
+ if (!a || !(a instanceof HTMLElement) || a.querySelector("svg"))
275
207
  return;
276
- }
277
- const iconHTML = getIcon(iconName, options);
278
- if (iconHTML) {
279
- button.innerHTML = iconHTML;
280
- }
208
+ const s = D(t, e);
209
+ s && (a.innerHTML = s);
281
210
  }
282
- function injectAutoRotateIcons(button) {
283
- if (!button || !(button instanceof HTMLElement)) return;
284
- if (button.querySelector('svg')) {
211
+ function q(a) {
212
+ if (!a || !(a instanceof HTMLElement) || a.querySelector("svg"))
285
213
  return;
286
- }
287
- const playHTML = getIcon('play', {
288
- className: 'play-icon'
289
- });
290
- const pauseHTML = getIcon('pause', {
291
- className: 'pause-icon'
292
- });
293
- if (playHTML && pauseHTML) {
294
- button.innerHTML = playHTML + pauseHTML;
295
- }
214
+ const t = D("play", { className: "play-icon" }), e = D("pause", { className: "pause-icon" });
215
+ t && e && (a.innerHTML = t + e);
296
216
  }
297
-
298
- function isMobile() {
217
+ function F() {
299
218
  return window.innerWidth <= 768;
300
219
  }
301
- function normalizeIndex(index, length) {
302
- if (length <= 0) return 0;
303
- return (index % length + length) % length;
220
+ function y(a, t) {
221
+ return t <= 0 ? 0 : (a % t + t) % t;
304
222
  }
305
-
306
- const PROXIMITY_THRESHOLD = 2;
307
- class Navigator {
308
- constructor(carousel) {
309
- this.carousel = carousel;
223
+ const V = 2;
224
+ class K {
225
+ constructor(t) {
226
+ this.carousel = t;
310
227
  }
311
228
  get currentIndex() {
312
229
  return this.carousel.state.currentIndex;
313
230
  }
314
- set currentIndex(value) {
315
- this.carousel.state.currentIndex = normalizeIndex(value, this.carousel.totalItems);
231
+ set currentIndex(t) {
232
+ this.carousel.state.currentIndex = y(t, this.carousel.totalItems);
316
233
  }
317
- getShortestDistance(from, to) {
318
- const total = this.carousel.totalItems;
319
- const normalizedTo = normalizeIndex(to, total);
320
- const normalizedFrom = normalizeIndex(from, total);
321
- const forwardDist = (normalizedTo - normalizedFrom + total) % total;
322
- const backwardDist = (normalizedFrom - normalizedTo + total) % total;
323
- return forwardDist <= backwardDist ? forwardDist : -backwardDist;
234
+ getShortestDistance(t, e) {
235
+ const s = this.carousel.totalItems, i = y(e, s), o = y(t, s), n = (i - o + s) % s, l = (o - i + s) % s;
236
+ return n <= l ? n : -l;
324
237
  }
325
- isNearby(from, to) {
326
- const distance = Math.abs(this.getShortestDistance(from, to));
327
- return distance <= PROXIMITY_THRESHOLD;
238
+ isNearby(t, e) {
239
+ return Math.abs(this.getShortestDistance(t, e)) <= V;
328
240
  }
329
241
  updateAfterNavigation() {
330
- this.carousel.animator.updateCarousel();
331
- this.carousel.updateCounter();
332
- if (this.carousel.options.preloadRange > 0) {
333
- this.carousel.preloadImages();
334
- }
242
+ this.carousel.animator.updateCarousel(), this.carousel.updateCounter(), this.carousel.options.preloadRange > 0 && this.carousel.preloadImages();
335
243
  }
336
- rotate(direction) {
337
- this.currentIndex = this.currentIndex + direction;
338
- this.updateAfterNavigation();
244
+ rotate(t) {
245
+ this.currentIndex = this.currentIndex + t, this.updateAfterNavigation();
339
246
  }
340
247
  next() {
341
248
  this.rotate(1);
@@ -343,662 +250,432 @@ class Navigator {
343
250
  prev() {
344
251
  this.rotate(-1);
345
252
  }
346
- goTo(index) {
347
- const normalizedIndex = normalizeIndex(index, this.carousel.totalItems);
348
- if (normalizedIndex === this.currentIndex) return;
349
- this.currentIndex = normalizedIndex;
350
- this.updateAfterNavigation();
351
- }
352
- navigateIfDifferent(targetIndex, callback) {
353
- const normalizedIndex = normalizeIndex(targetIndex, this.carousel.totalItems);
354
- if (normalizedIndex === this.currentIndex) return false;
355
- callback(normalizedIndex);
356
- return true;
357
- }
358
- handleItemClick(index) {
359
- this.navigateIfDifferent(index, normalizedIndex => {
360
- const {
361
- layoutMode
362
- } = this.carousel.options;
363
- if (layoutMode === 'radial') {
364
- this.handleRadialItemClick(normalizedIndex);
365
- } else {
366
- this.handleStackItemClick(normalizedIndex);
367
- }
368
- });
253
+ goTo(t) {
254
+ const e = y(t, this.carousel.totalItems);
255
+ e !== this.currentIndex && (this.currentIndex = e, this.updateAfterNavigation());
369
256
  }
370
- handleRadialItemClick(normalizedIndex) {
371
- const shortestDist = this.getShortestDistance(this.currentIndex, normalizedIndex);
372
- if (Math.abs(shortestDist) > 1) {
373
- const direction = shortestDist > 0 ? 1 : -1;
374
- this.rotate(direction);
375
- } else {
376
- this.rotate(shortestDist);
377
- }
257
+ navigateIfDifferent(t, e) {
258
+ const s = y(t, this.carousel.totalItems);
259
+ return s === this.currentIndex ? !1 : (e(s), !0);
378
260
  }
379
- handleStackItemClick(normalizedIndex) {
380
- if (this.isNearby(this.currentIndex, normalizedIndex)) {
381
- const shortestDist = this.getShortestDistance(this.currentIndex, normalizedIndex);
382
- this.rotate(shortestDist);
383
- } else {
384
- this.goTo(normalizedIndex);
385
- }
261
+ handleItemClick(t) {
262
+ this.navigateIfDifferent(t, (e) => {
263
+ const { layoutMode: s } = this.carousel.options;
264
+ s === "radial" ? this.handleRadialItemClick(e) : this.handleStackItemClick(e);
265
+ });
386
266
  }
387
- handleIndicatorClick(index) {
388
- this.navigateIfDifferent(index, normalizedIndex => {
389
- const {
390
- layoutMode
391
- } = this.carousel.options;
392
- if (layoutMode === 'radial') {
393
- const shortestDist = this.getShortestDistance(this.currentIndex, normalizedIndex);
394
- this.rotate(shortestDist);
395
- } else {
396
- this.goTo(normalizedIndex);
397
- }
267
+ handleRadialItemClick(t) {
268
+ const e = this.getShortestDistance(this.currentIndex, t);
269
+ if (Math.abs(e) > 1) {
270
+ const s = e > 0 ? 1 : -1;
271
+ this.rotate(s);
272
+ } else
273
+ this.rotate(e);
274
+ }
275
+ handleStackItemClick(t) {
276
+ if (this.isNearby(this.currentIndex, t)) {
277
+ const e = this.getShortestDistance(this.currentIndex, t);
278
+ this.rotate(e);
279
+ } else
280
+ this.goTo(t);
281
+ }
282
+ handleIndicatorClick(t) {
283
+ this.navigateIfDifferent(t, (e) => {
284
+ const { layoutMode: s } = this.carousel.options;
285
+ if (s === "radial") {
286
+ const i = this.getShortestDistance(this.currentIndex, e);
287
+ this.rotate(i);
288
+ } else
289
+ this.goTo(e);
398
290
  });
399
291
  }
400
292
  }
401
-
402
- const RADIAL_RADIUS = 400;
403
- const CLASSIC_POSITIONS = Object.freeze({
404
- center: {
405
- x: 50,
406
- scale: 1
407
- },
408
- peek: {
409
- scale: 1
410
- },
411
- hidden: {
412
- scale: 0.85
413
- }
414
- });
415
- const CLASSIC_SPACING = Object.freeze({
293
+ const U = 400, m = Object.freeze({
294
+ center: { x: 50, scale: 1 },
295
+ peek: { scale: 1 },
296
+ hidden: { scale: 0.85 }
297
+ }), k = Object.freeze({
416
298
  gapPercent: 5,
417
299
  additionalMobile: 40,
418
300
  additionalDesktop: 15,
419
301
  mobileBreakpoint: 768
420
- });
421
- const MOMENTUM_CONFIG = Object.freeze({
302
+ }), S = Object.freeze({
422
303
  friction: 0.92,
423
304
  minVelocity: 0.05,
424
305
  navigationThreshold: 1.5,
425
306
  dampingFactor: 0.6
426
- });
427
- const STACK_POSITION_CLASSES = [CLASS_NAMES.itemCenter, CLASS_NAMES.itemPrev, CLASS_NAMES.itemNext, CLASS_NAMES.itemHidden];
428
- class Animator {
429
- constructor(carousel) {
430
- this.carousel = carousel;
431
- this.momentumAnimation = null;
432
- this.isAnimating = false;
433
- }
434
- normalizeAngleDiff(diff) {
435
- return (diff + 180) % 360 - 180;
436
- }
437
- round(value, decimals = 2) {
438
- return Math.round(value * 10 ** decimals) / 10 ** decimals;
439
- }
440
- getAdjacentIndices(currentIndex) {
307
+ }), G = [
308
+ r.itemCenter,
309
+ r.itemPrev,
310
+ r.itemNext,
311
+ r.itemHidden
312
+ ];
313
+ class Y {
314
+ constructor(t) {
315
+ this.carousel = t, this.momentumAnimation = null, this.isAnimating = !1, this.previousIndex = null;
316
+ }
317
+ normalizeAngleDiff(t) {
318
+ return (t + 180) % 360 - 180;
319
+ }
320
+ round(t, e = 2) {
321
+ return Math.round(t * 10 ** e) / 10 ** e;
322
+ }
323
+ getAdjacentIndices(t) {
441
324
  return {
442
- prev: normalizeIndex(currentIndex - 1, this.carousel.totalItems),
443
- next: normalizeIndex(currentIndex + 1, this.carousel.totalItems)
325
+ prev: y(t - 1, this.carousel.totalItems),
326
+ next: y(t + 1, this.carousel.totalItems)
444
327
  };
445
328
  }
446
- setCarouselRotation(angle) {
447
- const rounded = this.round(angle, 2);
448
- this.carousel.container.style.setProperty('--carousel-rotation', `${rounded}deg`);
329
+ setCarouselRotation(t) {
330
+ const e = this.round(t, 2);
331
+ this.carousel.container.style.setProperty("--carousel-rotation", `${e}deg`);
449
332
  }
450
- setCSSVariables(element, variables) {
451
- for (const [key, value] of Object.entries(variables)) {
452
- element.style.setProperty(key, value);
453
- }
333
+ setCSSVariables(t, e) {
334
+ for (const [s, i] of Object.entries(e))
335
+ t.style.setProperty(s, i);
454
336
  }
455
- updateRadialRotation(currentIndex) {
456
- const targetAngle = -this.carousel.state.angleUnit * currentIndex;
457
- const currentRotation = this.carousel.container.style.getPropertyValue('--carousel-rotation');
458
- if (!currentRotation || currentRotation === '0deg') {
459
- this.setCarouselRotation(targetAngle);
337
+ updateRadialRotation(t) {
338
+ const e = -this.carousel.state.angleUnit * t, s = this.carousel.container.style.getPropertyValue("--carousel-rotation");
339
+ if (!s || s === "0deg") {
340
+ this.setCarouselRotation(e);
460
341
  return;
461
342
  }
462
-
463
- // [개발참고] 최단 경로 계산: -180 ~ 180 범위로 정규화
464
- const currentAngle = parseFloat(currentRotation);
465
- const diff = this.normalizeAngleDiff(targetAngle - currentAngle);
466
- const finalAngle = currentAngle + diff;
467
- this.setCarouselRotation(finalAngle);
343
+ const i = parseFloat(s), o = this.normalizeAngleDiff(e - i), n = i + o;
344
+ this.setCarouselRotation(n);
468
345
  }
469
346
  updateCarousel() {
470
- const {
471
- currentIndex
472
- } = this.carousel.state;
473
- const {
474
- layoutMode
475
- } = this.carousel.options;
476
- if (layoutMode === 'stack' || layoutMode === 'classic') {
477
- this.setCarouselRotation(0);
478
- } else if (layoutMode === 'radial') {
479
- this.updateRadialRotation(currentIndex);
480
- }
481
- this.updateActiveItem();
347
+ const { currentIndex: t } = this.carousel.state, { layoutMode: e } = this.carousel.options;
348
+ e === "stack" || e === "classic" ? this.setCarouselRotation(0) : e === "radial" && this.updateRadialRotation(t), this.updateActiveItem();
482
349
  }
483
350
  updateActiveItem() {
484
- const {
485
- currentIndex
486
- } = this.carousel.state;
487
- const {
488
- layoutMode
489
- } = this.carousel.options;
490
- this.carousel.ui.updateActiveStates(currentIndex);
491
- if (layoutMode === 'radial') {
492
- this.updateRadialPositions(currentIndex);
493
- } else if (layoutMode === 'classic') {
494
- this.updateClassicPositions(currentIndex);
495
- } else {
496
- this.updateStackPositions(currentIndex);
497
- }
498
- }
499
- updateRadialPositions(currentIndex) {
500
- const {
501
- angleUnit
502
- } = this.carousel.state;
503
- for (let i = 0; i < this.carousel.items.length; i++) {
504
- const item = this.carousel.items[i];
505
- const angle = angleUnit * i;
506
- this.setCSSVariables(item, {
507
- '--item-angle': `${this.round(angle, 2)}deg`,
508
- '--item-radius': `${RADIAL_RADIUS}px`
351
+ const { currentIndex: t } = this.carousel.state, { layoutMode: e } = this.carousel.options;
352
+ this.carousel.ui.updateActiveStates(t), e === "radial" ? this.updateRadialPositions(t) : e === "classic" ? this.updateClassicPositions(t) : this.updateStackPositions(t);
353
+ }
354
+ updateRadialPositions(t) {
355
+ const { angleUnit: e } = this.carousel.state;
356
+ for (let o = 0; o < this.carousel.items.length; o++) {
357
+ const n = this.carousel.items[o], l = e * o;
358
+ this.setCSSVariables(n, {
359
+ "--item-angle": `${this.round(l, 2)}deg`,
360
+ "--item-radius": `${U}px`
509
361
  });
510
362
  }
511
- const {
512
- prev,
513
- next
514
- } = this.getAdjacentIndices(currentIndex);
515
- this.carousel.ui.setPeekItems(prev, next);
516
- }
517
- updateStackPositions(currentIndex) {
518
- const {
519
- prev,
520
- next
521
- } = this.getAdjacentIndices(currentIndex);
363
+ const { prev: s, next: i } = this.getAdjacentIndices(t);
364
+ this.carousel.ui.setPeekItems(s, i);
365
+ }
366
+ updateStackPositions(t) {
367
+ const { prev: e, next: s } = this.getAdjacentIndices(t);
522
368
  for (let i = 0; i < this.carousel.items.length; i++) {
523
- const item = this.carousel.items[i];
524
- item.classList.remove(...STACK_POSITION_CLASSES);
525
- if (i === currentIndex) {
526
- item.classList.add(CLASS_NAMES.itemCenter);
527
- } else if (i === prev) {
528
- item.classList.add(CLASS_NAMES.itemPrev);
529
- } else if (i === next) {
530
- item.classList.add(CLASS_NAMES.itemNext);
531
- } else {
532
- item.classList.add(CLASS_NAMES.itemHidden);
533
- }
369
+ const o = this.carousel.items[i];
370
+ o.classList.remove(...G), i === t ? o.classList.add(r.itemCenter) : i === e ? o.classList.add(r.itemPrev) : i === s ? o.classList.add(r.itemNext) : o.classList.add(r.itemHidden);
534
371
  }
535
372
  }
536
- calculateClassicSpacing(containerWidth) {
537
- const itemWidth = Math.max(300, Math.min(containerWidth * 0.35, 500));
538
- const isMobile = containerWidth <= CLASSIC_SPACING.mobileBreakpoint;
539
- const itemHalfPercent = itemWidth / containerWidth * 50;
540
- const baseSpacing = itemHalfPercent + CLASSIC_SPACING.gapPercent;
541
- const additionalSpacing = isMobile ? CLASSIC_SPACING.additionalMobile : CLASSIC_SPACING.additionalDesktop;
542
- return baseSpacing + additionalSpacing;
543
- }
544
- getClassicItemPosition(itemIndex, currentIndex, itemSpacing) {
545
- const {
546
- prev,
547
- next
548
- } = this.getAdjacentIndices(currentIndex);
549
- if (itemIndex === currentIndex) {
373
+ calculateClassicSpacing(t) {
374
+ const e = Math.max(300, Math.min(t * 0.35, 500)), s = t <= k.mobileBreakpoint, o = e / t * 50 + k.gapPercent, n = s ? k.additionalMobile : k.additionalDesktop;
375
+ return o + n;
376
+ }
377
+ // ==========================================
378
+ // Classic Mode - Seamless Infinite Scroll
379
+ // ==========================================
380
+ getWrapInfo(t, e) {
381
+ if (t === null) return { isWrap: !1, direction: 0 };
382
+ const s = this.carousel.totalItems, i = t === s - 1 && e === 0, o = t === 0 && e === s - 1;
383
+ return i ? { isWrap: !0, direction: 1 } : o ? { isWrap: !0, direction: -1 } : { isWrap: !1, direction: e > t ? 1 : -1 };
384
+ }
385
+ getClassicItemPosition(t, e, s, i = 0) {
386
+ const { prev: o, next: n } = this.getAdjacentIndices(e), l = this.carousel.totalItems;
387
+ if (t === e)
550
388
  return {
551
- x: CLASSIC_POSITIONS.center.x,
552
- scale: CLASSIC_POSITIONS.center.scale
389
+ x: m.center.x,
390
+ scale: m.center.scale,
391
+ isCenter: !0
553
392
  };
554
- }
555
- if (itemIndex === prev) {
393
+ if (t === o)
556
394
  return {
557
- x: CLASSIC_POSITIONS.center.x - itemSpacing,
558
- scale: CLASSIC_POSITIONS.peek.scale
395
+ x: m.center.x - s,
396
+ scale: m.peek.scale,
397
+ isPrev: !0
559
398
  };
560
- }
561
- if (itemIndex === next) {
399
+ if (t === n)
562
400
  return {
563
- x: CLASSIC_POSITIONS.center.x + itemSpacing,
564
- scale: CLASSIC_POSITIONS.peek.scale
401
+ x: m.center.x + s,
402
+ scale: m.peek.scale,
403
+ isNext: !0
565
404
  };
566
- }
567
- const distanceFromCurrent = itemIndex - currentIndex;
405
+ const u = (t - e + l) % l, d = (e - t + l) % l;
568
406
  return {
569
- x: distanceFromCurrent < 0 ? CLASSIC_POSITIONS.center.x - itemSpacing * 2 : CLASSIC_POSITIONS.center.x + itemSpacing * 2,
570
- scale: CLASSIC_POSITIONS.hidden.scale
407
+ x: u < d ? m.center.x + s * 2 : m.center.x - s * 2,
408
+ scale: m.hidden.scale,
409
+ isHidden: !0
571
410
  };
572
411
  }
573
- updateClassicPositions(currentIndex) {
574
- const {
575
- prev,
576
- next
577
- } = this.getAdjacentIndices(currentIndex);
578
- const containerWidth = this.carousel.container.offsetWidth;
579
- const itemSpacing = this.calculateClassicSpacing(containerWidth);
580
- for (let i = 0; i < this.carousel.items.length; i++) {
581
- const item = this.carousel.items[i];
582
- const {
583
- x,
584
- scale
585
- } = this.getClassicItemPosition(i, currentIndex, itemSpacing);
586
- this.setCSSVariables(item, {
587
- '--item-x': `${this.round(x, 2)}%`,
588
- '--item-scale': String(scale)
589
- });
590
- }
591
- this.carousel.ui.setPeekItems(prev, next);
592
- }
593
- startMomentum(velocity) {
412
+ updateClassicPositions(t) {
413
+ const { prev: e, next: s } = this.getAdjacentIndices(t), i = this.carousel.container.offsetWidth, o = this.calculateClassicSpacing(i), { isWrap: n, direction: l } = this.getWrapInfo(this.previousIndex, t), u = this.carousel.items, d = this.previousIndex !== null ? this.getAdjacentIndices(this.previousIndex) : { prev: null, next: null };
414
+ if (n) {
415
+ const h = new Set([
416
+ t,
417
+ e,
418
+ s,
419
+ this.previousIndex,
420
+ d.prev,
421
+ d.next
422
+ ].filter((c) => c !== null));
423
+ for (let c = 0; c < u.length; c++)
424
+ h.has(c) || (u[c].style.transition = "none");
425
+ this.carousel.container.offsetHeight;
426
+ }
427
+ for (let h = 0; h < u.length; h++) {
428
+ const c = u[h], p = this.getClassicItemPosition(h, t, o);
429
+ this.setCSSVariables(c, {
430
+ "--item-x": `${this.round(p.x, 2)}%`,
431
+ "--item-scale": String(p.scale)
432
+ }), p.isCenter ? (c.style.opacity = "1", c.style.visibility = "visible", c.style.zIndex = "100") : p.isPrev || p.isNext ? (c.style.opacity = "0.6", c.style.visibility = "visible", c.style.zIndex = "50") : (c.style.opacity = "0", c.style.visibility = "hidden", c.style.zIndex = "0");
433
+ }
434
+ n && requestAnimationFrame(() => {
435
+ for (let h = 0; h < u.length; h++)
436
+ u[h].style.transition = "";
437
+ }), this.previousIndex = t, this.carousel.ui.setPeekItems(e, s);
438
+ }
439
+ // ==========================================
440
+ // Momentum
441
+ // ==========================================
442
+ startMomentum(t) {
594
443
  this.stopMomentum();
595
- let currentVelocity = velocity;
596
- const momentumStep = () => {
597
- currentVelocity *= MOMENTUM_CONFIG.friction;
598
- if (Math.abs(currentVelocity) < MOMENTUM_CONFIG.minVelocity) {
444
+ let e = t;
445
+ const s = () => {
446
+ if (e *= S.friction, Math.abs(e) < S.minVelocity) {
599
447
  this.stopMomentum();
600
448
  return;
601
449
  }
602
- if (Math.abs(currentVelocity) > MOMENTUM_CONFIG.navigationThreshold) {
603
- const direction = currentVelocity > 0 ? -1 : 1;
604
- this.carousel.navigator.rotate(direction);
605
- currentVelocity *= MOMENTUM_CONFIG.dampingFactor;
450
+ if (Math.abs(e) > S.navigationThreshold) {
451
+ const i = e > 0 ? -1 : 1;
452
+ this.carousel.navigator.rotate(i), e *= S.dampingFactor;
606
453
  }
607
- this.momentumAnimation = requestAnimationFrame(momentumStep);
454
+ this.momentumAnimation = requestAnimationFrame(s);
608
455
  };
609
- this.isAnimating = true;
610
- this.momentumAnimation = requestAnimationFrame(momentumStep);
456
+ this.isAnimating = !0, this.momentumAnimation = requestAnimationFrame(s);
611
457
  }
612
458
  stopMomentum() {
613
- if (this.momentumAnimation) {
614
- cancelAnimationFrame(this.momentumAnimation);
615
- this.momentumAnimation = null;
616
- }
617
- this.isAnimating = false;
459
+ this.momentumAnimation && (cancelAnimationFrame(this.momentumAnimation), this.momentumAnimation = null), this.isAnimating = !1;
618
460
  }
619
461
  }
620
-
621
- class AutoRotate {
622
- constructor(carousel) {
623
- this.carousel = carousel;
624
- this.interval = null;
625
- this.isActive = false;
462
+ class Z {
463
+ constructor(t) {
464
+ this.carousel = t, this.interval = null, this.isActive = !1;
626
465
  }
627
- setActiveState(isActive) {
628
- this.isActive = isActive;
629
- this.carousel.ui.updateAutoRotateButton(isActive);
466
+ setActiveState(t) {
467
+ this.isActive = t, this.carousel.ui.updateAutoRotateButton(t);
630
468
  }
631
469
  toggle() {
632
470
  this.isActive ? this.stop() : this.start();
633
471
  }
634
472
  start() {
635
473
  if (this.isActive) return;
636
- this.setActiveState(true);
637
- const rotateInterval = this.carousel.options.autoRotateInterval;
474
+ this.setActiveState(!0);
475
+ const t = this.carousel.options.autoRotateInterval;
638
476
  this.interval = setInterval(() => {
639
477
  this.carousel.navigator.next();
640
- }, rotateInterval);
478
+ }, t);
641
479
  }
642
480
  stop() {
643
- if (!this.isActive) return;
644
- this.setActiveState(false);
645
- if (this.interval) {
646
- clearInterval(this.interval);
647
- this.interval = null;
648
- }
481
+ this.isActive && (this.setActiveState(!1), this.interval && (clearInterval(this.interval), this.interval = null));
649
482
  }
650
483
  destroy() {
651
- this.stop();
652
- this.carousel = null;
484
+ this.stop(), this.carousel = null;
653
485
  }
654
486
  }
655
-
656
- const WHEEL_CONFIG = Object.freeze({
487
+ const x = Object.freeze({
657
488
  threshold: 50,
658
489
  timeout: 150,
659
490
  cooldown: 100
660
- });
661
- const DRAG_CONFIG = Object.freeze({
491
+ }), w = Object.freeze({
662
492
  touchThreshold: 15,
663
493
  mouseThreshold: 10,
664
494
  velocityThreshold: 0.5
665
- });
666
- const RESIZE_DEBOUNCE = 100;
667
- class EventHandler {
668
- constructor(carousel) {
669
- this.carousel = carousel;
670
- this.boundHandlers = new Map();
671
- this.touch = {
495
+ }), J = 100;
496
+ let Q = 0;
497
+ class tt {
498
+ constructor(t) {
499
+ this.carousel = t, this.boundHandlers = /* @__PURE__ */ new Map(), this.resizeTimer = null, this.touch = {
672
500
  startX: 0,
673
501
  endX: 0
674
- };
675
- this.drag = {
676
- active: false,
502
+ }, this.drag = {
503
+ active: !1,
677
504
  startX: 0,
678
505
  currentX: 0,
679
506
  lastX: 0,
680
507
  lastTime: 0,
681
508
  velocity: 0
682
- };
683
- this.wheel = {
684
- isScrolling: false,
509
+ }, this.wheel = {
510
+ isScrolling: !1,
685
511
  scrollTimeout: null,
686
512
  lastWheelTime: 0,
687
513
  accumulatedDelta: 0
688
514
  };
689
515
  }
690
516
  init() {
691
- this.initNavigationButtons();
692
- this.initKeyboard();
693
- this.initWheel();
694
- this.initItemClick();
695
- this.initIndicatorClick();
696
- this.initTouch();
697
- this.initMouse();
698
- this.initResize();
699
- }
700
- stopAutoRotateAndNavigate(navigationFn) {
701
- this.completeCurrentIndicator();
702
- this.carousel.autoRotate.stop();
703
- navigationFn();
517
+ this.initNavigationButtons(), this.initKeyboard(), this.initWheel(), this.initItemClick(), this.initIndicatorClick(), this.initTouch(), this.initMouse(), this.initResize();
518
+ }
519
+ stopAutoRotateAndNavigate(t) {
520
+ this.completeCurrentIndicator(), this.carousel.autoRotate.stop(), t();
704
521
  }
705
522
  completeCurrentIndicator() {
706
- const currentIndicator = this.carousel.indicators[this.carousel.state.currentIndex];
707
- if (currentIndicator && currentIndicator.classList.contains('peek-carousel__indicator--active')) {
708
- currentIndicator.classList.add('peek-carousel__indicator--completed');
709
- }
523
+ const t = this.carousel.indicators[this.carousel.state.currentIndex];
524
+ t && t.classList.contains("peek-carousel__indicator--active") && t.classList.add("peek-carousel__indicator--completed");
710
525
  }
711
- resetDragState(index) {
712
- this.carousel.ui.removeDraggingClass(index);
713
- this.carousel.ui.clearDragTransform();
526
+ resetDragState(t) {
527
+ this.carousel.ui.removeDraggingClass(t), this.carousel.ui.clearDragTransform();
714
528
  }
715
- updateDraggingClass(dragDistance, currentIndex, threshold) {
716
- if (dragDistance > threshold) {
717
- this.carousel.ui.addDraggingClass(currentIndex, 'right');
718
- } else if (dragDistance < -threshold) {
719
- this.carousel.ui.addDraggingClass(currentIndex, 'left');
720
- }
529
+ updateDraggingClass(t, e, s) {
530
+ t > s ? this.carousel.ui.addDraggingClass(e, "right") : t < -s && this.carousel.ui.addDraggingClass(e, "left");
721
531
  }
722
- initDragState(clientX) {
723
- this.drag.active = true;
724
- this.drag.startX = clientX;
725
- this.drag.currentX = clientX;
726
- this.drag.lastX = clientX;
727
- this.drag.lastTime = Date.now();
728
- this.drag.velocity = 0;
532
+ initDragState(t) {
533
+ this.drag.active = !0, this.drag.startX = t, this.drag.currentX = t, this.drag.lastX = t, this.drag.lastTime = Date.now(), this.drag.velocity = 0;
729
534
  }
730
535
  resetMouseCursor() {
731
- this.carousel.elements.carousel.style.cursor = 'grab';
536
+ this.carousel.elements.carousel.style.cursor = "grab";
732
537
  }
733
- calculateWheelDelta(e) {
734
- const deltaX = Math.abs(e.deltaX);
735
- const deltaY = Math.abs(e.deltaY);
736
- const isHorizontal = deltaX > deltaY;
737
-
738
- // [개발참고] 수평: 왼쪽(-) = 다음, 오른쪽(+) = 이전
739
- // 수직: 아래(+) = 다음, 위(-) = 이전
740
- return isHorizontal ? -e.deltaX : e.deltaY;
538
+ calculateWheelDelta(t) {
539
+ const e = Math.abs(t.deltaX), s = Math.abs(t.deltaY);
540
+ return e > s ? -t.deltaX : t.deltaY;
741
541
  }
742
542
  resetWheelState() {
743
- this.wheel.isScrolling = false;
744
- this.wheel.accumulatedDelta = 0;
543
+ this.wheel.isScrolling = !1, this.wheel.accumulatedDelta = 0;
745
544
  }
746
545
  initNavigationButtons() {
747
- const {
748
- prevBtn,
749
- nextBtn,
750
- autoRotateBtn
751
- } = this.carousel.elements;
752
- if (prevBtn) {
753
- this.addHandler(prevBtn, 'click', () => {
754
- this.stopAutoRotateAndNavigate(() => this.carousel.navigator.prev());
755
- });
756
- }
757
- if (nextBtn) {
758
- this.addHandler(nextBtn, 'click', () => {
759
- this.stopAutoRotateAndNavigate(() => this.carousel.navigator.next());
760
- });
761
- }
762
- if (autoRotateBtn) {
763
- this.addHandler(autoRotateBtn, 'click', () => {
764
- this.carousel.autoRotate.toggle();
765
- });
766
- }
546
+ const { prevBtn: t, nextBtn: e, autoRotateBtn: s } = this.carousel.elements;
547
+ t && this.addHandler(t, "click", () => {
548
+ this.stopAutoRotateAndNavigate(() => this.carousel.navigator.prev());
549
+ }), e && this.addHandler(e, "click", () => {
550
+ this.stopAutoRotateAndNavigate(() => this.carousel.navigator.next());
551
+ }), s && this.addHandler(s, "click", () => {
552
+ this.carousel.autoRotate.toggle();
553
+ });
767
554
  }
768
555
  initKeyboard() {
769
556
  if (!this.carousel.options.enableKeyboard) return;
770
- const handler = e => {
771
- const {
772
- navigator,
773
- autoRotate,
774
- totalItems
775
- } = this.carousel;
557
+ const t = (e) => {
558
+ const { navigator: s, autoRotate: i, totalItems: o } = this.carousel;
776
559
  switch (e.key) {
777
- case KEYS.arrowLeft:
778
- autoRotate.stop();
779
- navigator.prev();
560
+ case b.arrowLeft:
561
+ i.stop(), s.prev();
780
562
  break;
781
- case KEYS.arrowRight:
782
- autoRotate.stop();
783
- navigator.next();
563
+ case b.arrowRight:
564
+ i.stop(), s.next();
784
565
  break;
785
- case KEYS.home:
786
- e.preventDefault();
787
- autoRotate.stop();
788
- navigator.goTo(0);
566
+ case b.home:
567
+ e.preventDefault(), i.stop(), s.goTo(0);
789
568
  break;
790
- case KEYS.end:
791
- e.preventDefault();
792
- autoRotate.stop();
793
- navigator.goTo(totalItems - 1);
569
+ case b.end:
570
+ e.preventDefault(), i.stop(), s.goTo(o - 1);
794
571
  break;
795
- case KEYS.space:
796
- e.preventDefault();
797
- autoRotate.toggle();
572
+ case b.space:
573
+ e.preventDefault(), i.toggle();
798
574
  break;
799
575
  default:
800
- const numKey = parseInt(e.key);
801
- if (numKey >= 1 && numKey <= totalItems) {
802
- e.preventDefault();
803
- autoRotate.stop();
804
- navigator.goTo(numKey - 1);
805
- }
576
+ const n = parseInt(e.key);
577
+ n >= 1 && n <= o && (e.preventDefault(), i.stop(), s.goTo(n - 1));
806
578
  }
807
579
  };
808
- this.addHandler(document, 'keydown', handler);
580
+ this.addHandler(document, "keydown", t);
809
581
  }
810
582
  initWheel() {
811
583
  if (!this.carousel.options.enableWheel) return;
812
- const handler = e => {
813
- const deltaX = Math.abs(e.deltaX);
814
- const deltaY = Math.abs(e.deltaY);
815
- if (deltaX < 1 && deltaY < 1) {
584
+ const t = (e) => {
585
+ const s = Math.abs(e.deltaX), i = Math.abs(e.deltaY);
586
+ if (s < 1 && i < 1 || s === i)
816
587
  return;
817
- }
818
- if (deltaX === deltaY) {
819
- return;
820
- }
821
588
  e.preventDefault();
822
- const currentTime = Date.now();
823
- if (currentTime - this.wheel.lastWheelTime < WHEEL_CONFIG.cooldown) {
824
- return;
589
+ const o = Date.now();
590
+ if (!(o - this.wheel.lastWheelTime < x.cooldown)) {
591
+ if (this.wheel.isScrolling || (this.wheel.isScrolling = !0, this.wheel.accumulatedDelta = 0, this.carousel.autoRotate.stop(), this.carousel.animator.stopMomentum()), this.wheel.accumulatedDelta += this.calculateWheelDelta(e), Math.abs(this.wheel.accumulatedDelta) >= x.threshold) {
592
+ const n = this.wheel.accumulatedDelta > 0 ? 1 : -1;
593
+ this.carousel.navigator.rotate(n), this.wheel.accumulatedDelta = 0, this.wheel.lastWheelTime = o;
594
+ }
595
+ clearTimeout(this.wheel.scrollTimeout), this.wheel.scrollTimeout = setTimeout(() => {
596
+ this.resetWheelState();
597
+ }, x.timeout);
825
598
  }
826
- if (!this.wheel.isScrolling) {
827
- this.wheel.isScrolling = true;
828
- this.wheel.accumulatedDelta = 0;
829
- this.carousel.autoRotate.stop();
830
- this.carousel.animator.stopMomentum();
831
- }
832
- this.wheel.accumulatedDelta += this.calculateWheelDelta(e);
833
- if (Math.abs(this.wheel.accumulatedDelta) >= WHEEL_CONFIG.threshold) {
834
- const direction = this.wheel.accumulatedDelta > 0 ? 1 : -1;
835
- this.carousel.navigator.rotate(direction);
836
- this.wheel.accumulatedDelta = 0;
837
- this.wheel.lastWheelTime = currentTime;
838
- }
839
- clearTimeout(this.wheel.scrollTimeout);
840
- this.wheel.scrollTimeout = setTimeout(() => {
841
- this.resetWheelState();
842
- }, WHEEL_CONFIG.timeout);
843
599
  };
844
- this.addHandler(this.carousel.elements.carousel, 'wheel', handler, {
845
- passive: false
846
- });
600
+ this.addHandler(
601
+ this.carousel.elements.carousel,
602
+ "wheel",
603
+ t,
604
+ { passive: !1 }
605
+ );
847
606
  }
848
607
  initItemClick() {
849
- const {
850
- items
851
- } = this.carousel;
852
- for (let i = 0; i < items.length; i++) {
853
- this.addHandler(items[i], 'click', () => {
854
- this.carousel.autoRotate.stop();
855
- this.carousel.navigator.handleItemClick(i);
608
+ const { items: t } = this.carousel;
609
+ for (let e = 0; e < t.length; e++)
610
+ this.addHandler(t[e], "click", () => {
611
+ this.carousel.autoRotate.stop(), this.carousel.navigator.handleItemClick(e);
856
612
  });
857
- }
858
613
  }
859
614
  initIndicatorClick() {
860
- const {
861
- indicators
862
- } = this.carousel;
863
- for (let i = 0; i < indicators.length; i++) {
864
- this.addHandler(indicators[i], 'click', () => {
865
- this.carousel.autoRotate.stop();
866
- this.carousel.navigator.handleIndicatorClick(i);
615
+ const { indicators: t } = this.carousel;
616
+ for (let e = 0; e < t.length; e++)
617
+ this.addHandler(t[e], "click", () => {
618
+ this.carousel.autoRotate.stop(), this.carousel.navigator.handleIndicatorClick(e);
867
619
  });
868
- }
869
620
  }
870
621
  initTouch() {
871
- if (!this.carousel.options.enableTouch) return;
872
- this.addHandler(this.carousel.elements.carousel, 'touchstart', e => {
873
- this.touch.startX = e.changedTouches[0].screenX;
874
- });
875
- this.addHandler(this.carousel.elements.carousel, 'touchmove', e => {
876
- const touchCurrentX = e.changedTouches[0].screenX;
877
- const dragDistance = touchCurrentX - this.touch.startX;
878
- const {
879
- currentIndex
880
- } = this.carousel.state;
881
- this.carousel.ui.updateDragTransform(dragDistance);
882
- this.updateDraggingClass(dragDistance, currentIndex, DRAG_CONFIG.touchThreshold);
883
- });
884
- this.addHandler(this.carousel.elements.carousel, 'touchend', e => {
885
- this.touch.endX = e.changedTouches[0].screenX;
886
- const swipeDistance = this.touch.endX - this.touch.startX;
887
- const {
888
- swipeThreshold
889
- } = this.carousel.options;
890
- const {
891
- currentIndex
892
- } = this.carousel.state;
893
- this.resetDragState(currentIndex);
894
- if (swipeDistance < -swipeThreshold) {
895
- this.carousel.autoRotate.stop();
896
- this.carousel.navigator.next();
897
- } else if (swipeDistance > swipeThreshold) {
898
- this.carousel.autoRotate.stop();
899
- this.carousel.navigator.prev();
900
- }
901
- });
622
+ this.carousel.options.enableTouch && (this.addHandler(this.carousel.elements.carousel, "touchstart", (t) => {
623
+ this.touch.startX = t.changedTouches[0].screenX;
624
+ }), this.addHandler(this.carousel.elements.carousel, "touchmove", (t) => {
625
+ const s = t.changedTouches[0].screenX - this.touch.startX, { currentIndex: i } = this.carousel.state;
626
+ this.carousel.ui.updateDragTransform(s), this.updateDraggingClass(s, i, w.touchThreshold);
627
+ }), this.addHandler(this.carousel.elements.carousel, "touchend", (t) => {
628
+ this.touch.endX = t.changedTouches[0].screenX;
629
+ const e = this.touch.endX - this.touch.startX, { swipeThreshold: s } = this.carousel.options, { currentIndex: i } = this.carousel.state;
630
+ this.resetDragState(i), e < -s ? (this.carousel.autoRotate.stop(), this.carousel.navigator.next()) : e > s && (this.carousel.autoRotate.stop(), this.carousel.navigator.prev());
631
+ }));
902
632
  }
903
633
  initMouse() {
904
- if (!this.carousel.options.enableMouse) return;
905
- this.addHandler(this.carousel.elements.carousel, 'mousedown', e => {
906
- if (isMobile()) return;
907
- this.initDragState(e.clientX);
908
- this.carousel.autoRotate.stop();
909
- this.carousel.animator.stopMomentum();
910
- this.carousel.elements.carousel.style.cursor = 'grabbing';
911
- e.preventDefault();
912
- });
913
- this.addHandler(document, 'mousemove', e => {
634
+ this.carousel.options.enableMouse && (this.addHandler(this.carousel.elements.carousel, "mousedown", (t) => {
635
+ F() || (this.initDragState(t.clientX), this.carousel.autoRotate.stop(), this.carousel.animator.stopMomentum(), this.carousel.elements.carousel.style.cursor = "grabbing", t.preventDefault());
636
+ }), this.addHandler(document, "mousemove", (t) => {
914
637
  if (!this.drag.active) return;
915
- const currentTime = Date.now();
916
- const deltaTime = currentTime - this.drag.lastTime;
917
- const deltaX = e.clientX - this.drag.lastX;
918
- if (deltaTime > 0) {
919
- this.drag.velocity = deltaX / deltaTime;
920
- }
921
- this.drag.currentX = e.clientX;
922
- this.drag.lastX = e.clientX;
923
- this.drag.lastTime = currentTime;
924
- const dragDistance = this.drag.currentX - this.drag.startX;
925
- const {
926
- currentIndex
927
- } = this.carousel.state;
928
- this.carousel.ui.updateDragTransform(dragDistance);
929
- this.updateDraggingClass(dragDistance, currentIndex, DRAG_CONFIG.mouseThreshold);
930
- if (Math.abs(dragDistance) > this.carousel.options.dragThreshold) {
931
- const direction = dragDistance > 0 ? -1 : 1;
932
- this.carousel.navigator.rotate(direction);
933
- this.drag.startX = this.drag.currentX;
934
- this.resetDragState(currentIndex);
638
+ const e = Date.now(), s = e - this.drag.lastTime, i = t.clientX - this.drag.lastX;
639
+ s > 0 && (this.drag.velocity = i / s), this.drag.currentX = t.clientX, this.drag.lastX = t.clientX, this.drag.lastTime = e;
640
+ const o = this.drag.currentX - this.drag.startX, { currentIndex: n } = this.carousel.state;
641
+ if (this.carousel.ui.updateDragTransform(o), this.updateDraggingClass(o, n, w.mouseThreshold), Math.abs(o) > this.carousel.options.dragThreshold) {
642
+ const l = o > 0 ? -1 : 1;
643
+ this.carousel.navigator.rotate(l), this.drag.startX = this.drag.currentX, this.resetDragState(n);
935
644
  }
936
- });
937
- this.addHandler(document, 'mouseup', () => {
645
+ }), this.addHandler(document, "mouseup", () => {
938
646
  if (!this.drag.active) return;
939
- this.drag.active = false;
940
- this.resetMouseCursor();
941
- const {
942
- currentIndex
943
- } = this.carousel.state;
944
- this.resetDragState(currentIndex);
945
- if (Math.abs(this.drag.velocity) > DRAG_CONFIG.velocityThreshold) {
946
- this.carousel.animator.startMomentum(this.drag.velocity);
947
- }
948
- });
949
- this.addHandler(this.carousel.elements.carousel, 'mouseleave', () => {
647
+ this.drag.active = !1, this.resetMouseCursor();
648
+ const { currentIndex: t } = this.carousel.state;
649
+ this.resetDragState(t), Math.abs(this.drag.velocity) > w.velocityThreshold && this.carousel.animator.startMomentum(this.drag.velocity);
650
+ }), this.addHandler(this.carousel.elements.carousel, "mouseleave", () => {
950
651
  if (this.drag.active) {
951
- this.drag.active = false;
952
- this.resetMouseCursor();
953
- const {
954
- currentIndex
955
- } = this.carousel.state;
956
- this.resetDragState(currentIndex);
652
+ this.drag.active = !1, this.resetMouseCursor();
653
+ const { currentIndex: t } = this.carousel.state;
654
+ this.resetDragState(t);
957
655
  }
958
- });
959
- if (window.innerWidth > BREAKPOINTS.mobile) {
960
- this.resetMouseCursor();
961
- }
656
+ }), window.innerWidth > H.mobile && this.resetMouseCursor());
962
657
  }
963
658
  initResize() {
964
- let resizeTimer;
965
- const handler = () => {
966
- clearTimeout(resizeTimer);
967
- resizeTimer = setTimeout(() => {
968
- this.carousel.animator.updateCarousel();
969
- }, RESIZE_DEBOUNCE);
659
+ const t = () => {
660
+ clearTimeout(this.resizeTimer), this.resizeTimer = setTimeout(() => {
661
+ this.carousel && this.carousel.animator.updateCarousel();
662
+ }, J);
970
663
  };
971
- this.addHandler(window, 'resize', handler);
972
- }
973
- addHandler(element, event, handler, options) {
974
- element.addEventListener(event, handler, options);
975
- const key = `${event}-${Date.now()}-${Math.random()}`;
976
- this.boundHandlers.set(key, {
977
- element,
978
- event,
979
- handler,
980
- options
981
- });
664
+ this.addHandler(window, "resize", t);
665
+ }
666
+ addHandler(t, e, s, i) {
667
+ t.addEventListener(e, s, i);
668
+ const o = `${e}-${++Q}`;
669
+ this.boundHandlers.set(o, { element: t, event: e, handler: s, options: i });
982
670
  }
983
671
  destroy() {
984
- if (this.wheel.scrollTimeout) {
985
- clearTimeout(this.wheel.scrollTimeout);
986
- this.wheel.scrollTimeout = null;
987
- }
988
- for (const {
989
- element,
990
- event,
991
- handler,
992
- options
993
- } of this.boundHandlers.values()) {
994
- element.removeEventListener(event, handler, options);
995
- }
996
- this.boundHandlers.clear();
997
- this.carousel = null;
672
+ this.wheel.scrollTimeout && (clearTimeout(this.wheel.scrollTimeout), this.wheel.scrollTimeout = null), this.resizeTimer && (clearTimeout(this.resizeTimer), this.resizeTimer = null);
673
+ for (const { element: t, event: e, handler: s, options: i } of this.boundHandlers.values())
674
+ t.removeEventListener(e, s, i);
675
+ this.boundHandlers.clear(), this.drag.active = !1, this.drag.velocity = 0, this.wheel.isScrolling = !1, this.wheel.accumulatedDelta = 0, this.carousel = null;
998
676
  }
999
677
  }
1000
-
1001
- const DRAG_TRANSFORM_CONFIG = Object.freeze({
678
+ const T = Object.freeze({
1002
679
  stack: {
1003
680
  maxDrag: 200,
1004
681
  offsetMultiplier: 100,
@@ -1011,326 +688,195 @@ const DRAG_TRANSFORM_CONFIG = Object.freeze({
1011
688
  dragSensitivity: 0.5
1012
689
  }
1013
690
  });
1014
- class UIManager {
1015
- constructor(carousel) {
1016
- this.carousel = carousel;
691
+ class et {
692
+ constructor(t) {
693
+ this.carousel = t;
1017
694
  }
1018
- updateActiveStates(currentIndex) {
695
+ updateActiveStates(t) {
1019
696
  for (let i = 0; i < this.carousel.items.length; i++) {
1020
- const item = this.carousel.items[i];
1021
- removeClass(item, CLASS_NAMES.itemActive, CLASS_NAMES.itemPrev, CLASS_NAMES.itemNext);
1022
- item.removeAttribute(ARIA.current);
697
+ const o = this.carousel.items[i];
698
+ v(o, r.itemActive, r.itemPrev, r.itemNext), o.removeAttribute(g.current);
1023
699
  }
1024
700
  for (let i = 0; i < this.carousel.indicators.length; i++) {
1025
- const indicator = this.carousel.indicators[i];
1026
- removeClass(indicator, CLASS_NAMES.indicatorActive, CLASS_NAMES.indicatorProgress);
1027
- setAttribute(indicator, ARIA.selected, 'false');
1028
- setAttribute(indicator, ARIA.tabindex, '-1');
1029
- }
1030
- const currentItem = this.carousel.items[currentIndex];
1031
- const currentIndicator = this.carousel.indicators[currentIndex];
1032
- if (currentItem) {
1033
- addClass(currentItem, CLASS_NAMES.itemActive);
1034
- setAttribute(currentItem, ARIA.current, 'true');
1035
- }
1036
- if (currentIndicator) {
1037
- removeClass(currentIndicator, CLASS_NAMES.indicatorCompleted);
1038
- addClass(currentIndicator, CLASS_NAMES.indicatorActive);
1039
- setAttribute(currentIndicator, ARIA.selected, 'true');
1040
- setAttribute(currentIndicator, ARIA.tabindex, '0');
1041
- if (this.carousel.autoRotate.isActive) {
1042
- this.updateIndicatorProgress(currentIndicator);
1043
- }
1044
- }
1045
- }
1046
- updateIndicatorProgress(indicator) {
1047
- setCSSVar(indicator, '--progress-duration', `${this.carousel.options.autoRotateInterval}ms`);
1048
- setTimeout(() => {
1049
- if (indicator) {
1050
- addClass(indicator, CLASS_NAMES.indicatorProgress);
1051
- }
1052
- }, DURATIONS.progressReset);
701
+ const o = this.carousel.indicators[i];
702
+ v(
703
+ o,
704
+ r.indicatorActive,
705
+ r.indicatorProgress
706
+ ), I(o, g.selected, "false"), I(o, g.tabindex, "-1");
707
+ }
708
+ const e = this.carousel.items[t], s = this.carousel.indicators[t];
709
+ e && (f(e, r.itemActive), I(e, g.current, "true")), s && (v(s, r.indicatorCompleted), f(s, r.indicatorActive), I(s, g.selected, "true"), I(s, g.tabindex, "0"), this.carousel.autoRotate.isActive && this.updateIndicatorProgress(s));
710
+ }
711
+ updateIndicatorProgress(t) {
712
+ B(
713
+ t,
714
+ "--progress-duration",
715
+ `${this.carousel.options.autoRotateInterval}ms`
716
+ ), setTimeout(() => {
717
+ t && f(t, r.indicatorProgress);
718
+ }, E.progressReset);
1053
719
  }
1054
720
  clearPeekItems() {
1055
- for (let i = 0; i < this.carousel.items.length; i++) {
1056
- const item = this.carousel.items[i];
1057
- removeClass(item, CLASS_NAMES.itemPrev, CLASS_NAMES.itemNext);
721
+ for (let t = 0; t < this.carousel.items.length; t++) {
722
+ const e = this.carousel.items[t];
723
+ v(e, r.itemPrev, r.itemNext);
1058
724
  }
1059
725
  }
1060
- setPeekItems(prevIndex, nextIndex) {
1061
- const prevItem = this.carousel.items[prevIndex];
1062
- const nextItem = this.carousel.items[nextIndex];
1063
- if (prevItem) addClass(prevItem, CLASS_NAMES.itemPrev);
1064
- if (nextItem) addClass(nextItem, CLASS_NAMES.itemNext);
1065
- }
1066
- updateAutoRotateButton(isActive) {
1067
- const {
1068
- autoRotateBtn
1069
- } = this.carousel.elements;
1070
- if (!autoRotateBtn) return;
1071
- if (isActive) {
1072
- addClass(autoRotateBtn, CLASS_NAMES.btnActive);
1073
- setAttribute(autoRotateBtn, ARIA.pressed, 'true');
1074
- } else {
1075
- removeClass(autoRotateBtn, CLASS_NAMES.btnActive);
1076
- setAttribute(autoRotateBtn, ARIA.pressed, 'false');
1077
- }
726
+ setPeekItems(t, e) {
727
+ const s = this.carousel.items[t], i = this.carousel.items[e];
728
+ s && f(s, r.itemPrev), i && f(i, r.itemNext);
1078
729
  }
1079
- addDraggingClass(index, direction) {
1080
- const item = this.carousel.items[index];
1081
- if (!item) return;
1082
- const leftClass = CLASS_NAMES.itemDraggingLeft;
1083
- const rightClass = CLASS_NAMES.itemDraggingRight;
1084
- removeClass(item, leftClass, rightClass);
1085
- if (direction === 'left') {
1086
- addClass(item, leftClass);
1087
- } else if (direction === 'right') {
1088
- addClass(item, rightClass);
1089
- }
730
+ updateAutoRotateButton(t) {
731
+ const { autoRotateBtn: e } = this.carousel.elements;
732
+ e && (t ? (f(e, r.btnActive), I(e, g.pressed, "true")) : (v(e, r.btnActive), I(e, g.pressed, "false")));
733
+ }
734
+ addDraggingClass(t, e) {
735
+ const s = this.carousel.items[t];
736
+ if (!s) return;
737
+ const i = r.itemDraggingLeft, o = r.itemDraggingRight;
738
+ v(s, i, o), e === "left" ? f(s, i) : e === "right" && f(s, o);
739
+ }
740
+ removeDraggingClass(t) {
741
+ const e = this.carousel.items[t];
742
+ e && v(e, r.itemDraggingLeft, r.itemDraggingRight);
1090
743
  }
1091
- removeDraggingClass(index) {
1092
- const item = this.carousel.items[index];
1093
- if (!item) return;
1094
- removeClass(item, CLASS_NAMES.itemDraggingLeft, CLASS_NAMES.itemDraggingRight);
1095
- }
1096
- round(value, decimals = 2) {
1097
- return Math.round(value * 10 ** decimals) / 10 ** decimals;
1098
- }
1099
- applyEasing(progress) {
1100
- return progress * (2 - Math.abs(progress));
1101
- }
1102
- updateDragTransform(dragDistance) {
1103
- const {
1104
- layoutMode
1105
- } = this.carousel.options;
1106
- if (layoutMode === 'stack') {
1107
- // [개발참고] Stack 모드: 탄성 효과 적용 (easeOutQuad)
1108
- const config = DRAG_TRANSFORM_CONFIG.stack;
1109
- const clampedDrag = Math.max(-config.maxDrag, Math.min(config.maxDrag, dragDistance));
1110
- const progress = clampedDrag / config.maxDrag;
1111
- const easedProgress = this.applyEasing(progress);
1112
- const dragOffset = this.round(easedProgress * config.offsetMultiplier);
1113
- const dragRotation = this.round(easedProgress * config.rotationMultiplier);
1114
- this.carousel.container.style.setProperty('--drag-offset', `${dragOffset}px`);
1115
- this.carousel.container.style.setProperty('--drag-rotation', `${dragRotation}deg`);
1116
- } else if (layoutMode === 'radial') {
1117
- const config = DRAG_TRANSFORM_CONFIG.radial;
1118
- const dragRotation = this.round(dragDistance * config.rotationSensitivity);
1119
- this.carousel.container.style.setProperty('--drag-rotation-y', `${dragRotation}deg`);
1120
- } else if (layoutMode === 'classic') {
1121
- const config = DRAG_TRANSFORM_CONFIG.classic;
1122
- const dragOffset = this.round(dragDistance * config.dragSensitivity);
1123
- this.carousel.container.style.setProperty('--drag-offset', `${dragOffset}px`);
744
+ round(t, e = 2) {
745
+ return Math.round(t * 10 ** e) / 10 ** e;
746
+ }
747
+ applyEasing(t) {
748
+ return t * (2 - Math.abs(t));
749
+ }
750
+ updateDragTransform(t) {
751
+ const { layoutMode: e } = this.carousel.options;
752
+ if (e === "stack") {
753
+ const s = T.stack, o = Math.max(-s.maxDrag, Math.min(s.maxDrag, t)) / s.maxDrag, n = this.applyEasing(o), l = this.round(n * s.offsetMultiplier), u = this.round(n * s.rotationMultiplier);
754
+ this.carousel.container.style.setProperty("--drag-offset", `${l}px`), this.carousel.container.style.setProperty("--drag-rotation", `${u}deg`);
755
+ } else if (e === "radial") {
756
+ const s = T.radial, i = this.round(t * s.rotationSensitivity);
757
+ this.carousel.container.style.setProperty("--drag-rotation-y", `${i}deg`);
758
+ } else if (e === "classic") {
759
+ const s = T.classic, i = this.round(t * s.dragSensitivity);
760
+ this.carousel.container.style.setProperty("--drag-offset", `${i}px`);
1124
761
  }
1125
762
  }
1126
763
  clearDragTransform() {
1127
- this.carousel.container.style.setProperty('--drag-offset', '0px');
1128
- this.carousel.container.style.setProperty('--drag-rotation', '0deg');
1129
- this.carousel.container.style.setProperty('--drag-rotation-y', '0deg');
764
+ this.carousel.container.style.setProperty("--drag-offset", "0px"), this.carousel.container.style.setProperty("--drag-rotation", "0deg"), this.carousel.container.style.setProperty("--drag-rotation-y", "0deg");
765
+ }
766
+ destroy() {
1130
767
  }
1131
- destroy() {}
1132
768
  }
1133
-
1134
- const FULL_CIRCLE_DEGREES = 360;
1135
- class PeekCarousel {
1136
- constructor(selector, options = {}) {
1137
- this.container = getElement(selector);
1138
- if (!this.container) {
1139
- throw new Error(`PeekCarousel: 셀렉터 "${selector}"에 해당하는 컨테이너를 찾을 수 없습니다`);
1140
- }
1141
- this.options = validateOptions(options);
1142
- this.initElements();
1143
- if (this.items.length === 0) {
1144
- throw new Error('PeekCarousel: 캐러셀 아이템을 찾을 수 없습니다');
1145
- }
769
+ const st = 360;
770
+ class it {
771
+ constructor(t, e = {}) {
772
+ if (this.container = N(t), !this.container)
773
+ throw new Error(`PeekCarousel: 셀렉터 "${t}"에 해당하는 컨테이너를 찾을 수 없습니다`);
774
+ if (this.options = L(e), this.initElements(), this.items.length === 0)
775
+ throw new Error("PeekCarousel: 캐러셀 아이템을 찾을 수 없습니다");
1146
776
  this.state = {
1147
777
  currentIndex: this.options.startIndex,
1148
- angleUnit: FULL_CIRCLE_DEGREES / this.totalItems
1149
- };
1150
- this.initModules();
1151
- this.init();
778
+ angleUnit: st / this.totalItems
779
+ }, this.initModules(), this.init();
1152
780
  }
1153
781
  initElements() {
1154
782
  this.elements = {
1155
- carousel: this.container.querySelector(SELECTORS.carousel),
783
+ carousel: this.container.querySelector(C.carousel),
1156
784
  prevBtn: null,
1157
785
  nextBtn: null,
1158
786
  autoRotateBtn: null,
1159
787
  controls: null,
1160
788
  nav: null
1161
- };
1162
- this.items = getElements(SELECTORS.item, this.container);
1163
- this.totalItems = this.items.length;
1164
- this.indicators = [];
789
+ }, this.items = $(C.item, this.container), this.totalItems = this.items.length, this.indicators = [];
1165
790
  }
1166
791
  initModules() {
1167
- this.navigator = new Navigator(this);
1168
- this.animator = new Animator(this);
1169
- this.autoRotate = new AutoRotate(this);
1170
- this.eventHandler = new EventHandler(this);
1171
- this.ui = new UIManager(this);
792
+ this.navigator = new K(this), this.animator = new Y(this), this.autoRotate = new Z(this), this.eventHandler = new tt(this), this.ui = new et(this);
1172
793
  }
1173
794
  init() {
1174
- this.updateLayoutClass();
1175
- this.createNavigation();
1176
- this.createControls();
1177
- this.injectIcons();
1178
- this.createCounter();
1179
- this.setImageLoadingAttributes();
1180
- this.initCSSVariables();
1181
- this.eventHandler.init();
1182
- this.animator.updateCarousel();
1183
- if (this.options.autoRotate) {
1184
- this.autoRotate.start();
1185
- }
1186
- if (this.options.preloadRange > 0) {
1187
- this.preloadImages();
1188
- }
795
+ this.updateLayoutClass(), this.createNavigation(), this.createControls(), this.injectIcons(), this.createCounter(), this.setImageLoadingAttributes(), this.initCSSVariables(), this.eventHandler.init(), this.animator.updateCarousel(), this.options.autoRotate && this.autoRotate.start(), this.options.preloadRange > 0 && this.preloadImages();
1189
796
  }
1190
797
  initCSSVariables() {
1191
- this.container.style.setProperty('--carousel-rotation', '0deg');
1192
- this.container.style.setProperty('--drag-offset', '0px');
1193
- this.container.style.setProperty('--drag-rotation', '0deg');
1194
- this.container.style.setProperty('--drag-rotation-y', '0deg');
798
+ this.container.style.setProperty("--carousel-rotation", "0deg"), this.container.style.setProperty("--drag-offset", "0px"), this.container.style.setProperty("--drag-rotation", "0deg"), this.container.style.setProperty("--drag-rotation-y", "0deg");
1195
799
  }
1196
800
  createNavigation() {
1197
801
  if (!this.options.showNavigation) return;
1198
- const existingNav = this.container.querySelector(`.${CLASS_NAMES.nav}`);
1199
- if (existingNav) {
1200
- this.elements.nav = existingNav;
1201
- this.elements.prevBtn = existingNav.querySelector(SELECTORS.prevBtn);
1202
- this.elements.nextBtn = existingNav.querySelector(SELECTORS.nextBtn);
802
+ const t = this.container.querySelector(`.${r.nav}`);
803
+ if (t) {
804
+ this.elements.nav = t, this.elements.prevBtn = t.querySelector(C.prevBtn), this.elements.nextBtn = t.querySelector(C.nextBtn);
1203
805
  return;
1204
806
  }
1205
- const nav = document.createElement('div');
1206
- nav.className = CLASS_NAMES.nav;
1207
- const prevBtn = document.createElement('button');
1208
- prevBtn.className = `${CLASS_NAMES.navBtn} ${CLASS_NAMES.btn} ${CLASS_NAMES.prevBtn}`;
1209
- prevBtn.setAttribute('aria-label', 'Previous');
1210
- const nextBtn = document.createElement('button');
1211
- nextBtn.className = `${CLASS_NAMES.navBtn} ${CLASS_NAMES.btn} ${CLASS_NAMES.nextBtn}`;
1212
- nextBtn.setAttribute('aria-label', 'Next');
1213
- nav.appendChild(prevBtn);
1214
- nav.appendChild(nextBtn);
1215
- this.container.appendChild(nav);
1216
- this.elements.nav = nav;
1217
- this.elements.prevBtn = prevBtn;
1218
- this.elements.nextBtn = nextBtn;
807
+ const e = document.createElement("div");
808
+ e.className = r.nav;
809
+ const s = document.createElement("button");
810
+ s.className = `${r.navBtn} ${r.btn} ${r.prevBtn}`, s.setAttribute("aria-label", "Previous");
811
+ const i = document.createElement("button");
812
+ i.className = `${r.navBtn} ${r.btn} ${r.nextBtn}`, i.setAttribute("aria-label", "Next"), e.appendChild(s), e.appendChild(i), this.container.appendChild(e), this.elements.nav = e, this.elements.prevBtn = s, this.elements.nextBtn = i;
1219
813
  }
1220
814
  createControls() {
1221
815
  if (!this.options.showIndicators && !this.options.showAutoRotateButton) return;
1222
- const existingControls = this.container.querySelector(`.${CLASS_NAMES.controls}`);
1223
- if (existingControls) {
1224
- this.elements.controls = existingControls;
1225
- const indicatorsWrapper = existingControls.querySelector(`.${CLASS_NAMES.indicators}`);
1226
- if (indicatorsWrapper && this.options.showIndicators) {
1227
- indicatorsWrapper.innerHTML = '';
1228
- this.createIndicators(indicatorsWrapper);
1229
- }
1230
- this.elements.autoRotateBtn = existingControls.querySelector(SELECTORS.autoRotateBtn);
816
+ const t = this.container.querySelector(`.${r.controls}`);
817
+ if (t) {
818
+ this.elements.controls = t;
819
+ const s = t.querySelector(`.${r.indicators}`);
820
+ s && this.options.showIndicators && (s.innerHTML = "", this.createIndicators(s)), this.elements.autoRotateBtn = t.querySelector(C.autoRotateBtn);
1231
821
  return;
1232
822
  }
1233
- const controls = document.createElement('div');
1234
- controls.className = CLASS_NAMES.controls;
1235
- if (this.options.showIndicators) {
1236
- const indicatorsWrapper = document.createElement('div');
1237
- indicatorsWrapper.className = CLASS_NAMES.indicators;
1238
- this.createIndicators(indicatorsWrapper);
1239
- controls.appendChild(indicatorsWrapper);
823
+ const e = document.createElement("div");
824
+ if (e.className = r.controls, this.options.showIndicators) {
825
+ const s = document.createElement("div");
826
+ s.className = r.indicators, this.createIndicators(s), e.appendChild(s);
1240
827
  }
1241
828
  if (this.options.showAutoRotateButton) {
1242
- const autoRotateBtn = document.createElement('button');
1243
- autoRotateBtn.className = `${CLASS_NAMES.autoRotateBtn} ${CLASS_NAMES.btn} ${CLASS_NAMES.btnAutoRotate}`;
1244
- autoRotateBtn.setAttribute('aria-label', 'Toggle auto-rotate');
1245
- autoRotateBtn.setAttribute('aria-pressed', 'false');
1246
- controls.appendChild(autoRotateBtn);
1247
- this.elements.autoRotateBtn = autoRotateBtn;
829
+ const s = document.createElement("button");
830
+ s.className = `${r.autoRotateBtn} ${r.btn} ${r.btnAutoRotate}`, s.setAttribute("aria-label", "Toggle auto-rotate"), s.setAttribute("aria-pressed", "false"), e.appendChild(s), this.elements.autoRotateBtn = s;
1248
831
  }
1249
- this.container.appendChild(controls);
1250
- this.elements.controls = controls;
832
+ this.container.appendChild(e), this.elements.controls = e;
1251
833
  }
1252
- createIndicators(wrapper) {
834
+ createIndicators(t) {
1253
835
  this.indicators = [];
1254
- for (let i = 0; i < this.totalItems; i++) {
1255
- const indicator = document.createElement('button');
1256
- const isActive = i === this.state.currentIndex;
1257
- indicator.className = CLASS_NAMES.indicator;
1258
- indicator.classList.add(CLASS_NAMES.indicatorPeek);
1259
- indicator.setAttribute('role', 'tab');
1260
- indicator.setAttribute('aria-label', `Image ${i + 1}`);
1261
- indicator.setAttribute('aria-selected', isActive ? 'true' : 'false');
1262
- indicator.setAttribute('tabindex', isActive ? '0' : '-1');
1263
- if (isActive) {
1264
- indicator.classList.add(CLASS_NAMES.indicatorActive);
1265
- }
1266
- wrapper.appendChild(indicator);
1267
- this.indicators.push(indicator);
836
+ for (let e = 0; e < this.totalItems; e++) {
837
+ const s = document.createElement("button"), i = e === this.state.currentIndex;
838
+ s.className = r.indicator, s.classList.add(r.indicatorPeek), s.setAttribute("role", "tab"), s.setAttribute("aria-label", `Image ${e + 1}`), s.setAttribute("aria-selected", i ? "true" : "false"), s.setAttribute("tabindex", i ? "0" : "-1"), i && s.classList.add(r.indicatorActive), t.appendChild(s), this.indicators.push(s);
1268
839
  }
1269
840
  }
1270
841
  injectIcons() {
1271
- const {
1272
- prevBtn,
1273
- nextBtn,
1274
- autoRotateBtn
1275
- } = this.elements;
1276
- if (prevBtn) injectIcon(prevBtn, 'prev');
1277
- if (nextBtn) injectIcon(nextBtn, 'next');
1278
- if (autoRotateBtn) injectAutoRotateIcons(autoRotateBtn);
842
+ const { prevBtn: t, nextBtn: e, autoRotateBtn: s } = this.elements;
843
+ t && _(t, "prev"), e && _(e, "next"), s && q(s);
1279
844
  }
1280
845
  createCounter() {
1281
846
  if (!this.options.showCounter) return;
1282
- const existingCounter = this.container.querySelector(`.${CLASS_NAMES.counter}`);
1283
- if (existingCounter) {
1284
- this.counterElement = existingCounter;
1285
- this.updateCounter();
847
+ const t = this.container.querySelector(`.${r.counter}`);
848
+ if (t) {
849
+ this.counterElement = t, this.updateCounter();
1286
850
  return;
1287
851
  }
1288
- const counter = document.createElement('div');
1289
- counter.className = CLASS_NAMES.counter;
1290
- counter.setAttribute('aria-live', 'polite');
1291
- counter.setAttribute('aria-atomic', 'true');
1292
- counter.innerHTML = `
1293
- <span class="${CLASS_NAMES.counterCurrent}">${this.state.currentIndex + 1}</span>
1294
- <span class="${CLASS_NAMES.counterSeparator}">/</span>
1295
- <span class="${CLASS_NAMES.counterTotal}">${this.totalItems}</span>
1296
- `;
1297
- this.container.appendChild(counter);
1298
- this.counterElement = counter;
852
+ const e = document.createElement("div");
853
+ e.className = r.counter, e.setAttribute("aria-live", "polite"), e.setAttribute("aria-atomic", "true"), e.innerHTML = `
854
+ <span class="${r.counterCurrent}">${this.state.currentIndex + 1}</span>
855
+ <span class="${r.counterSeparator}">/</span>
856
+ <span class="${r.counterTotal}">${this.totalItems}</span>
857
+ `, this.container.appendChild(e), this.counterElement = e;
1299
858
  }
1300
859
  updateCounter() {
1301
860
  if (!this.counterElement) return;
1302
- const currentSpan = this.counterElement.querySelector(`.${CLASS_NAMES.counterCurrent}`);
1303
- if (currentSpan) {
1304
- currentSpan.textContent = this.state.currentIndex + 1;
1305
- }
861
+ const t = this.counterElement.querySelector(`.${r.counterCurrent}`);
862
+ t && (t.textContent = this.state.currentIndex + 1);
1306
863
  }
1307
864
  setImageLoadingAttributes() {
1308
- const {
1309
- startIndex
1310
- } = this.options;
1311
- const preloadRange = this.options.preloadRange || 1;
1312
- for (let index = 0; index < this.items.length; index++) {
1313
- const item = this.items[index];
1314
- const img = item.querySelector(`.${CLASS_NAMES.image}`);
1315
- if (!img || img.hasAttribute('loading')) continue;
1316
- const distance = Math.abs(index - startIndex);
1317
- const isNearby = distance <= preloadRange;
1318
- img.setAttribute('loading', isNearby ? 'eager' : 'lazy');
865
+ const { startIndex: t } = this.options, e = this.options.preloadRange || 1;
866
+ for (let s = 0; s < this.items.length; s++) {
867
+ const o = this.items[s].querySelector(`.${r.image}`);
868
+ if (!o || o.hasAttribute("loading")) continue;
869
+ const l = Math.abs(s - t) <= e;
870
+ o.setAttribute("loading", l ? "eager" : "lazy");
1319
871
  }
1320
872
  }
1321
873
  updateLayoutClass() {
1322
- const currentMode = this.currentLayoutMode;
1323
- const newMode = this.options.layoutMode;
1324
- if (currentMode && currentMode !== newMode) {
1325
- this.container.classList.remove(`peek-carousel--${currentMode}`);
1326
- }
1327
- this.container.classList.add(`peek-carousel--${newMode}`);
1328
- this.currentLayoutMode = newMode;
874
+ const t = this.currentLayoutMode, e = this.options.layoutMode;
875
+ t && t !== e && this.container.classList.remove(`peek-carousel--${t}`), this.container.classList.add(`peek-carousel--${e}`), this.currentLayoutMode = e;
1329
876
  }
1330
877
  preloadImages() {
1331
- preloadImagesInRange(this.items, this.state.currentIndex, this.options.preloadRange);
878
+ X(this.items, this.state.currentIndex, this.options.preloadRange);
1332
879
  }
1333
-
1334
880
  // [개발참고] Public API
1335
881
  next() {
1336
882
  this.navigator.next();
@@ -1338,8 +884,8 @@ class PeekCarousel {
1338
884
  prev() {
1339
885
  this.navigator.prev();
1340
886
  }
1341
- goTo(index) {
1342
- this.navigator.goTo(index);
887
+ goTo(t) {
888
+ this.navigator.goTo(t);
1343
889
  }
1344
890
  startAutoRotate() {
1345
891
  this.autoRotate.start();
@@ -1351,10 +897,7 @@ class PeekCarousel {
1351
897
  this.autoRotate.toggle();
1352
898
  }
1353
899
  destroy() {
1354
- this.autoRotate.destroy();
1355
- this.animator.stopMomentum();
1356
- this.eventHandler.destroy();
1357
- this.ui.destroy();
900
+ this.autoRotate.destroy(), this.animator.stopMomentum(), this.eventHandler.destroy(), this.ui.destroy();
1358
901
  }
1359
902
  get currentIndex() {
1360
903
  return this.state.currentIndex;
@@ -1363,6 +906,7 @@ class PeekCarousel {
1363
906
  return this.autoRotate.isActive;
1364
907
  }
1365
908
  }
1366
-
1367
- export { PeekCarousel as default };
909
+ export {
910
+ it as default
911
+ };
1368
912
  //# sourceMappingURL=peek-carousel.esm.js.map