@ivcreative/accessible-vanilla-slick 1.0.2

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.
@@ -0,0 +1,2087 @@
1
+ // slick/src/utils/events.js
2
+ var EventDispatcher = class {
3
+ constructor() {
4
+ this.listeners = {};
5
+ }
6
+ /**
7
+ * Subscribe to an event
8
+ */
9
+ on(event, callback, context = null) {
10
+ if (!this.listeners[event]) {
11
+ this.listeners[event] = [];
12
+ }
13
+ this.listeners[event].push({ callback, context });
14
+ return this;
15
+ }
16
+ /**
17
+ * Subscribe to an event once
18
+ */
19
+ once(event, callback, context = null) {
20
+ const wrapper = (...args) => {
21
+ callback.apply(context, args);
22
+ this.off(event, wrapper);
23
+ };
24
+ return this.on(event, wrapper, context);
25
+ }
26
+ /**
27
+ * Unsubscribe from an event
28
+ */
29
+ off(event, callback = null) {
30
+ if (!event) {
31
+ this.listeners = {};
32
+ return this;
33
+ }
34
+ if (!callback) {
35
+ delete this.listeners[event];
36
+ return this;
37
+ }
38
+ if (this.listeners[event]) {
39
+ this.listeners[event] = this.listeners[event].filter(
40
+ (listener) => listener.callback !== callback
41
+ );
42
+ }
43
+ return this;
44
+ }
45
+ /**
46
+ * Emit/trigger an event
47
+ */
48
+ emit(event, data = null) {
49
+ if (!this.listeners[event])
50
+ return this;
51
+ this.listeners[event].forEach((listener) => {
52
+ listener.callback.call(listener.context, data);
53
+ });
54
+ return this;
55
+ }
56
+ /**
57
+ * Clear all listeners
58
+ */
59
+ clear() {
60
+ this.listeners = {};
61
+ return this;
62
+ }
63
+ };
64
+
65
+ // slick/src/utils/helpers.js
66
+ function extend(target, ...sources) {
67
+ if (!sources.length)
68
+ return target;
69
+ const source = sources.shift();
70
+ if (isObject(target) && isObject(source)) {
71
+ for (const key in source) {
72
+ if (isObject(source[key])) {
73
+ if (!target[key])
74
+ Object.assign(target, { [key]: {} });
75
+ extend(target[key], source[key]);
76
+ } else {
77
+ Object.assign(target, { [key]: source[key] });
78
+ }
79
+ }
80
+ }
81
+ return extend(target, ...sources);
82
+ }
83
+ function isObject(obj) {
84
+ return obj && typeof obj === "object" && !Array.isArray(obj) && obj.constructor === Object;
85
+ }
86
+ function debounce(func, wait = 0) {
87
+ let timeout;
88
+ return function executedFunction(...args) {
89
+ const later = () => {
90
+ clearTimeout(timeout);
91
+ func(...args);
92
+ };
93
+ clearTimeout(timeout);
94
+ timeout = setTimeout(later, wait);
95
+ };
96
+ }
97
+ var idCounter = 0;
98
+ function uniqueId(prefix = "slick") {
99
+ return `${prefix}-${++idCounter}`;
100
+ }
101
+ function parseHTML(htmlString) {
102
+ const temp = document.createElement("div");
103
+ temp.innerHTML = htmlString.trim();
104
+ return temp.firstElementChild;
105
+ }
106
+ var requestAnimFrame = window.requestAnimationFrame || function(callback) {
107
+ return setTimeout(callback, 1e3 / 60);
108
+ };
109
+ var cancelAnimFrame = window.cancelAnimationFrame || function(id) {
110
+ clearTimeout(id);
111
+ };
112
+ function getWindowDimensions() {
113
+ return {
114
+ width: window.innerWidth || document.documentElement.clientWidth,
115
+ height: window.innerHeight || document.documentElement.clientHeight
116
+ };
117
+ }
118
+
119
+ // slick/src/utils/dom.js
120
+ function select(selector, context = document) {
121
+ return context.querySelector(selector);
122
+ }
123
+ function selectAll(selector, context = document) {
124
+ return Array.from(context.querySelectorAll(selector));
125
+ }
126
+ function addClass(element, className) {
127
+ if (!element)
128
+ return;
129
+ if (Array.isArray(element)) {
130
+ element.forEach((el) => addClass(el, className));
131
+ } else {
132
+ element.classList.add(...className.split(" "));
133
+ }
134
+ }
135
+ function removeClass(element, className) {
136
+ if (!element)
137
+ return;
138
+ if (Array.isArray(element)) {
139
+ element.forEach((el) => removeClass(el, className));
140
+ } else {
141
+ element.classList.remove(...className.split(" "));
142
+ }
143
+ }
144
+ function hasClass(element, className) {
145
+ return element ? element.classList.contains(className) : false;
146
+ }
147
+ function setAttribute(element, name, value) {
148
+ if (!element)
149
+ return;
150
+ if (Array.isArray(element)) {
151
+ element.forEach((el) => setAttribute(el, name, value));
152
+ } else if (typeof name === "object") {
153
+ Object.entries(name).forEach(([key, val]) => {
154
+ setAttribute(element, key, val);
155
+ });
156
+ } else {
157
+ if (value === null) {
158
+ element.removeAttribute(name);
159
+ } else {
160
+ element.setAttribute(name, value);
161
+ }
162
+ }
163
+ }
164
+ function getAttribute(element, name) {
165
+ return element ? element.getAttribute(name) : null;
166
+ }
167
+ function removeAttribute(element, name) {
168
+ if (!element)
169
+ return;
170
+ if (Array.isArray(element)) {
171
+ element.forEach((el) => removeAttribute(el, name));
172
+ } else {
173
+ element.removeAttribute(name);
174
+ }
175
+ }
176
+ function setStyle(element, name, value) {
177
+ if (!element)
178
+ return;
179
+ if (Array.isArray(element)) {
180
+ element.forEach((el) => setStyle(el, name, value));
181
+ } else if (typeof name === "object") {
182
+ Object.entries(name).forEach(([key, val]) => {
183
+ element.style[key] = val;
184
+ });
185
+ } else {
186
+ element.style[name] = value;
187
+ }
188
+ }
189
+ function getDimensions(element) {
190
+ const rect = element.getBoundingClientRect();
191
+ return {
192
+ width: element.offsetWidth || rect.width,
193
+ height: element.offsetHeight || rect.height,
194
+ top: element.offsetTop || rect.top,
195
+ left: element.offsetLeft || rect.left
196
+ };
197
+ }
198
+ function getInnerWidth(element) {
199
+ const styles = window.getComputedStyle(element);
200
+ const paddingLeft = parseFloat(styles.paddingLeft) || 0;
201
+ const paddingRight = parseFloat(styles.paddingRight) || 0;
202
+ return element.clientWidth - paddingLeft - paddingRight;
203
+ }
204
+ function getOuterWidth(element, includeMargin = false) {
205
+ let width = element.offsetWidth;
206
+ if (includeMargin) {
207
+ const style = window.getComputedStyle(element);
208
+ width += parseFloat(style.marginLeft) + parseFloat(style.marginRight);
209
+ }
210
+ return width;
211
+ }
212
+ function getOuterHeight(element, includeMargin = false) {
213
+ let height = element.offsetHeight;
214
+ if (includeMargin) {
215
+ const style = window.getComputedStyle(element);
216
+ height += parseFloat(style.marginTop) + parseFloat(style.marginBottom);
217
+ }
218
+ return height;
219
+ }
220
+ function appendChild(parent, child) {
221
+ if (!parent)
222
+ return;
223
+ if (typeof child === "string") {
224
+ parent.insertAdjacentHTML("beforeend", child);
225
+ } else {
226
+ parent.appendChild(child);
227
+ }
228
+ }
229
+ function insertBefore(target, element) {
230
+ if (!target)
231
+ return;
232
+ if (typeof element === "string") {
233
+ target.insertAdjacentHTML("beforebegin", element);
234
+ } else {
235
+ target.parentNode.insertBefore(element, target);
236
+ }
237
+ }
238
+ function remove(element) {
239
+ if (!element)
240
+ return;
241
+ if (Array.isArray(element)) {
242
+ element.forEach((el) => remove(el));
243
+ } else if (element.parentNode) {
244
+ element.parentNode.removeChild(element);
245
+ }
246
+ }
247
+ function empty(element) {
248
+ if (!element)
249
+ return;
250
+ while (element.firstChild) {
251
+ element.removeChild(element.firstChild);
252
+ }
253
+ }
254
+ function getChildren(element, selector = null) {
255
+ if (!element)
256
+ return [];
257
+ if (selector) {
258
+ return Array.from(element.children).filter((child) => child.matches(selector));
259
+ }
260
+ return Array.from(element.children);
261
+ }
262
+
263
+ // slick/src/utils/css.js
264
+ function supportsTransforms() {
265
+ const element = document.createElement("div");
266
+ return "transform" in element.style || "WebkitTransform" in element.style || "MozTransform" in element.style || "OTransform" in element.style || "msTransform" in element.style;
267
+ }
268
+ function getTransformProperty() {
269
+ const element = document.createElement("div");
270
+ const properties = ["transform", "WebkitTransform", "MozTransform", "OTransform", "msTransform"];
271
+ for (const prop of properties) {
272
+ if (prop in element.style) {
273
+ return prop;
274
+ }
275
+ }
276
+ return "transform";
277
+ }
278
+ function getTransitionProperty() {
279
+ const element = document.createElement("div");
280
+ const properties = ["transition", "WebkitTransition", "MozTransition", "OTransition", "msTransition"];
281
+ for (const prop of properties) {
282
+ if (prop in element.style) {
283
+ return prop;
284
+ }
285
+ }
286
+ return "transition";
287
+ }
288
+ function applyTransition(element, duration, easing = "ease") {
289
+ const transitionProp = getTransitionProperty();
290
+ element.style[transitionProp] = `all ${duration}ms ${easing}`;
291
+ }
292
+ function removeTransition(element) {
293
+ const transitionProp = getTransitionProperty();
294
+ element.style[transitionProp] = "none";
295
+ }
296
+ function translate3d(element, x, y = 0, z = 0) {
297
+ const transformProp = getTransformProperty();
298
+ element.style[transformProp] = `translate3d(${x}px, ${y}px, ${z}px)`;
299
+ }
300
+
301
+ // slick/src/SlickSlider.js
302
+ var SlickSlider = class _SlickSlider {
303
+ static INSTANCES = /* @__PURE__ */ new Map();
304
+ constructor(element, options = {}) {
305
+ this.element = element;
306
+ this.instanceId = uniqueId("slick");
307
+ this.constructor.INSTANCES.set(this.instanceId, this);
308
+ this.options = extend({}, this.constructor.DEFAULTS, options);
309
+ this.originalOptions = extend({}, this.options);
310
+ this.state = extend({}, this.constructor.INITIAL_STATE);
311
+ this.dispatcher = new EventDispatcher();
312
+ this.boundMethods = {};
313
+ this.init();
314
+ }
315
+ /**
316
+ * Default configuration options
317
+ */
318
+ static DEFAULTS = {
319
+ // Slider behavior
320
+ accessibility: true,
321
+ adaptiveHeight: false,
322
+ appendArrows: null,
323
+ appendDots: null,
324
+ arrows: true,
325
+ arrowsPlacement: null,
326
+ // 'before', 'after', 'split'
327
+ asNavFor: null,
328
+ autoplay: false,
329
+ autoplaySpeed: 3e3,
330
+ centerMode: false,
331
+ centerPadding: "50px",
332
+ cssEase: "ease",
333
+ customPaging: null,
334
+ dots: false,
335
+ dotsClass: "slick-dots",
336
+ draggable: true,
337
+ edge: false,
338
+ easing: "linear",
339
+ edgeFriction: 0.35,
340
+ fade: false,
341
+ focusOnSelect: false,
342
+ focusOnChange: false,
343
+ infinite: true,
344
+ initialSlide: 0,
345
+ instructionsText: null,
346
+ lazyLoad: "ondemand",
347
+ // 'ondemand', 'progressive', or false
348
+ mobileFirst: false,
349
+ nextArrow: '<button class="slick-next" aria-label="Next slide"><span class="slick-next-icon" aria-hidden="true"></span></button>',
350
+ pauseIcon: '<span class="slick-pause-icon" aria-hidden="true"></span>',
351
+ pauseOnFocus: true,
352
+ pauseOnHover: true,
353
+ playIcon: '<span class="slick-play-icon" aria-hidden="true"></span>',
354
+ prevArrow: '<button class="slick-prev" aria-label="Previous slide"><span class="slick-prev-icon" aria-hidden="true"></span></button>',
355
+ respondTo: "window",
356
+ // 'window', 'slider', or 'min'
357
+ responsive: null,
358
+ rows: 1,
359
+ rtl: false,
360
+ slide: "",
361
+ slidesPerRow: 1,
362
+ slidesToShow: 1,
363
+ slidesToScroll: 1,
364
+ speed: 500,
365
+ swipe: true,
366
+ swipeToSlide: false,
367
+ touchMove: true,
368
+ touchThreshold: 5,
369
+ useAutoplayToggleButton: true,
370
+ useCSS: true,
371
+ useGroupRole: true,
372
+ useTransform: true,
373
+ variableWidth: false,
374
+ vertical: false,
375
+ verticalSwiping: false,
376
+ waitForAnimate: true,
377
+ zIndex: 1e3,
378
+ // Accessibility
379
+ regionLabel: "slider"
380
+ };
381
+ /**
382
+ * Initial state
383
+ */
384
+ static INITIAL_STATE = {
385
+ activeBreakpoint: null,
386
+ animating: false,
387
+ autoPlayTimer: null,
388
+ currentDirection: 0,
389
+ currentLeft: 0,
390
+ currentSlide: 0,
391
+ direction: 1,
392
+ dotListElement: null,
393
+ dotSlidesToScroll: 1,
394
+ dots: null,
395
+ dragging: false,
396
+ edgeHit: false,
397
+ slidesCache: null,
398
+ gestureEndTime: 0,
399
+ gestureStartTime: 0,
400
+ instructionsText: null,
401
+ interrupted: false,
402
+ listHeight: 0,
403
+ listWidth: 0,
404
+ loadIndex: 0,
405
+ nextArrowElement: null,
406
+ pauseButton: null,
407
+ postSlideDelay: 0,
408
+ prevArrowElement: null,
409
+ scrolling: false,
410
+ slideCount: 0,
411
+ slideHeight: 0,
412
+ slideOffset: 0,
413
+ slideWidth: 0,
414
+ slideTrack: null,
415
+ slides: [],
416
+ sliding: false,
417
+ slideList: null,
418
+ swipeLeft: 0,
419
+ swiping: false,
420
+ suppressNavSync: false,
421
+ swipeDirection: null,
422
+ targetSlide: 0,
423
+ touchObject: {},
424
+ touchStartTime: 0,
425
+ transformsEnabled: false,
426
+ unslicked: false,
427
+ windowHeight: 0,
428
+ windowWidth: 0,
429
+ yeti: null
430
+ };
431
+ /**
432
+ * Key codes for keyboard navigation
433
+ */
434
+ static KEYS = {
435
+ ENTER: 13,
436
+ SPACE: 32,
437
+ LEFT: 37,
438
+ UP: 38,
439
+ RIGHT: 39,
440
+ DOWN: 40,
441
+ TAB: 9,
442
+ HOME: 36,
443
+ END: 35,
444
+ ESCAPE: 27
445
+ };
446
+ /**
447
+ * Initialize slider
448
+ */
449
+ init() {
450
+ this.element.setAttribute("data-slick-slider", this.instanceId);
451
+ addClass(this.element, "slick-slider");
452
+ this.state.transformsEnabled = supportsTransforms();
453
+ this.setProps();
454
+ this.state.currentSlide = this.options.initialSlide;
455
+ this.state.currentDirection = 1;
456
+ this.state.rtl = this.options.rtl;
457
+ this.state.rows = this.options.rows;
458
+ this.state.slideCount = 0;
459
+ this.loadSlider();
460
+ this.buildOut();
461
+ this.setupInfinite();
462
+ if (this.options.accessibility) {
463
+ setAttribute(this.element, "role", "region");
464
+ setAttribute(this.element, "aria-label", this.options.regionLabel);
465
+ }
466
+ if (this.options.arrows && this.state.slideCount > this.options.slidesToShow) {
467
+ this.buildArrows();
468
+ }
469
+ if (this.options.dots && this.state.slideCount > this.options.slidesToShow) {
470
+ this.buildDots();
471
+ }
472
+ if (this.options.autoplay && this.options.useAutoplayToggleButton && this.state.slideCount > 1) {
473
+ this.buildAutoplayButton();
474
+ }
475
+ this.updateNavigationVisibility();
476
+ addClass(this.element, "slick-initialized");
477
+ if (this.options.variableWidth) {
478
+ window.requestAnimationFrame(() => {
479
+ this.setPosition();
480
+ });
481
+ } else {
482
+ this.setPosition();
483
+ }
484
+ this.initializeEvents();
485
+ if (this.options.autoplay) {
486
+ this.autoPlay();
487
+ }
488
+ if (this.options.responsive && this.options.responsive.length) {
489
+ this.checkResponsive(true);
490
+ }
491
+ this.emit("init", { instance: this });
492
+ }
493
+ /**
494
+ * Set properties matching jQuery setProps()
495
+ */
496
+ setProps() {
497
+ this.state.positionProp = this.options.vertical ? "top" : "left";
498
+ if (this.options.fade) {
499
+ this.options.centerMode = false;
500
+ this.options.slidesToShow = 1;
501
+ this.options.slidesToScroll = 1;
502
+ }
503
+ const style = document.body.style;
504
+ if (style.transform !== void 0) {
505
+ this.state.animType = "transform";
506
+ } else if (style.webkitTransform !== void 0) {
507
+ this.state.animType = "webkitTransform";
508
+ } else if (style.MozTransform !== void 0) {
509
+ this.state.animType = "MozTransform";
510
+ } else if (style.msTransform !== void 0) {
511
+ this.state.animType = "msTransform";
512
+ } else if (style.OTransform !== void 0) {
513
+ this.state.animType = "OTransform";
514
+ } else {
515
+ this.state.animType = false;
516
+ }
517
+ }
518
+ /**
519
+ * Setup infinite mode - CRITICAL for infinite scrolling
520
+ * Clones the first and last slides to enable seamless wrapping
521
+ */
522
+ setupInfinite() {
523
+ if (!this.options.infinite || this.options.fade || this.state.slideCount <= this.options.slidesToShow) {
524
+ return;
525
+ }
526
+ const infiniteCount = this.options.centerMode ? this.options.slidesToShow + 1 : this.options.slidesToShow;
527
+ for (let i = this.state.slideCount; i > this.state.slideCount - infiniteCount; i -= 1) {
528
+ const slideIndex = i - 1;
529
+ const clone2 = this.state.slides[slideIndex].cloneNode(true);
530
+ addClass(clone2, "slick-cloned");
531
+ setAttribute(clone2, "aria-hidden", "true");
532
+ setAttribute(clone2, "tabindex", "-1");
533
+ setAttribute(clone2, "data-slick-index", String(slideIndex - this.state.slideCount));
534
+ this.state.slideTrack.insertBefore(clone2, this.state.slideTrack.firstChild);
535
+ }
536
+ const appendCount = Math.max(
537
+ this.state.slideCount,
538
+ this.options.slidesToShow + this.options.slidesToScroll
539
+ );
540
+ for (let i = 0; i < appendCount; i += 1) {
541
+ const slideIndex = i % this.state.slideCount;
542
+ const clone2 = this.state.slides[slideIndex].cloneNode(true);
543
+ addClass(clone2, "slick-cloned");
544
+ setAttribute(clone2, "aria-hidden", "true");
545
+ setAttribute(clone2, "tabindex", "-1");
546
+ setAttribute(clone2, "data-slick-index", String(i + this.state.slideCount));
547
+ appendChild(this.state.slideTrack, clone2);
548
+ }
549
+ void this.state.slideTrack.offsetWidth;
550
+ }
551
+ /**
552
+ * Load slides from DOM
553
+ */
554
+ loadSlider() {
555
+ const slides = this.options.slide ? selectAll(this.options.slide, this.element) : getChildren(this.element);
556
+ this.state.slides = Array.from(slides);
557
+ this.state.slideCount = this.state.slides.length;
558
+ this.state.slides.forEach((slide, index) => {
559
+ addClass(slide, "slick-slide");
560
+ setAttribute(slide, "data-slick-index", index);
561
+ if (this.options.useGroupRole) {
562
+ setAttribute(slide, "role", "group");
563
+ setAttribute(slide, "aria-label", `slide ${index + 1}`);
564
+ }
565
+ });
566
+ this.wrapSlideContent();
567
+ this.emit("loaded", { slideCount: this.state.slideCount });
568
+ }
569
+ /**
570
+ * Wrap slide content with inline-block div for proper layout
571
+ * Matches jQuery Slick behavior: wraps immediate children in div with display: inline-block
572
+ */
573
+ wrapSlideContent() {
574
+ this.state.slides.forEach((slide) => {
575
+ const children = Array.from(getChildren(slide));
576
+ if (children.length === 1 && children[0].tagName === "DIV") {
577
+ const innerDiv = children[0];
578
+ if (innerDiv.style.display !== "inline-block") {
579
+ setStyle(innerDiv, "width", "100%");
580
+ setStyle(innerDiv, "display", "inline-block");
581
+ }
582
+ return;
583
+ }
584
+ const hasInlineBlockWrapper = children.length === 1 && getComputedStyle(children[0]).display === "inline-block";
585
+ if (hasInlineBlockWrapper) {
586
+ return;
587
+ }
588
+ const wrapper = document.createElement("div");
589
+ setStyle(wrapper, "width", "100%");
590
+ setStyle(wrapper, "display", "inline-block");
591
+ children.forEach((child) => {
592
+ appendChild(wrapper, child);
593
+ });
594
+ appendChild(slide, wrapper);
595
+ });
596
+ }
597
+ /**
598
+ * Build slider DOM structure
599
+ */
600
+ buildOut() {
601
+ const track = select(".slick-track", this.element);
602
+ const list = select(".slick-list", this.element);
603
+ if (!track || !list) {
604
+ const listDiv = document.createElement("div");
605
+ addClass(listDiv, "slick-list");
606
+ const trackDiv = document.createElement("div");
607
+ addClass(trackDiv, "slick-track");
608
+ this.state.slides.forEach((slide) => {
609
+ appendChild(trackDiv, slide);
610
+ });
611
+ appendChild(listDiv, trackDiv);
612
+ appendChild(this.element, listDiv);
613
+ this.state.slideTrack = trackDiv;
614
+ this.state.slideList = listDiv;
615
+ } else {
616
+ this.state.slideTrack = track;
617
+ this.state.slideList = list;
618
+ }
619
+ if (this.options.accessibility) {
620
+ setAttribute(this.element, "role", "region");
621
+ setAttribute(this.element, "aria-label", this.options.regionLabel);
622
+ }
623
+ }
624
+ /**
625
+ * Build navigation arrows
626
+ */
627
+ buildArrows() {
628
+ const prevArrowHTML = this.options.prevArrow;
629
+ const prevArrow = parseHTML(prevArrowHTML);
630
+ addClass(prevArrow, "slick-arrow");
631
+ this.state.prevArrowElement = prevArrow;
632
+ prevArrow.addEventListener("click", (e) => this.prevClick(e));
633
+ const nextArrowHTML = this.options.nextArrow;
634
+ const nextArrow = parseHTML(nextArrowHTML);
635
+ addClass(nextArrow, "slick-arrow");
636
+ this.state.nextArrowElement = nextArrow;
637
+ nextArrow.addEventListener("click", (e) => this.nextClick(e));
638
+ const appendTarget = this.options.appendArrows || this.element;
639
+ const slideList = this.state.slideList;
640
+ if (slideList && slideList.parentNode === appendTarget) {
641
+ insertBefore(slideList, prevArrow);
642
+ appendChild(appendTarget, nextArrow);
643
+ } else {
644
+ appendChild(appendTarget, prevArrow);
645
+ appendChild(appendTarget, nextArrow);
646
+ }
647
+ this.emit("arrowsBuilt");
648
+ }
649
+ /**
650
+ * Build navigation dots
651
+ */
652
+ buildDots() {
653
+ const dotContainer = document.createElement("ul");
654
+ addClass(dotContainer, this.options.dotsClass);
655
+ addClass(this.element, "slick-dotted");
656
+ const dotCount = Math.ceil(this.state.slideCount / this.options.slidesToScroll);
657
+ for (let i = 0; i < dotCount; i++) {
658
+ const dot = document.createElement("li");
659
+ const button = document.createElement("button");
660
+ const icon = document.createElement("span");
661
+ addClass(icon, "slick-dot-icon");
662
+ setAttribute(button, "aria-label", `Go to slide ${i + 1}`);
663
+ setAttribute(button, "data-slide-index", i);
664
+ if (i === 0)
665
+ addClass(dot, "slick-active");
666
+ button.addEventListener("click", (e) => this.dotClick(e));
667
+ appendChild(button, icon);
668
+ appendChild(dot, button);
669
+ appendChild(dotContainer, dot);
670
+ }
671
+ this.state.dots = dotContainer;
672
+ this.state.dotListElement = dotContainer;
673
+ const appendTarget = this.options.appendDots || this.element;
674
+ appendChild(appendTarget, dotContainer);
675
+ this.updateDots();
676
+ this.emit("dotsBuilt");
677
+ }
678
+ /**
679
+ * Update dot active state
680
+ */
681
+ updateDots() {
682
+ if (!this.state.dots)
683
+ return;
684
+ const dotIndex = Math.floor(this.state.currentSlide / this.options.slidesToScroll);
685
+ const dots = Array.from(this.state.dots.children);
686
+ dots.forEach((dot, index) => {
687
+ if (index === dotIndex) {
688
+ addClass(dot, "slick-active");
689
+ } else {
690
+ removeClass(dot, "slick-active");
691
+ }
692
+ });
693
+ }
694
+ /**
695
+ * Build autoplay toggle button
696
+ */
697
+ buildAutoplayButton() {
698
+ const button = document.createElement("button");
699
+ addClass(button, "slick-autoplay-toggle-button");
700
+ setAttribute(button, "aria-label", "Play/Pause slider autoplay");
701
+ this.state.pauseButton = button;
702
+ button.addEventListener("click", () => this.autoPlayToggleHandler());
703
+ this.setAutoplayButtonState(Boolean(this.state.paused));
704
+ if (this.state.slideList) {
705
+ this.element.insertBefore(button, this.state.slideList);
706
+ } else {
707
+ appendChild(this.element, button);
708
+ }
709
+ }
710
+ /**
711
+ * Update autoplay button icon and state
712
+ */
713
+ setAutoplayButtonState(isPaused) {
714
+ if (!this.state.pauseButton)
715
+ return;
716
+ setAttribute(this.state.pauseButton, "aria-pressed", isPaused ? "true" : "false");
717
+ empty(this.state.pauseButton);
718
+ const iconMarkup = isPaused ? this.options.playIcon : this.options.pauseIcon;
719
+ if (typeof iconMarkup === "string") {
720
+ appendChild(this.state.pauseButton, parseHTML(iconMarkup));
721
+ } else if (iconMarkup) {
722
+ appendChild(this.state.pauseButton, iconMarkup);
723
+ }
724
+ }
725
+ /**
726
+ * Setup event listeners
727
+ */
728
+ initializeEvents() {
729
+ this.boundMethods.handleResize = debounce(() => this.checkResponsive(), 250);
730
+ window.addEventListener("resize", this.boundMethods.handleResize);
731
+ this.boundMethods.handleVisibilityChange = () => this.handleVisibilityChange();
732
+ document.addEventListener("visibilitychange", this.boundMethods.handleVisibilityChange);
733
+ this.boundMethods.handleKeydown = (e) => this.handleKeydown(e);
734
+ this.element.addEventListener("keydown", this.boundMethods.handleKeydown);
735
+ if (this.options.draggable && this.state.slideList) {
736
+ this.boundMethods.handleMouseDown = (e) => this.startDrag(e);
737
+ this.state.slideList.addEventListener("mousedown", this.boundMethods.handleMouseDown);
738
+ }
739
+ if (this.options.swipe && this.state.slideList && "ontouchstart" in window) {
740
+ this.boundMethods.handleTouchStart = (e) => this.startDrag(e);
741
+ this.boundMethods.handleTouchEnd = (e) => this.endDrag(e);
742
+ this.boundMethods.handleTouchMove = (e) => this.trackDrag(e);
743
+ this.state.slideList.addEventListener("touchstart", this.boundMethods.handleTouchStart, { passive: true });
744
+ this.state.slideList.addEventListener("touchend", this.boundMethods.handleTouchEnd, { passive: true });
745
+ this.state.slideList.addEventListener("touchmove", this.boundMethods.handleTouchMove, { passive: false });
746
+ }
747
+ this.boundMethods.handleFocus = () => this.handleFocus();
748
+ this.boundMethods.handleBlur = () => this.handleBlur();
749
+ this.element.addEventListener("focusin", this.boundMethods.handleFocus, true);
750
+ this.element.addEventListener("focusout", this.boundMethods.handleBlur, true);
751
+ if (this.options.focusOnSelect && this.state.slideTrack) {
752
+ this.boundMethods.handleSlideClick = (e) => this.handleSlideClick(e);
753
+ this.state.slideTrack.addEventListener("click", this.boundMethods.handleSlideClick);
754
+ }
755
+ }
756
+ /**
757
+ * Resolve slide index into range [0, slideCount - 1]
758
+ */
759
+ normalizeSlideIndex(index) {
760
+ if (this.state.slideCount <= 0 || !Number.isFinite(index)) {
761
+ return 0;
762
+ }
763
+ const count = this.state.slideCount;
764
+ let normalized = index % count;
765
+ if (normalized < 0) {
766
+ normalized += count;
767
+ }
768
+ return normalized;
769
+ }
770
+ /**
771
+ * Resolve asNavFor option to slider instances
772
+ */
773
+ getNavTargetInstances() {
774
+ const asNavFor = this.options.asNavFor;
775
+ if (!asNavFor) {
776
+ return [];
777
+ }
778
+ const targets = [];
779
+ if (typeof asNavFor === "string") {
780
+ const elements = Array.from(document.querySelectorAll(asNavFor));
781
+ elements.forEach((element) => {
782
+ const instanceId = element.getAttribute("data-slick-slider");
783
+ if (!instanceId)
784
+ return;
785
+ const instance = this.constructor.INSTANCES.get(instanceId);
786
+ if (instance && instance !== this) {
787
+ targets.push(instance);
788
+ }
789
+ });
790
+ return targets;
791
+ }
792
+ if (asNavFor instanceof _SlickSlider) {
793
+ return asNavFor === this ? [] : [asNavFor];
794
+ }
795
+ if (asNavFor instanceof Element) {
796
+ const instanceId = asNavFor.getAttribute("data-slick-slider");
797
+ const instance = instanceId ? this.constructor.INSTANCES.get(instanceId) : null;
798
+ return instance && instance !== this ? [instance] : [];
799
+ }
800
+ return [];
801
+ }
802
+ /**
803
+ * Sync current slide to linked sliders (asNavFor)
804
+ */
805
+ syncAsNavFor(index, dontAnimate = false) {
806
+ const targets = this.getNavTargetInstances();
807
+ if (!targets.length) {
808
+ return;
809
+ }
810
+ targets.forEach((target) => {
811
+ if (!target || target.state.unslicked) {
812
+ return;
813
+ }
814
+ const targetIndex = target.normalizeSlideIndex(index);
815
+ if (target.state.currentSlide === targetIndex) {
816
+ return;
817
+ }
818
+ target.state.suppressNavSync = true;
819
+ target.goTo(targetIndex, dontAnimate);
820
+ target.state.suppressNavSync = false;
821
+ });
822
+ }
823
+ /**
824
+ * Handle click-to-select on slide track
825
+ */
826
+ handleSlideClick(e) {
827
+ const targetSlide = e.target.closest(".slick-slide");
828
+ if (!targetSlide || !this.state.slideTrack || !this.state.slideTrack.contains(targetSlide)) {
829
+ return;
830
+ }
831
+ const rawIndex = parseInt(getAttribute(targetSlide, "data-slick-index"), 10);
832
+ if (Number.isNaN(rawIndex)) {
833
+ return;
834
+ }
835
+ const index = this.normalizeSlideIndex(rawIndex);
836
+ this.goTo(index);
837
+ }
838
+ /**
839
+ * Public API: Go to next slide
840
+ */
841
+ next() {
842
+ this.changeSlide({ data: { message: "next" } });
843
+ }
844
+ /**
845
+ * Public API: Go to previous slide
846
+ */
847
+ prev() {
848
+ this.changeSlide({ data: { message: "prev" } });
849
+ }
850
+ /**
851
+ * Public API: Go to specific slide
852
+ */
853
+ goTo(index, dontAnimate = false) {
854
+ if (index < 0 || index >= this.state.slideCount)
855
+ return;
856
+ this.changeSlide({ data: { message: "index", index } }, dontAnimate);
857
+ }
858
+ /**
859
+ * Public API: Play autoplay
860
+ */
861
+ play() {
862
+ if (!this.options.autoplay)
863
+ return;
864
+ this.state.paused = false;
865
+ this.autoPlay();
866
+ this.setAutoplayButtonState(false);
867
+ this.emit("play");
868
+ }
869
+ /**
870
+ * Public API: Pause autoplay
871
+ */
872
+ pause() {
873
+ if (!this.options.autoplay)
874
+ return;
875
+ this.autoPlayClear();
876
+ this.state.paused = true;
877
+ this.setAutoplayButtonState(true);
878
+ this.emit("pause");
879
+ }
880
+ /**
881
+ * Public API: Get current slide index
882
+ */
883
+ getCurrentSlide() {
884
+ return this.state.currentSlide;
885
+ }
886
+ /**
887
+ * Public API: Get configuration option
888
+ */
889
+ getOption(option) {
890
+ return this.options[option];
891
+ }
892
+ /**
893
+ * Public API: Set configuration option
894
+ */
895
+ setOption(option, value) {
896
+ this.options[option] = value;
897
+ this.emit("setOption", { option, value });
898
+ }
899
+ /**
900
+ * Public API: Add slide(s)
901
+ * Adds new slide(s) to the carousel
902
+ */
903
+ addSlide(markup, index = null, addBefore = false) {
904
+ if (!markup)
905
+ return false;
906
+ if (typeof index === "boolean") {
907
+ addBefore = index;
908
+ index = null;
909
+ }
910
+ if (index !== null && (index < 0 || index >= this.state.slideCount)) {
911
+ return false;
912
+ }
913
+ this.unloadClones();
914
+ let newSlide;
915
+ if (typeof markup === "string") {
916
+ newSlide = parseHTML(markup);
917
+ } else {
918
+ newSlide = markup;
919
+ }
920
+ if (typeof index === "number") {
921
+ if (index === 0 && this.state.slides.length === 0) {
922
+ appendChild(this.state.slideTrack, newSlide);
923
+ } else if (addBefore) {
924
+ const targetSlide = this.state.slides[index];
925
+ if (targetSlide && targetSlide.parentNode) {
926
+ insertBefore(targetSlide, newSlide);
927
+ } else {
928
+ appendChild(this.state.slideTrack, newSlide);
929
+ }
930
+ } else {
931
+ const targetSlide = this.state.slides[index];
932
+ if (targetSlide && targetSlide.nextSibling) {
933
+ insertBefore(targetSlide.nextSibling, newSlide);
934
+ } else if (targetSlide && targetSlide.parentNode) {
935
+ appendChild(this.state.slideTrack, newSlide);
936
+ }
937
+ }
938
+ } else {
939
+ if (addBefore === true) {
940
+ if (this.state.slideTrack.firstChild) {
941
+ insertBefore(this.state.slideTrack.firstChild, newSlide);
942
+ } else {
943
+ appendChild(this.state.slideTrack, newSlide);
944
+ }
945
+ } else {
946
+ appendChild(this.state.slideTrack, newSlide);
947
+ }
948
+ }
949
+ addClass(newSlide, "slick-slide");
950
+ this.state.slides = getChildren(this.state.slideTrack).filter((el) => !hasClass(el, "slick-cloned"));
951
+ this.state.slideCount = this.state.slides.length;
952
+ this.reinit();
953
+ this.emit("addSlide");
954
+ return true;
955
+ }
956
+ /**
957
+ * Public API: Remove slide
958
+ * Removes a slide from the carousel
959
+ */
960
+ removeSlide(index, removeBefore = false, removeAll = false) {
961
+ if (this.state.slideCount < 1 || index < 0 || index > this.state.slideCount - 1) {
962
+ return false;
963
+ }
964
+ this.unloadClones();
965
+ if (removeAll === true) {
966
+ while (this.state.slideTrack.firstChild) {
967
+ const child = this.state.slideTrack.firstChild;
968
+ if (!hasClass(child, "slick-cloned")) {
969
+ remove(child);
970
+ }
971
+ }
972
+ } else {
973
+ const slideToRemove = this.state.slides[index];
974
+ if (slideToRemove) {
975
+ remove(slideToRemove);
976
+ }
977
+ }
978
+ this.state.slides = getChildren(this.state.slideTrack).filter((el) => !hasClass(el, "slick-cloned"));
979
+ this.state.slideCount = this.state.slides.length;
980
+ if (this.state.currentSlide >= this.state.slideCount && this.state.currentSlide !== 0) {
981
+ this.state.currentSlide = this.state.currentSlide - this.options.slidesToScroll;
982
+ }
983
+ this.reinit();
984
+ this.emit("removeSlide");
985
+ return true;
986
+ }
987
+ /**
988
+ * Alias for addSlide (jQuery Slick compatibility)
989
+ */
990
+ slickAdd(markup, index = null, addBefore = false) {
991
+ return this.addSlide(markup, index, addBefore);
992
+ }
993
+ /**
994
+ * Alias for removeSlide (jQuery Slick compatibility)
995
+ */
996
+ slickRemove(index, removeBefore = false, removeAll = false) {
997
+ return this.removeSlide(index, removeBefore, removeAll);
998
+ }
999
+ /**
1000
+ * Alias for slickFilter (jQuery Slick compatibility)
1001
+ */
1002
+ filterSlides(filter) {
1003
+ return this.slickFilter(filter);
1004
+ }
1005
+ /**
1006
+ * Public API: Filter slides (jQuery Slick compatibility)
1007
+ */
1008
+ slickFilter(filter) {
1009
+ if (filter == null || !this.state.slideTrack) {
1010
+ return false;
1011
+ }
1012
+ if (!this.state.slidesCache) {
1013
+ this.state.slidesCache = this.state.slides.slice();
1014
+ }
1015
+ this.unloadClones();
1016
+ const filteredSlides = this.state.slidesCache.filter(
1017
+ (slide, index) => this.matchesSlideFilter(slide, filter, index)
1018
+ );
1019
+ empty(this.state.slideTrack);
1020
+ filteredSlides.forEach((slide) => appendChild(this.state.slideTrack, slide));
1021
+ this.state.currentSlide = 0;
1022
+ this.reinit();
1023
+ this.emit("filter");
1024
+ return true;
1025
+ }
1026
+ /**
1027
+ * Alias for slickUnfilter (jQuery Slick compatibility)
1028
+ */
1029
+ unfilterSlides() {
1030
+ return this.slickUnfilter();
1031
+ }
1032
+ /**
1033
+ * Public API: Remove active filter and restore all slides (jQuery Slick compatibility)
1034
+ */
1035
+ slickUnfilter() {
1036
+ if (!this.state.slideTrack || !this.state.slidesCache) {
1037
+ return false;
1038
+ }
1039
+ this.unloadClones();
1040
+ empty(this.state.slideTrack);
1041
+ this.state.slidesCache.forEach((slide) => appendChild(this.state.slideTrack, slide));
1042
+ this.state.slidesCache = null;
1043
+ this.state.currentSlide = 0;
1044
+ this.reinit();
1045
+ this.emit("unfilter");
1046
+ return true;
1047
+ }
1048
+ /**
1049
+ * Match slide against a jQuery-like filter selector or callback
1050
+ */
1051
+ matchesSlideFilter(slide, filter, index) {
1052
+ if (typeof filter === "function") {
1053
+ return Boolean(filter.call(slide, index, slide));
1054
+ }
1055
+ if (typeof filter !== "string") {
1056
+ return false;
1057
+ }
1058
+ const hasEvenPseudo = /:even\b/.test(filter);
1059
+ const hasOddPseudo = /:odd\b/.test(filter);
1060
+ const selector = filter.replace(/:even\b|:odd\b/g, "").trim();
1061
+ const parityMatch = hasEvenPseudo ? index % 2 === 0 : hasOddPseudo ? index % 2 === 1 : true;
1062
+ if (!parityMatch) {
1063
+ return false;
1064
+ }
1065
+ if (!selector) {
1066
+ return true;
1067
+ }
1068
+ try {
1069
+ return slide.matches(selector);
1070
+ } catch (e) {
1071
+ return false;
1072
+ }
1073
+ }
1074
+ /**
1075
+ * Public API: Destroy slider
1076
+ */
1077
+ destroy() {
1078
+ removeEventListener(window, "resize", this.boundMethods.handleResize);
1079
+ removeEventListener(document, "visibilitychange", this.boundMethods.handleVisibilityChange);
1080
+ removeEventListener(this.element, "keydown", this.boundMethods.handleKeydown);
1081
+ this.dispatcher.clear();
1082
+ if (this.state.pauseButton)
1083
+ remove(this.state.pauseButton);
1084
+ if (this.state.prevArrowElement)
1085
+ remove(this.state.prevArrowElement);
1086
+ if (this.state.nextArrowElement)
1087
+ remove(this.state.nextArrowElement);
1088
+ if (this.state.dots)
1089
+ remove(this.state.dots);
1090
+ this.state.unslicked = true;
1091
+ this.constructor.INSTANCES.delete(this.instanceId);
1092
+ this.emit("destroy");
1093
+ }
1094
+ /**
1095
+ * Handle slide change
1096
+ */
1097
+ changeSlide(e, dontAnimate = false) {
1098
+ const message = e?.data?.message;
1099
+ const previousSlide = this.normalizeSlideIndex(this.state.currentSlide);
1100
+ let targetSlide = previousSlide;
1101
+ if (message === "next") {
1102
+ targetSlide = previousSlide + this.options.slidesToScroll;
1103
+ } else if (message === "prev") {
1104
+ targetSlide = previousSlide - this.options.slidesToScroll;
1105
+ } else if (message === "index" && Number.isInteger(e?.data?.index)) {
1106
+ targetSlide = e.data.index;
1107
+ }
1108
+ if (this.options.fade) {
1109
+ if (!this.options.infinite) {
1110
+ targetSlide = Math.max(0, Math.min(targetSlide, this.state.slideCount - 1));
1111
+ } else {
1112
+ targetSlide = this.normalizeSlideIndex(targetSlide);
1113
+ }
1114
+ if (targetSlide === previousSlide)
1115
+ return;
1116
+ if (this.state.animating && this.options.waitForAnimate)
1117
+ return;
1118
+ this.emit("beforeChange", { previousSlide, nextSlide: targetSlide });
1119
+ const shouldAnimate2 = this.options.useCSS && !dontAnimate && this.options.speed > 0;
1120
+ this.state.currentSlide = targetSlide;
1121
+ if (!this.state.suppressNavSync && this.options.asNavFor) {
1122
+ this.syncAsNavFor(targetSlide, dontAnimate);
1123
+ }
1124
+ if (shouldAnimate2) {
1125
+ this.state.animating = true;
1126
+ this.fadeSlideTransition(previousSlide, targetSlide, () => {
1127
+ this.state.animating = false;
1128
+ this.setPosition();
1129
+ this.emit("afterChange", { currentSlide: this.state.currentSlide });
1130
+ });
1131
+ } else {
1132
+ this.state.animating = false;
1133
+ this.setPosition();
1134
+ this.emit("afterChange", { currentSlide: this.state.currentSlide });
1135
+ }
1136
+ return;
1137
+ }
1138
+ if (!this.options.infinite) {
1139
+ targetSlide = Math.max(0, Math.min(targetSlide, this.state.slideCount - 1));
1140
+ }
1141
+ if (targetSlide === previousSlide)
1142
+ return;
1143
+ if (this.state.animating && this.options.waitForAnimate)
1144
+ return;
1145
+ this.emit("beforeChange", { previousSlide, nextSlide: targetSlide });
1146
+ const shouldAnimate = this.options.useCSS && !dontAnimate && this.options.speed > 0;
1147
+ this.state.animating = shouldAnimate;
1148
+ if (shouldAnimate) {
1149
+ applyTransition(this.state.slideTrack, this.options.speed, this.options.cssEase);
1150
+ this.animateHeight();
1151
+ } else {
1152
+ removeTransition(this.state.slideTrack);
1153
+ }
1154
+ this.state.currentSlide = targetSlide;
1155
+ const normalizedTarget = this.normalizeSlideIndex(targetSlide);
1156
+ if (!this.state.suppressNavSync && this.options.asNavFor) {
1157
+ this.syncAsNavFor(normalizedTarget, dontAnimate);
1158
+ }
1159
+ this.setPosition();
1160
+ if (shouldAnimate) {
1161
+ window.setTimeout(() => {
1162
+ if (this.options.infinite) {
1163
+ let repositionSlide = targetSlide;
1164
+ if (targetSlide >= this.state.slideCount) {
1165
+ repositionSlide = targetSlide % this.state.slideCount;
1166
+ } else if (targetSlide < 0) {
1167
+ repositionSlide = this.state.slideCount + targetSlide % this.state.slideCount;
1168
+ }
1169
+ if (repositionSlide !== targetSlide) {
1170
+ removeTransition(this.state.slideTrack);
1171
+ this.state.currentSlide = repositionSlide;
1172
+ this.setPosition();
1173
+ } else {
1174
+ removeTransition(this.state.slideTrack);
1175
+ }
1176
+ } else {
1177
+ removeTransition(this.state.slideTrack);
1178
+ }
1179
+ this.state.animating = false;
1180
+ }, this.options.speed);
1181
+ } else {
1182
+ this.state.animating = false;
1183
+ }
1184
+ this.emit("afterChange", { currentSlide: this.state.currentSlide });
1185
+ }
1186
+ /**
1187
+ * Quick reposition for infinite wrap - minimal calculations, no forced reflows
1188
+ * Used when wrapping from last slide to first (or vice versa) to maintain 60fps
1189
+ */
1190
+ quickReposition() {
1191
+ if (!this.state.slideList || !this.state.slideTrack)
1192
+ return;
1193
+ if (!this.state.slideWidth) {
1194
+ const listWidth = this.state.listWidth || getInnerWidth(this.state.slideList) || 400;
1195
+ this.state.slideWidth = Math.ceil(listWidth / this.options.slidesToShow);
1196
+ }
1197
+ let targetLeft = 0;
1198
+ if (this.options.variableWidth) {
1199
+ const allSlidesInDOM = selectAll(".slick-slide", this.state.slideTrack);
1200
+ let slideIndex = this.state.currentSlide;
1201
+ const cloneOffset = this.options.infinite && this.state.slideCount > this.options.slidesToShow ? this.options.centerMode ? this.options.slidesToShow + 1 : this.options.slidesToShow : 0;
1202
+ slideIndex = this.state.currentSlide + cloneOffset;
1203
+ if (slideIndex < 0 || slideIndex >= allSlidesInDOM.length) {
1204
+ slideIndex = Math.max(0, Math.min(slideIndex, allSlidesInDOM.length - 1));
1205
+ }
1206
+ const targetSlide = allSlidesInDOM[slideIndex];
1207
+ if (targetSlide) {
1208
+ const slideOffsetLeft = targetSlide.offsetLeft || 0;
1209
+ targetLeft = -slideOffsetLeft;
1210
+ if (this.options.centerMode && this.state.listWidth) {
1211
+ const slideWidth = getOuterWidth(targetSlide);
1212
+ targetLeft += (this.state.listWidth - slideWidth) / 2;
1213
+ }
1214
+ }
1215
+ } else {
1216
+ const allSlidesInDOM = selectAll(".slick-slide", this.state.slideTrack);
1217
+ const totalSlideCount = allSlidesInDOM.length;
1218
+ const trackWidth = Math.ceil(this.state.slideWidth * totalSlideCount);
1219
+ setStyle(this.state.slideTrack, "width", `${trackWidth}px`);
1220
+ let slideOffset = 0;
1221
+ if (this.options.infinite && this.state.slideCount > this.options.slidesToShow) {
1222
+ slideOffset = this.state.slideWidth * this.options.slidesToShow * -1;
1223
+ }
1224
+ if (this.state.slideCount <= this.options.slidesToShow) {
1225
+ slideOffset = 0;
1226
+ }
1227
+ if (this.options.centerMode && this.state.slideCount <= this.options.slidesToShow) {
1228
+ slideOffset = this.state.slideWidth * Math.floor(this.options.slidesToShow) / 2 - this.state.slideWidth * this.state.slideCount / 2;
1229
+ } else if (this.options.centerMode && this.options.infinite) {
1230
+ slideOffset += this.state.slideWidth * Math.floor(this.options.slidesToShow / 2) - this.state.slideWidth;
1231
+ } else if (this.options.centerMode) {
1232
+ slideOffset = 0;
1233
+ slideOffset += this.state.slideWidth * Math.floor(this.options.slidesToShow / 2);
1234
+ }
1235
+ targetLeft = this.state.currentSlide * this.state.slideWidth * -1 + slideOffset;
1236
+ }
1237
+ if (this.options.useTransform && this.state.transformsEnabled) {
1238
+ translate3d(this.state.slideTrack, targetLeft, 0, 0);
1239
+ } else {
1240
+ setStyle(this.state.slideTrack, "left", `${targetLeft}px`);
1241
+ }
1242
+ this.updateSlideVisibility();
1243
+ this.updateArrows();
1244
+ this.updateDots();
1245
+ }
1246
+ /**
1247
+ * Fade transition between slides (jQuery Slick parity)
1248
+ */
1249
+ fadeSlideTransition(fromIndex, toIndex, callback) {
1250
+ const fromSlide = this.state.slides[this.normalizeSlideIndex(fromIndex)];
1251
+ const toSlide = this.state.slides[this.normalizeSlideIndex(toIndex)];
1252
+ if (!toSlide) {
1253
+ if (callback)
1254
+ callback();
1255
+ return;
1256
+ }
1257
+ const transitionValue = `opacity ${this.options.speed}ms ${this.options.cssEase}`;
1258
+ if (fromSlide) {
1259
+ setStyle(fromSlide, "transition", transitionValue);
1260
+ setStyle(fromSlide, "opacity", "0");
1261
+ setStyle(fromSlide, "z-index", String(this.options.zIndex - 2));
1262
+ }
1263
+ setStyle(toSlide, "transition", transitionValue);
1264
+ setStyle(toSlide, "opacity", "1");
1265
+ setStyle(toSlide, "z-index", String(this.options.zIndex - 1));
1266
+ const newHeight = getOuterHeight(toSlide);
1267
+ if (newHeight > 0 && this.state.slideTrack) {
1268
+ setStyle(this.state.slideTrack, "height", `${newHeight}px`);
1269
+ }
1270
+ window.setTimeout(() => {
1271
+ if (fromSlide) {
1272
+ setStyle(fromSlide, "transition", "");
1273
+ }
1274
+ setStyle(toSlide, "transition", "");
1275
+ if (callback)
1276
+ callback();
1277
+ }, this.options.speed);
1278
+ }
1279
+ /**
1280
+ * Position slides for fade mode (jQuery Slick parity)
1281
+ * Uses absolute positioning so all slides overlap at the same location
1282
+ */
1283
+ setFade() {
1284
+ if (!this.state.slideTrack)
1285
+ return;
1286
+ const slides = selectAll(".slick-slide", this.state.slideTrack);
1287
+ if (!slides.length)
1288
+ return;
1289
+ let maxHeight = 0;
1290
+ slides.forEach((slide) => {
1291
+ const slideHeight = getOuterHeight(slide);
1292
+ if (slideHeight > maxHeight) {
1293
+ maxHeight = slideHeight;
1294
+ }
1295
+ });
1296
+ if (maxHeight > 0) {
1297
+ setStyle(this.state.slideTrack, "height", `${maxHeight}px`);
1298
+ }
1299
+ slides.forEach((slide, index) => {
1300
+ setStyle(slide, "position", "absolute");
1301
+ setStyle(slide, "left", "0");
1302
+ setStyle(slide, "top", "0");
1303
+ setStyle(slide, "width", "100%");
1304
+ setStyle(slide, "opacity", "0");
1305
+ setStyle(slide, "z-index", String(this.options.zIndex - 2));
1306
+ setStyle(slide, "transition", "");
1307
+ });
1308
+ const currentIndex = Math.max(0, Math.min(this.state.currentSlide, slides.length - 1));
1309
+ if (slides[currentIndex]) {
1310
+ setStyle(slides[currentIndex], "opacity", "1");
1311
+ setStyle(slides[currentIndex], "z-index", String(this.options.zIndex - 1));
1312
+ }
1313
+ }
1314
+ /**
1315
+ * Set slide position
1316
+ */
1317
+ setPosition() {
1318
+ if (!this.state.slideList || !this.state.slideTrack)
1319
+ return;
1320
+ if (this.options.centerMode) {
1321
+ if (this.options.vertical) {
1322
+ setStyle(this.state.slideList, "padding", `${this.options.centerPadding} 0px`);
1323
+ } else {
1324
+ setStyle(this.state.slideList, "padding", `0px ${this.options.centerPadding}`);
1325
+ }
1326
+ } else {
1327
+ setStyle(this.state.slideList, "padding", "0px");
1328
+ }
1329
+ void this.state.slideList.offsetWidth;
1330
+ let listWidth = getInnerWidth(this.state.slideList) || getDimensions(this.state.slideList).width;
1331
+ if (!listWidth || listWidth <= 0) {
1332
+ const containerWidth = getDimensions(this.state.slideList).width;
1333
+ if (containerWidth && containerWidth > 0) {
1334
+ listWidth = containerWidth;
1335
+ } else {
1336
+ const parentWidth = this.element.offsetWidth || window.innerWidth;
1337
+ listWidth = parentWidth > 0 ? parentWidth : 300;
1338
+ }
1339
+ }
1340
+ this.state.listWidth = listWidth;
1341
+ if (this.options.fade) {
1342
+ this.state.slideWidth = listWidth;
1343
+ setStyle(this.state.slideTrack, "width", `${listWidth}px`);
1344
+ setStyle(this.state.slideTrack, "position", "relative");
1345
+ setStyle(this.state.slideTrack, "left", "0");
1346
+ setStyle(this.state.slideTrack, "top", "0");
1347
+ setStyle(this.state.slideTrack, "transform", "none");
1348
+ this.setFade();
1349
+ this.updateSlideVisibility();
1350
+ this.updateDots();
1351
+ this.updateArrows();
1352
+ this.updateNavigationVisibility();
1353
+ this.setHeight();
1354
+ return;
1355
+ }
1356
+ let trackWidth = 0;
1357
+ let targetLeft = 0;
1358
+ let slideOffset = 0;
1359
+ if (this.options.variableWidth) {
1360
+ const allSlidesInDOM = selectAll(".slick-slide", this.state.slideTrack);
1361
+ const totalSlideCount = allSlidesInDOM.length;
1362
+ trackWidth = 5e3 * totalSlideCount;
1363
+ setStyle(this.state.slideTrack, "width", `${trackWidth}px`);
1364
+ allSlidesInDOM.forEach((slide) => {
1365
+ if (slide.style.display === "none") {
1366
+ setStyle(slide, "display", "block");
1367
+ }
1368
+ });
1369
+ void this.state.slideTrack.offsetHeight;
1370
+ void this.state.slideTrack.getBoundingClientRect();
1371
+ allSlidesInDOM.forEach((slide) => void slide.offsetLeft);
1372
+ let slideIndex = this.state.currentSlide;
1373
+ const cloneOffset = this.options.infinite && this.state.slideCount > this.options.slidesToShow ? this.options.centerMode ? this.options.slidesToShow + 1 : this.options.slidesToShow : 0;
1374
+ slideIndex = this.state.currentSlide + cloneOffset;
1375
+ if (slideIndex < 0 || slideIndex >= allSlidesInDOM.length) {
1376
+ slideIndex = Math.max(0, Math.min(slideIndex, allSlidesInDOM.length - 1));
1377
+ }
1378
+ const targetSlide = allSlidesInDOM[slideIndex];
1379
+ if (targetSlide) {
1380
+ const slideOffsetLeft = targetSlide.offsetLeft || 0;
1381
+ if (this.options.rtl && !this.options.vertical) {
1382
+ const slideWidth = getOuterWidth(targetSlide);
1383
+ targetLeft = -(trackWidth - slideOffsetLeft - slideWidth);
1384
+ } else {
1385
+ targetLeft = -slideOffsetLeft;
1386
+ }
1387
+ if (this.options.centerMode) {
1388
+ const slideWidth = getOuterWidth(targetSlide);
1389
+ targetLeft += (listWidth - slideWidth) / 2;
1390
+ }
1391
+ }
1392
+ this.state.slideWidth = listWidth;
1393
+ } else {
1394
+ this.state.slideWidth = Math.ceil(listWidth / this.options.slidesToShow);
1395
+ const allSlidesInDOM = selectAll(".slick-slide", this.state.slideTrack);
1396
+ const slidesToStyle = allSlidesInDOM && allSlidesInDOM.length > 0 ? allSlidesInDOM : this.state.slides;
1397
+ const totalSlideCount = slidesToStyle.length;
1398
+ trackWidth = Math.ceil(this.state.slideWidth * totalSlideCount);
1399
+ setStyle(this.state.slideTrack, "width", `${trackWidth}px`);
1400
+ let offset = 0;
1401
+ const firstSlide = this.state.slides[0];
1402
+ if (firstSlide) {
1403
+ const styles = window.getComputedStyle(firstSlide);
1404
+ const marginLeft = parseFloat(styles.marginLeft) || 0;
1405
+ const marginRight = parseFloat(styles.marginRight) || 0;
1406
+ const paddingLeft = parseFloat(styles.paddingLeft) || 0;
1407
+ const paddingRight = parseFloat(styles.paddingRight) || 0;
1408
+ const borderLeft = parseFloat(styles.borderLeft) || 0;
1409
+ const borderRight = parseFloat(styles.borderRight) || 0;
1410
+ offset = marginLeft + marginRight + paddingLeft + paddingRight + borderLeft + borderRight;
1411
+ }
1412
+ const slideWidthToSet = Math.max(0, this.state.slideWidth - offset);
1413
+ slidesToStyle.forEach((slide) => {
1414
+ setStyle(slide, "width", `${slideWidthToSet}px`);
1415
+ });
1416
+ slideOffset = 0;
1417
+ if (this.options.infinite) {
1418
+ if (this.state.slideCount > this.options.slidesToShow) {
1419
+ slideOffset = this.state.slideWidth * this.options.slidesToShow * -1;
1420
+ }
1421
+ } else {
1422
+ if (this.state.currentSlide + this.options.slidesToShow > this.state.slideCount) {
1423
+ slideOffset = (this.state.currentSlide + this.options.slidesToShow - this.state.slideCount) * this.state.slideWidth;
1424
+ }
1425
+ }
1426
+ if (this.state.slideCount <= this.options.slidesToShow) {
1427
+ slideOffset = 0;
1428
+ }
1429
+ if (this.options.centerMode && this.state.slideCount <= this.options.slidesToShow) {
1430
+ slideOffset = this.state.slideWidth * Math.floor(this.options.slidesToShow) / 2 - this.state.slideWidth * this.state.slideCount / 2;
1431
+ } else if (this.options.centerMode && this.options.infinite) {
1432
+ slideOffset += this.state.slideWidth * Math.floor(this.options.slidesToShow / 2) - this.state.slideWidth;
1433
+ } else if (this.options.centerMode) {
1434
+ slideOffset = 0;
1435
+ slideOffset += this.state.slideWidth * Math.floor(this.options.slidesToShow / 2);
1436
+ }
1437
+ targetLeft = this.state.currentSlide * this.state.slideWidth * -1 + slideOffset;
1438
+ }
1439
+ setStyle(this.state.slideTrack, "width", `${trackWidth}px`);
1440
+ if (this.options.rtl && !this.options.vertical && !this.options.fade) {
1441
+ targetLeft = -targetLeft;
1442
+ }
1443
+ if (this.options.fade) {
1444
+ this.setFade();
1445
+ } else if (this.options.useTransform && this.state.transformsEnabled) {
1446
+ translate3d(this.state.slideTrack, targetLeft, 0, 0);
1447
+ } else {
1448
+ setStyle(this.state.slideTrack, "left", `${targetLeft}px`);
1449
+ }
1450
+ this.updateSlideVisibility();
1451
+ this.updateDots();
1452
+ this.updateArrows();
1453
+ this.updateNavigationVisibility();
1454
+ this.setHeight();
1455
+ }
1456
+ /**
1457
+ * Get total margin width (left + right) of a slide
1458
+ */
1459
+ getSlideMargins(slide) {
1460
+ const styles = window.getComputedStyle(slide);
1461
+ const marginLeft = parseFloat(styles.marginLeft) || 0;
1462
+ const marginRight = parseFloat(styles.marginRight) || 0;
1463
+ return marginLeft + marginRight;
1464
+ }
1465
+ /**
1466
+ * Update slide ARIA hidden states and active classes
1467
+ */
1468
+ updateSlideVisibility() {
1469
+ if (!this.state.slideTrack)
1470
+ return;
1471
+ const allSlides = selectAll(".slick-slide", this.state.slideTrack);
1472
+ if (this.options.fade) {
1473
+ allSlides.forEach((slide) => {
1474
+ removeClass(slide, "slick-active");
1475
+ removeClass(slide, "slick-current");
1476
+ removeClass(slide, "slick-center");
1477
+ });
1478
+ if (allSlides[this.state.currentSlide]) {
1479
+ addClass(allSlides[this.state.currentSlide], "slick-active");
1480
+ addClass(allSlides[this.state.currentSlide], "slick-current");
1481
+ }
1482
+ return;
1483
+ }
1484
+ allSlides.forEach((slide) => {
1485
+ removeClass(slide, "slick-active");
1486
+ removeClass(slide, "slick-current");
1487
+ removeClass(slide, "slick-center");
1488
+ setAttribute(slide, "aria-hidden", "true");
1489
+ });
1490
+ const hasClones = selectAll(".slick-cloned", this.state.slideTrack).length > 0;
1491
+ const offsetForClones = hasClones && this.options.infinite && this.state.slideCount > this.options.slidesToShow ? this.options.centerMode ? this.options.slidesToShow + 1 : this.options.slidesToShow : 0;
1492
+ const centerOffset = this.options.centerMode ? Math.floor(this.options.slidesToShow / 2) : 0;
1493
+ const visibleStart = offsetForClones + this.state.currentSlide - centerOffset;
1494
+ const visibleEnd = visibleStart + this.options.slidesToShow;
1495
+ const centerIndex = offsetForClones + this.state.currentSlide;
1496
+ allSlides.forEach((slide, index) => {
1497
+ if (index >= visibleStart && index < visibleEnd) {
1498
+ addClass(slide, "slick-active");
1499
+ removeAttribute(slide, "aria-hidden");
1500
+ }
1501
+ if (index === centerIndex) {
1502
+ addClass(slide, "slick-current");
1503
+ if (this.options.centerMode) {
1504
+ addClass(slide, "slick-center");
1505
+ }
1506
+ }
1507
+ });
1508
+ }
1509
+ /**
1510
+ * Update arrow disabled states
1511
+ */
1512
+ updateArrows() {
1513
+ if (!this.options.arrows)
1514
+ return;
1515
+ if (!this.state.prevArrowElement || !this.state.nextArrowElement)
1516
+ return;
1517
+ const maxIndex = Math.max(0, this.state.slideCount - this.options.slidesToShow);
1518
+ const disablePrev = !this.options.infinite && this.state.currentSlide === 0;
1519
+ const disableNext = !this.options.infinite && this.state.currentSlide >= maxIndex;
1520
+ if (disablePrev) {
1521
+ addClass(this.state.prevArrowElement, "slick-disabled");
1522
+ setAttribute(this.state.prevArrowElement, "disabled", "disabled");
1523
+ } else {
1524
+ removeClass(this.state.prevArrowElement, "slick-disabled");
1525
+ removeAttribute(this.state.prevArrowElement, "disabled");
1526
+ }
1527
+ if (disableNext) {
1528
+ addClass(this.state.nextArrowElement, "slick-disabled");
1529
+ setAttribute(this.state.nextArrowElement, "disabled", "disabled");
1530
+ } else {
1531
+ removeClass(this.state.nextArrowElement, "slick-disabled");
1532
+ removeAttribute(this.state.nextArrowElement, "disabled");
1533
+ }
1534
+ }
1535
+ /**
1536
+ * Update navigation visibility based on slide count
1537
+ * Hide arrows and dots if there aren't enough slides
1538
+ */
1539
+ updateNavigationVisibility() {
1540
+ const shouldShowNav = this.state.slideCount > this.options.slidesToShow;
1541
+ if (this.state.prevArrowElement) {
1542
+ if (shouldShowNav) {
1543
+ removeClass(this.state.prevArrowElement, "slick-hidden");
1544
+ removeAttribute(this.state.prevArrowElement, "aria-hidden");
1545
+ } else {
1546
+ addClass(this.state.prevArrowElement, "slick-hidden");
1547
+ setAttribute(this.state.prevArrowElement, "aria-hidden", "true");
1548
+ }
1549
+ }
1550
+ if (this.state.nextArrowElement) {
1551
+ if (shouldShowNav) {
1552
+ removeClass(this.state.nextArrowElement, "slick-hidden");
1553
+ removeAttribute(this.state.nextArrowElement, "aria-hidden");
1554
+ } else {
1555
+ addClass(this.state.nextArrowElement, "slick-hidden");
1556
+ setAttribute(this.state.nextArrowElement, "aria-hidden", "true");
1557
+ }
1558
+ }
1559
+ if (this.state.dots) {
1560
+ if (shouldShowNav) {
1561
+ removeClass(this.state.dots, "slick-hidden");
1562
+ removeAttribute(this.state.dots, "aria-hidden");
1563
+ } else {
1564
+ addClass(this.state.dots, "slick-hidden");
1565
+ setAttribute(this.state.dots, "aria-hidden", "true");
1566
+ }
1567
+ }
1568
+ }
1569
+ /**
1570
+ * Set list height to match current slide height (for adaptive height)
1571
+ */
1572
+ setHeight() {
1573
+ if (this.options.slidesToShow === 1 && this.options.adaptiveHeight === true && !this.options.vertical && this.state.slideList) {
1574
+ let slideIndex = this.state.currentSlide;
1575
+ if (this.options.infinite && slideIndex >= this.state.slideCount) {
1576
+ slideIndex = slideIndex % this.state.slideCount;
1577
+ } else if (this.options.infinite && slideIndex < 0) {
1578
+ slideIndex = this.state.slideCount + slideIndex % this.state.slideCount;
1579
+ }
1580
+ const currentSlide = this.state.slides[slideIndex];
1581
+ if (currentSlide) {
1582
+ const targetHeight = getOuterHeight(currentSlide);
1583
+ setStyle(this.state.slideList, "height", `${targetHeight}px`);
1584
+ }
1585
+ }
1586
+ }
1587
+ /**
1588
+ * Animate list height to match slide height when changing slides
1589
+ */
1590
+ animateHeight() {
1591
+ if (this.options.slidesToShow === 1 && this.options.adaptiveHeight === true && !this.options.vertical && this.state.slideList) {
1592
+ let slideIndex = this.state.currentSlide;
1593
+ if (this.options.infinite && slideIndex >= this.state.slideCount) {
1594
+ slideIndex = slideIndex % this.state.slideCount;
1595
+ } else if (this.options.infinite && slideIndex < 0) {
1596
+ slideIndex = this.state.slideCount + slideIndex % this.state.slideCount;
1597
+ }
1598
+ const currentSlide = this.state.slides[slideIndex];
1599
+ if (currentSlide) {
1600
+ const targetHeight = getOuterHeight(currentSlide);
1601
+ if (this.state.animating) {
1602
+ applyTransition(this.state.slideList, this.options.speed, this.options.cssEase);
1603
+ setStyle(this.state.slideList, "height", `${targetHeight}px`);
1604
+ window.setTimeout(() => {
1605
+ removeTransition(this.state.slideList);
1606
+ }, this.options.speed);
1607
+ } else {
1608
+ setStyle(this.state.slideList, "height", `${targetHeight}px`);
1609
+ }
1610
+ }
1611
+ }
1612
+ }
1613
+ /**
1614
+ * Handle previous arrow click
1615
+ */
1616
+ prevClick() {
1617
+ this.prev();
1618
+ }
1619
+ /**
1620
+ * Handle next arrow click
1621
+ */
1622
+ nextClick() {
1623
+ this.next();
1624
+ }
1625
+ /**
1626
+ * Handle dot click
1627
+ */
1628
+ dotClick(e) {
1629
+ const index = parseInt(getAttribute(e.currentTarget, "data-slide-index"));
1630
+ this.goTo(index);
1631
+ }
1632
+ /**
1633
+ * Start drag/swipe
1634
+ */
1635
+ startDrag(e) {
1636
+ const touch = e.type === "touchstart" ? e.touches[0] : e;
1637
+ this.state.touchObject = {
1638
+ startX: touch.pageX,
1639
+ startY: touch.pageY,
1640
+ curX: touch.pageX,
1641
+ curY: touch.pageY
1642
+ };
1643
+ this.state.dragging = true;
1644
+ this.state.touchStartTime = (/* @__PURE__ */ new Date()).getTime();
1645
+ if (e.type === "mousedown") {
1646
+ this.boundMethods.handleMouseMove = (e2) => this.trackDrag(e2);
1647
+ this.boundMethods.handleMouseUp = (e2) => this.endDrag(e2);
1648
+ document.addEventListener("mousemove", this.boundMethods.handleMouseMove);
1649
+ document.addEventListener("mouseup", this.boundMethods.handleMouseUp);
1650
+ }
1651
+ }
1652
+ /**
1653
+ * Track drag/swipe movement
1654
+ */
1655
+ trackDrag(e) {
1656
+ if (!this.state.dragging)
1657
+ return;
1658
+ const touch = e.type.indexOf("touch") !== -1 ? e.touches[0] : e;
1659
+ this.state.touchObject.curX = touch.pageX;
1660
+ this.state.touchObject.curY = touch.pageY;
1661
+ const swipeLength = Math.round(Math.sqrt(
1662
+ Math.pow(this.state.touchObject.curX - this.state.touchObject.startX, 2) + Math.pow(this.state.touchObject.curY - this.state.touchObject.startY, 2)
1663
+ ));
1664
+ if (swipeLength > this.options.touchThreshold) {
1665
+ this.state.swiping = true;
1666
+ const swipeAngle = Math.atan2(
1667
+ this.state.touchObject.curY - this.state.touchObject.startY,
1668
+ this.state.touchObject.curX - this.state.touchObject.startX
1669
+ ) * 180 / Math.PI;
1670
+ const horizontalSwipe = Math.abs(swipeAngle) < 45 || Math.abs(swipeAngle) > 135;
1671
+ const verticalSwipe = Math.abs(swipeAngle) >= 45 && Math.abs(swipeAngle) <= 135;
1672
+ if (this.options.vertical && verticalSwipe) {
1673
+ if (e.type === "touchmove" && this.options.touchMove) {
1674
+ e.preventDefault();
1675
+ }
1676
+ const swipeDistance = this.state.touchObject.curY - this.state.touchObject.startY;
1677
+ this.swipeHandler(swipeDistance);
1678
+ } else if (!this.options.vertical && horizontalSwipe) {
1679
+ if (e.type === "touchmove" && this.options.touchMove) {
1680
+ e.preventDefault();
1681
+ }
1682
+ const swipeDistance = this.state.touchObject.curX - this.state.touchObject.startX;
1683
+ this.swipeHandler(swipeDistance);
1684
+ }
1685
+ }
1686
+ }
1687
+ /**
1688
+ * End drag/swipe
1689
+ */
1690
+ endDrag(e) {
1691
+ if (!this.state.dragging)
1692
+ return;
1693
+ this.state.dragging = false;
1694
+ if (e.type === "mouseup") {
1695
+ document.removeEventListener("mousemove", this.boundMethods.handleMouseMove);
1696
+ document.removeEventListener("mouseup", this.boundMethods.handleMouseUp);
1697
+ }
1698
+ if (this.state.swiping) {
1699
+ this.state.swiping = false;
1700
+ const swipeTime = (/* @__PURE__ */ new Date()).getTime() - this.state.touchStartTime;
1701
+ const swipeDistance = this.options.vertical ? this.state.touchObject.curY - this.state.touchObject.startY : this.state.touchObject.curX - this.state.touchObject.startX;
1702
+ const referenceWidth = this.options.variableWidth ? this.state.listWidth : this.state.slideWidth;
1703
+ const minSwipe = referenceWidth / (this.options.touchThreshold || 5);
1704
+ if (Math.abs(swipeDistance) > minSwipe) {
1705
+ if (swipeDistance > 0) {
1706
+ this.prev();
1707
+ } else {
1708
+ this.next();
1709
+ }
1710
+ } else {
1711
+ this.setPosition();
1712
+ }
1713
+ }
1714
+ this.state.touchObject = {};
1715
+ }
1716
+ /**
1717
+ * Handle swipe movement
1718
+ */
1719
+ swipeHandler(swipeDistance) {
1720
+ if (this.options.variableWidth)
1721
+ return;
1722
+ const currentLeft = this.state.currentSlide * -this.state.slideWidth;
1723
+ const targetLeft = currentLeft + swipeDistance;
1724
+ let adjustedDistance = swipeDistance;
1725
+ if (!this.options.infinite) {
1726
+ const maxLeft = 0;
1727
+ const minLeft = -(this.state.slideCount - this.options.slidesToShow) * this.state.slideWidth;
1728
+ if (targetLeft > maxLeft) {
1729
+ adjustedDistance = swipeDistance * this.options.edgeFriction;
1730
+ } else if (targetLeft < minLeft) {
1731
+ adjustedDistance = swipeDistance * this.options.edgeFriction;
1732
+ }
1733
+ }
1734
+ const newLeft = currentLeft + adjustedDistance;
1735
+ translate3d(this.state.slideTrack, newLeft, 0, 0);
1736
+ }
1737
+ /**
1738
+ * Handle keyboard navigation
1739
+ */
1740
+ handleKeydown(e) {
1741
+ }
1742
+ /**
1743
+ * Handle focus
1744
+ */
1745
+ handleFocus() {
1746
+ this.state.focussed = true;
1747
+ if (this.options.pauseOnFocus && this.options.autoplay) {
1748
+ this.pause();
1749
+ }
1750
+ }
1751
+ /**
1752
+ * Handle blur
1753
+ */
1754
+ handleBlur() {
1755
+ this.state.focussed = false;
1756
+ if (this.options.autoplay && !this.state.paused) {
1757
+ this.play();
1758
+ }
1759
+ }
1760
+ /**
1761
+ * Handle visibility change (tab switch)
1762
+ */
1763
+ handleVisibilityChange() {
1764
+ if (document.hidden) {
1765
+ this.state.interrupted = true;
1766
+ if (this.options.autoplay) {
1767
+ this.autoPlayClear();
1768
+ }
1769
+ } else {
1770
+ this.state.interrupted = false;
1771
+ if (this.options.autoplay && !this.state.paused) {
1772
+ this.autoPlay();
1773
+ }
1774
+ }
1775
+ }
1776
+ /**
1777
+ * Start autoplay
1778
+ */
1779
+ autoPlay() {
1780
+ this.state.paused = false;
1781
+ this.state.autoPlayTimer = setInterval(() => {
1782
+ if (!this.state.paused && !this.state.interrupted && !this.state.focussed) {
1783
+ this.next();
1784
+ }
1785
+ }, this.options.autoplaySpeed);
1786
+ }
1787
+ /**
1788
+ * Clear autoplay timer
1789
+ */
1790
+ autoPlayClear() {
1791
+ if (this.state.autoPlayTimer) {
1792
+ clearInterval(this.state.autoPlayTimer);
1793
+ this.state.autoPlayTimer = null;
1794
+ }
1795
+ }
1796
+ /**
1797
+ * Handle autoplay button toggle
1798
+ */
1799
+ autoPlayToggleHandler() {
1800
+ if (this.state.paused) {
1801
+ this.play();
1802
+ } else {
1803
+ this.pause();
1804
+ }
1805
+ }
1806
+ /**
1807
+ * Check responsive breakpoints
1808
+ */
1809
+ checkResponsive(initial = false) {
1810
+ if (!this.options.responsive || !Array.isArray(this.options.responsive)) {
1811
+ return;
1812
+ }
1813
+ const windowWidth = getWindowDimensions().width;
1814
+ let targetBreakpoint = null;
1815
+ let targetSettings = null;
1816
+ let respondToWidth = windowWidth;
1817
+ if (this.options.respondTo === "window") {
1818
+ respondToWidth = windowWidth;
1819
+ } else if (this.options.respondTo === "slider") {
1820
+ respondToWidth = getDimensions(this.element).width;
1821
+ } else if (this.options.respondTo === "min") {
1822
+ respondToWidth = Math.min(windowWidth, getDimensions(this.element).width);
1823
+ }
1824
+ this.originalOptions.responsive.forEach((breakpoint) => {
1825
+ if (breakpoint.breakpoint) {
1826
+ if (this.originalOptions.mobileFirst) {
1827
+ if (respondToWidth >= breakpoint.breakpoint) {
1828
+ targetBreakpoint = breakpoint.breakpoint;
1829
+ targetSettings = breakpoint.settings;
1830
+ }
1831
+ } else {
1832
+ if (respondToWidth < breakpoint.breakpoint) {
1833
+ if (targetBreakpoint === null || breakpoint.breakpoint < targetBreakpoint) {
1834
+ targetBreakpoint = breakpoint.breakpoint;
1835
+ targetSettings = breakpoint.settings;
1836
+ }
1837
+ }
1838
+ }
1839
+ }
1840
+ });
1841
+ if (targetSettings) {
1842
+ if (targetSettings === "unslick") {
1843
+ this.unslick();
1844
+ } else {
1845
+ const optionsChanged = this.state.activeBreakpoint !== targetBreakpoint;
1846
+ if (optionsChanged) {
1847
+ this.state.activeBreakpoint = targetBreakpoint;
1848
+ const currentSlide = this.state.currentSlide;
1849
+ const newOptions = extend({}, this.originalOptions, targetSettings);
1850
+ this.options = newOptions;
1851
+ this.refresh();
1852
+ if (currentSlide < this.state.slideCount) {
1853
+ this.state.currentSlide = currentSlide;
1854
+ this.setPosition();
1855
+ }
1856
+ this.emit("breakpoint", { breakpoint: targetBreakpoint });
1857
+ }
1858
+ }
1859
+ } else if (this.state.activeBreakpoint !== null) {
1860
+ this.state.activeBreakpoint = null;
1861
+ const currentSlide = this.state.currentSlide;
1862
+ this.options = extend({}, this.originalOptions);
1863
+ this.refresh();
1864
+ if (currentSlide < this.state.slideCount) {
1865
+ this.state.currentSlide = currentSlide;
1866
+ this.setPosition();
1867
+ }
1868
+ this.emit("breakpoint", { breakpoint: null });
1869
+ }
1870
+ }
1871
+ /**
1872
+ * Refresh slider without destroying/recreating
1873
+ */
1874
+ refresh() {
1875
+ if (this.state.dots) {
1876
+ remove(this.state.dots);
1877
+ this.state.dots = null;
1878
+ removeClass(this.element, "slick-dotted");
1879
+ }
1880
+ if (this.options.dots) {
1881
+ this.buildDots();
1882
+ }
1883
+ if (this.options.arrows && (!this.state.prevArrowElement || !this.state.nextArrowElement)) {
1884
+ this.buildArrows();
1885
+ } else if (!this.options.arrows) {
1886
+ if (this.state.prevArrowElement) {
1887
+ remove(this.state.prevArrowElement);
1888
+ this.state.prevArrowElement = null;
1889
+ }
1890
+ if (this.state.nextArrowElement) {
1891
+ remove(this.state.nextArrowElement);
1892
+ this.state.nextArrowElement = null;
1893
+ }
1894
+ }
1895
+ this.setPosition();
1896
+ }
1897
+ /**
1898
+ * Reinitialize slider after slides have been added/removed
1899
+ */
1900
+ reinit() {
1901
+ const allSlides = getChildren(this.state.slideTrack);
1902
+ this.state.slides = allSlides.filter((slide) => !hasClass(slide, "slick-cloned"));
1903
+ this.state.slideCount = this.state.slides.length;
1904
+ if (this.state.currentSlide >= this.state.slideCount && this.state.currentSlide !== 0) {
1905
+ this.state.currentSlide = this.state.currentSlide - this.options.slidesToScroll;
1906
+ }
1907
+ if (this.state.slideCount <= this.options.slidesToShow) {
1908
+ this.state.currentSlide = 0;
1909
+ }
1910
+ this.state.slides.forEach((slide, index) => {
1911
+ addClass(slide, "slick-slide");
1912
+ setAttribute(slide, "data-slick-index", index);
1913
+ });
1914
+ if (this.options.infinite) {
1915
+ this.setupInfinite();
1916
+ }
1917
+ if (this.options.arrows && this.state.slideCount > this.options.slidesToShow) {
1918
+ if (!this.state.prevArrowElement) {
1919
+ this.buildArrows();
1920
+ }
1921
+ }
1922
+ if (this.options.dots && this.state.slideCount > this.options.slidesToShow) {
1923
+ if (!this.state.dots) {
1924
+ this.buildDots();
1925
+ } else {
1926
+ const dotCount = Math.ceil(this.state.slideCount / this.options.slidesToScroll);
1927
+ const dotContainer = this.state.dots;
1928
+ empty(dotContainer);
1929
+ for (let i = 0; i < dotCount; i++) {
1930
+ const dot = document.createElement("li");
1931
+ const button = document.createElement("button");
1932
+ const icon = document.createElement("span");
1933
+ addClass(icon, "slick-dot-icon");
1934
+ setAttribute(button, "aria-label", `Go to slide ${i + 1}`);
1935
+ setAttribute(button, "data-slide-index", i);
1936
+ if (i === 0)
1937
+ addClass(dot, "slick-active");
1938
+ button.addEventListener("click", (e) => this.dotClick(e));
1939
+ appendChild(button, icon);
1940
+ appendChild(dot, button);
1941
+ appendChild(dotContainer, dot);
1942
+ }
1943
+ }
1944
+ }
1945
+ this.setPosition();
1946
+ this.updateSlideVisibility();
1947
+ this.updateNavigationVisibility();
1948
+ this.emit("reInit");
1949
+ }
1950
+ /**
1951
+ * Unload cloned slides (used by addSlide/removeSlide)
1952
+ */
1953
+ unloadClones() {
1954
+ const clones = selectAll(".slick-cloned", this.state.slideTrack);
1955
+ clones.forEach((clone2) => remove(clone2));
1956
+ }
1957
+ /**
1958
+ * Unload slider elements
1959
+ */
1960
+ unload() {
1961
+ if (this.boundMethods.handleResize) {
1962
+ window.removeEventListener("resize", this.boundMethods.handleResize);
1963
+ }
1964
+ if (this.boundMethods.handleVisibilityChange) {
1965
+ document.removeEventListener("visibilitychange", this.boundMethods.handleVisibilityChange);
1966
+ }
1967
+ if (this.boundMethods.handleKeydown) {
1968
+ this.element.removeEventListener("keydown", this.boundMethods.handleKeydown);
1969
+ }
1970
+ if (this.boundMethods.handleMouseDown && this.state.slideList) {
1971
+ this.state.slideList.removeEventListener("mousedown", this.boundMethods.handleMouseDown);
1972
+ }
1973
+ if (this.boundMethods.handleTouchStart && this.state.slideList) {
1974
+ this.state.slideList.removeEventListener("touchstart", this.boundMethods.handleTouchStart);
1975
+ this.state.slideList.removeEventListener("touchend", this.boundMethods.handleTouchEnd);
1976
+ this.state.slideList.removeEventListener("touchmove", this.boundMethods.handleTouchMove);
1977
+ }
1978
+ if (this.boundMethods.handleFocus) {
1979
+ this.element.removeEventListener("focusin", this.boundMethods.handleFocus, true);
1980
+ }
1981
+ if (this.boundMethods.handleBlur) {
1982
+ this.element.removeEventListener("focusout", this.boundMethods.handleBlur, true);
1983
+ }
1984
+ if (this.boundMethods.handleSlideClick && this.state.slideTrack) {
1985
+ this.state.slideTrack.removeEventListener("click", this.boundMethods.handleSlideClick);
1986
+ }
1987
+ if (this.state.autoPlayTimer) {
1988
+ clearInterval(this.state.autoPlayTimer);
1989
+ this.state.autoPlayTimer = null;
1990
+ }
1991
+ if (this.state.prevArrowElement && this.state.prevArrowElement.parentNode) {
1992
+ remove(this.state.prevArrowElement);
1993
+ this.state.prevArrowElement = null;
1994
+ }
1995
+ if (this.state.nextArrowElement && this.state.nextArrowElement.parentNode) {
1996
+ remove(this.state.nextArrowElement);
1997
+ this.state.nextArrowElement = null;
1998
+ }
1999
+ if (this.state.dots && this.state.dots.parentNode) {
2000
+ remove(this.state.dots);
2001
+ this.state.dots = null;
2002
+ }
2003
+ if (this.state.pauseButton && this.state.pauseButton.parentNode) {
2004
+ remove(this.state.pauseButton);
2005
+ this.state.pauseButton = null;
2006
+ }
2007
+ if (this.state.slideTrack && this.state.slideTrack.parentNode) {
2008
+ const slides = getChildren(this.state.slideTrack);
2009
+ slides.forEach((slide) => {
2010
+ appendChild(this.state.slideList, slide);
2011
+ });
2012
+ remove(this.state.slideTrack);
2013
+ this.state.slideTrack = null;
2014
+ }
2015
+ }
2016
+ /**
2017
+ * On event - register listener
2018
+ */
2019
+ on(event, callback, context = null) {
2020
+ this.dispatcher.on(event, callback, context);
2021
+ return this;
2022
+ }
2023
+ /**
2024
+ * Once event - register one-time listener
2025
+ */
2026
+ once(event, callback, context = null) {
2027
+ this.dispatcher.once(event, callback, context);
2028
+ return this;
2029
+ }
2030
+ /**
2031
+ * Off event - remove listener
2032
+ */
2033
+ off(event, callback = null) {
2034
+ this.dispatcher.off(event, callback);
2035
+ return this;
2036
+ }
2037
+ /**
2038
+ * Emit custom event
2039
+ */
2040
+ emit(event, data = null) {
2041
+ this.dispatcher.emit(event, data);
2042
+ try {
2043
+ const customEvent = new CustomEvent(`slick:${event}`, {
2044
+ detail: data,
2045
+ bubbles: true,
2046
+ cancelable: true
2047
+ });
2048
+ this.element.dispatchEvent(customEvent);
2049
+ } catch (e) {
2050
+ try {
2051
+ const evt = document.createEvent("CustomEvent");
2052
+ evt.initCustomEvent(`slick:${event}`, true, true, data);
2053
+ this.element.dispatchEvent(evt);
2054
+ } catch (err) {
2055
+ console.warn("CustomEvent not supported");
2056
+ }
2057
+ }
2058
+ return this;
2059
+ }
2060
+ };
2061
+ var SlickSlider_default = SlickSlider;
2062
+
2063
+ // slick/src/index.js
2064
+ function Slick(element, options = {}) {
2065
+ if (Array.isArray(element)) {
2066
+ return element.map((el) => new SlickSlider_default(el, options));
2067
+ }
2068
+ return new SlickSlider_default(element, options);
2069
+ }
2070
+ Slick.auto = function(selector, options = {}) {
2071
+ const elements = document.querySelectorAll(selector);
2072
+ return Array.from(elements).map((el) => new SlickSlider_default(el, options));
2073
+ };
2074
+ Slick.version = "2.0.0";
2075
+ if (typeof window !== "undefined") {
2076
+ window.Slick = Slick;
2077
+ window.SlickSlider = SlickSlider_default;
2078
+ window.slickModule = {
2079
+ Slick,
2080
+ SlickSlider: SlickSlider_default,
2081
+ default: Slick
2082
+ };
2083
+ }
2084
+ export {
2085
+ SlickSlider_default as SlickSlider,
2086
+ Slick as default
2087
+ };